crypt32: Allow messages to be opened when compiled with CMSG_SIGNED_ENCODE_INFO_HAS_C...
[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     CryptReleaseContext(signer.hCryptProv, 0);
1110     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1111      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1112 }
1113
1114 static const BYTE privKey[] = {
1115  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1116  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1117  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1118  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1119  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1120  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1121  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1122  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1123  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1124  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1125  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1126  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1127  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1128  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1129  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1130  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1131  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1132  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1133  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1134  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1135  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1136  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1137  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1138  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1139 static BYTE pubKey[] = {
1140 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1141 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1142 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1143 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1144 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1145
1146 static void test_signed_msg_update(void)
1147 {
1148     HCRYPTMSG msg;
1149     BOOL ret;
1150     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1151     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1152     CERT_INFO certInfo = { 0 };
1153     HCRYPTKEY key;
1154
1155     certInfo.SerialNumber.cbData = sizeof(serialNum);
1156     certInfo.SerialNumber.pbData = serialNum;
1157     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1158     certInfo.Issuer.pbData = encodedCommonName;
1159     signer.pCertInfo = &certInfo;
1160     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1161     signInfo.cSigners = 1;
1162     signInfo.rgSigners = &signer;
1163
1164     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1165                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1166     if (!ret && GetLastError() == NTE_EXISTS) {
1167         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1168                                     PROV_RSA_FULL, 0);
1169     }
1170     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1171
1172     if (!ret) {
1173         skip("No context for tests\n");
1174         return;
1175     }
1176
1177     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1178      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1179     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1180     /* Detached CMSG_SIGNED allows non-final updates. */
1181     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1182     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1183     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1184     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1185     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1186     /* The final update requires a private key in the hCryptProv, in order to
1187      * generate the signature.
1188      */
1189     SetLastError(0xdeadbeef);
1190     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1191     ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1192      GetLastError() == NTE_NO_KEY),
1193      "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1194     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1195      0, 0, &key);
1196     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1197     /* The final update should be able to succeed now that a key exists, but
1198      * the previous (invalid) final update prevents it.
1199      */
1200     SetLastError(0xdeadbeef);
1201     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1202     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1203      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1204     CryptMsgClose(msg);
1205
1206     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1207      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1208     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1209     /* Detached CMSG_SIGNED allows non-final updates. */
1210     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1211     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1212     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1213     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1214     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1215     /* Now that the private key exists, the final update can succeed (even
1216      * with no data.)
1217      */
1218     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1219     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1220     /* But no updates are allowed after the final update. */
1221     SetLastError(0xdeadbeef);
1222     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1223     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1224      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1225     SetLastError(0xdeadbeef);
1226     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1227     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1228      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1229     CryptMsgClose(msg);
1230
1231     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1232      NULL, NULL);
1233     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1234     /* Non-detached messages don't allow non-final updates.. */
1235     SetLastError(0xdeadbeef);
1236     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1237     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1238      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1239     /* but they do allow final ones. */
1240     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1241     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1242     CryptMsgClose(msg);
1243     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1244      NULL, NULL);
1245     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1246     /* They also allow final updates with no data. */
1247     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1248     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1249     CryptMsgClose(msg);
1250
1251     CryptDestroyKey(key);
1252     CryptReleaseContext(signer.hCryptProv, 0);
1253     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1254      CRYPT_DELETEKEYSET);
1255 }
1256
1257 static const BYTE signedEmptyBareContent[] = {
1258 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1259 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1260 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1261 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1262 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1263 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1264 static const BYTE signedEmptyContent[] = {
1265 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1266 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1267 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1268 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1269 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1270 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1271 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1272 static const BYTE detachedSignedBareContent[] = {
1273 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1274 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1275 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1276 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1277 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1278 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1279 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1280 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1281 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1282 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1283 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1284 static const BYTE detachedSignedContent[] = {
1285 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1286 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1287 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1288 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1289 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1290 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1291 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1292 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1293 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1294 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1295 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1296 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1297 static const BYTE signedBareContent[] = {
1298 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1299 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1300 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1301 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1302 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1303 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1304 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1305 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1306 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1307 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1308 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1309 static const BYTE signedContent[] = {
1310 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1311 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1312 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1313 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1314 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1315 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1316 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1317 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1318 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1319 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1320 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1321 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1322 0x0d };
1323 static const BYTE signedHash[] = {
1324 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1325 0x2f };
1326 static const BYTE signedEncodedSigner[] = {
1327 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1328 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1329 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1330 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1331 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1332 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1333 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1334 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1335 static const BYTE signedWithAuthAttrsBareContent[] = {
1336 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1337 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1338 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1339 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1340 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1341 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1342 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1343 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1344 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1345 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1346 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1347 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1348 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1349 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1350 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1351 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1352 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1353 0xff,0xc6,0x33,0x63,0x34 };
1354 static BYTE cert[] = {
1355 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1356 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1357 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1358 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1359 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1360 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1361 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1362 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1363 0xff,0x02,0x01,0x01 };
1364 static BYTE v1CertWithPubKey[] = {
1365 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1366 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1367 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1368 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1369 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1370 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1371 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1372 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1373 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1374 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1375 0x01,0x01 };
1376 static const BYTE signedWithCertEmptyBareContent[] = {
1377 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1379 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1380 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1381 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1382 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1383 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1384 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1385 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1386 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1387 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1388 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1389 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1390 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1391 static const BYTE signedWithCertBareContent[] = {
1392 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1393 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1394 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1395 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1396 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1397 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1398 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1399 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1400 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1401 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1402 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1403 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1404 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1405 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1406 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1407 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1408 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1409 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1410 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1411 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1412 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1413 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1414 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1415 0x30,0x30,0x30,0x30,0x5a };
1416 static const BYTE signedWithCrlEmptyBareContent[] = {
1417 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1418 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1419 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1420 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1421 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1422 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1423 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1424 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1425 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1426 static const BYTE signedWithCrlBareContent[] = {
1427 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1428 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1429 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1430 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1431 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1432 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1433 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1434 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1435 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1436 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1437 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1438 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1439 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1440 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1441 0xa8,0x0d };
1442 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1443 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1444 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1445 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1446 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1447 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1448 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1449 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1450 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1451 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1452 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1453 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1454 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1455 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1456 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1457 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1458 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1459 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1460 0x04,0x00 };
1461 static const BYTE signedWithCertAndCrlBareContent[] = {
1462 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1463 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1464 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1465 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1466 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1467 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1468 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1469 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1470 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1471 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1472 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1473 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1474 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1475 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1476 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1477 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1478 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1479 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1480 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1481 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1482 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1483 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1484 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1485 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1486 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1487 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1488 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1489 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1490 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1491 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1492 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1493 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1494 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1495 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1496 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1497 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1498 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1499 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1500 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1501 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1502 static BYTE v1CertWithValidPubKey[] = {
1503 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1504 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1505 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1506 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1507 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1508 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1509 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1510 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1511 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1512 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1513 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1514 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1515 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1516 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1517 static const BYTE signedWithCertWithValidPubKeyEmptyContent[] = {
1518 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1519 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1520 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1521 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1522 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1523 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1524 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1525 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1526 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1527 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1528 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1529 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1530 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1531 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1532 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1533 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1534 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1535 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1536 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1537 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1538 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1539 0x00 };
1540 static const BYTE signedWithCertWithValidPubKeyContent[] = {
1541 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1542 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1543 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1544 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1545 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1546 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1547 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1548 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1549 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1550 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1551 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1552 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1553 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1554 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1555 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1556 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1557 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1558 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1559 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1560 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1561 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1562 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1563 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1564 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1565 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1566 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1567 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1568
1569 static void test_signed_msg_encoding(void)
1570 {
1571     HCRYPTMSG msg;
1572     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1573     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1574     CERT_INFO certInfo = { 0 };
1575     CERT_BLOB encodedCert = { sizeof(cert), cert };
1576     CRL_BLOB encodedCrl = { sizeof(crl), crl };
1577     char oid_common_name[] = szOID_COMMON_NAME;
1578     CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1579      encodedCommonName };
1580     CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1581     BOOL ret;
1582     HCRYPTKEY key;
1583     DWORD size;
1584
1585     certInfo.SerialNumber.cbData = sizeof(serialNum);
1586     certInfo.SerialNumber.pbData = serialNum;
1587     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1588     certInfo.Issuer.pbData = encodedCommonName;
1589     signer.pCertInfo = &certInfo;
1590     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1591     signInfo.cSigners = 1;
1592     signInfo.rgSigners = &signer;
1593
1594     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1595                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1596     if (!ret && GetLastError() == NTE_EXISTS) {
1597         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1598                                     PROV_RSA_FULL, 0);
1599     }
1600     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1601
1602     if (!ret) {
1603         skip("No context for tests\n");
1604         return;
1605     }
1606
1607     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1608      0, 0, &key);
1609     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1610
1611     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1612      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1613     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1614
1615     check_param("detached signed empty bare content", msg,
1616      CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1617      sizeof(signedEmptyBareContent));
1618     check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1619      signedEmptyContent, sizeof(signedEmptyContent));
1620     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1621     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1622     check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1623      signedHash, sizeof(signedHash));
1624     check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1625      detachedSignedBareContent, sizeof(detachedSignedBareContent));
1626     check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1627      detachedSignedContent, sizeof(detachedSignedContent));
1628     SetLastError(0xdeadbeef);
1629     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1630     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1631      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1632     check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1633      signedEncodedSigner, sizeof(signedEncodedSigner));
1634
1635     CryptMsgClose(msg);
1636
1637     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1638      NULL, NULL);
1639     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1640
1641     check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1642      signedEmptyBareContent, sizeof(signedEmptyBareContent));
1643     check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1644      signedEmptyContent, sizeof(signedEmptyContent));
1645     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1646     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1647     check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1648      signedBareContent, sizeof(signedBareContent));
1649     check_param("signed content", msg, CMSG_CONTENT_PARAM,
1650      signedContent, sizeof(signedContent));
1651
1652     CryptMsgClose(msg);
1653
1654     signer.cAuthAttr = 1;
1655     signer.rgAuthAttr = &attr;
1656     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1657      NULL, NULL);
1658     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1659
1660     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1661     check_param("signed with auth attrs bare content", msg,
1662      CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1663      sizeof(signedWithAuthAttrsBareContent));
1664
1665     CryptMsgClose(msg);
1666
1667     signer.cAuthAttr = 0;
1668     signInfo.rgCertEncoded = &encodedCert;
1669     signInfo.cCertEncoded = 1;
1670     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1671      NULL, NULL);
1672     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1673
1674     check_param("signed with cert empty bare content", msg,
1675      CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1676      sizeof(signedWithCertEmptyBareContent));
1677     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1678     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1679     check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1680      signedWithCertBareContent, sizeof(signedWithCertBareContent));
1681
1682     CryptMsgClose(msg);
1683
1684     signInfo.cCertEncoded = 0;
1685     signInfo.rgCrlEncoded = &encodedCrl;
1686     signInfo.cCrlEncoded = 1;
1687     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1688      NULL, NULL);
1689     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1690
1691     check_param("signed with crl empty bare content", msg,
1692      CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1693      sizeof(signedWithCrlEmptyBareContent));
1694     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1695     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1696     check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1697      signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1698
1699     CryptMsgClose(msg);
1700
1701     signInfo.cCertEncoded = 1;
1702     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1703      NULL, NULL);
1704     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1705
1706     check_param("signed with cert and crl empty bare content", msg,
1707      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1708      sizeof(signedWithCertAndCrlEmptyBareContent));
1709     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1710     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1711     check_param("signed with cert and crl bare content", msg,
1712      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1713      sizeof(signedWithCertAndCrlBareContent));
1714
1715     CryptMsgClose(msg);
1716
1717     /* Test with a cert with a (bogus) public key */
1718     signInfo.cCrlEncoded = 0;
1719     encodedCert.cbData = sizeof(v1CertWithPubKey);
1720     encodedCert.pbData = v1CertWithPubKey;
1721     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1722      NULL, NULL);
1723     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1724     check_param("signedWithCertWithPubKeyBareContent", msg,
1725      CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1726      sizeof(signedWithCertWithPubKeyBareContent));
1727     CryptMsgClose(msg);
1728
1729     encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1730     encodedCert.pbData = v1CertWithValidPubKey;
1731     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1732      NULL, NULL);
1733     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1734     check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1735      CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyEmptyContent,
1736      sizeof(signedWithCertWithValidPubKeyEmptyContent));
1737     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1738     check_param("signedWithCertWithValidPubKeyContent", msg,
1739      CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1740      sizeof(signedWithCertWithValidPubKeyContent));
1741     CryptMsgClose(msg);
1742
1743     CryptDestroyKey(key);
1744     CryptReleaseContext(signer.hCryptProv, 0);
1745     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1746      CRYPT_DELETEKEYSET);
1747 }
1748
1749 static void test_signed_msg_get_param(void)
1750 {
1751     BOOL ret;
1752     HCRYPTMSG msg;
1753     DWORD size, value = 0;
1754     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1755     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1756     CERT_INFO certInfo = { 0 };
1757
1758     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1759      NULL, NULL);
1760     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1761
1762     /* Content and bare content are always gettable */
1763     size = 0;
1764     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1765     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1766     size = 0;
1767     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1768     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1769     /* For "signed" messages, so is the version. */
1770     size = 0;
1771     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1772     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1773     size = sizeof(value);
1774     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1775     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1776     ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1777     /* But for this message, with no signers, the hash and signer aren't
1778      * available.
1779      */
1780     size = 0;
1781     SetLastError(0xdeadbeef);
1782     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1783     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1784      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1785     SetLastError(0xdeadbeef);
1786     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1787     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1788      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1789     /* As usual, the type isn't available. */
1790     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1791     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1792      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1793
1794     CryptMsgClose(msg);
1795
1796     certInfo.SerialNumber.cbData = sizeof(serialNum);
1797     certInfo.SerialNumber.pbData = serialNum;
1798     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1799     certInfo.Issuer.pbData = encodedCommonName;
1800     signer.pCertInfo = &certInfo;
1801     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1802     signInfo.cSigners = 1;
1803     signInfo.rgSigners = &signer;
1804
1805     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1806                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1807     if (!ret && GetLastError() == NTE_EXISTS) {
1808         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1809                                     PROV_RSA_FULL, 0);
1810     }
1811     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1812
1813     if (!ret) {
1814         skip("No context for tests\n");
1815         return;
1816     }
1817
1818     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1819      NULL, NULL);
1820     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1821
1822     /* This message, with one signer, has the hash and signer for index 0
1823      * available, but not for other indexes.
1824      */
1825     size = 0;
1826     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1827     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1828     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1829     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1830     size = 0;
1831     SetLastError(0xdeadbeef);
1832     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1833     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1834      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1835     SetLastError(0xdeadbeef);
1836     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1837     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1838      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1839     /* As usual, the type isn't available. */
1840     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1841     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1842      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1843
1844     CryptMsgClose(msg);
1845
1846     CryptReleaseContext(signer.hCryptProv, 0);
1847     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1848      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1849 }
1850
1851 static void test_signed_msg(void)
1852 {
1853     test_signed_msg_open();
1854     test_signed_msg_update();
1855     test_signed_msg_encoding();
1856     test_signed_msg_get_param();
1857 }
1858
1859 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1860 static const struct update_accum a4 = { 1, &b4 };
1861
1862 static const BYTE bogusOIDContent[] = {
1863 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1864 0x04,0x00 };
1865 static const BYTE bogusHashContent[] = {
1866 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1867 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1868 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1869 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1870 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1871
1872 static void test_decode_msg_update(void)
1873 {
1874     HCRYPTMSG msg;
1875     BOOL ret;
1876     CMSG_STREAM_INFO streamInfo = { 0 };
1877     DWORD i;
1878     struct update_accum accum = { 0, NULL };
1879
1880     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1881     /* Update with a full message in a final update */
1882     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1883     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1884     /* Can't update after a final update */
1885     SetLastError(0xdeadbeef);
1886     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1887     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1888      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1889     CryptMsgClose(msg);
1890
1891     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1892     /* Can't send a non-final update without streaming */
1893     SetLastError(0xdeadbeef);
1894     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1895      FALSE);
1896     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1897      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1898     /* A subsequent final update succeeds */
1899     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1900     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1901     CryptMsgClose(msg);
1902
1903     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1904     /* Updating a message that has a NULL stream callback fails */
1905     SetLastError(0xdeadbeef);
1906     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1907      FALSE);
1908     todo_wine
1909     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1910      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1911     /* Changing the callback pointer after the fact yields the same error (so
1912      * the message must copy the stream info, not just store a pointer to it)
1913      */
1914     streamInfo.pfnStreamOutput = nop_stream_output;
1915     SetLastError(0xdeadbeef);
1916     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1917      FALSE);
1918     todo_wine
1919     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1920      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1921     CryptMsgClose(msg);
1922
1923     /* Empty non-final updates are allowed when streaming.. */
1924     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1925     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1926     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1927     /* but final updates aren't when not enough data has been received. */
1928     SetLastError(0xdeadbeef);
1929     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1930     todo_wine
1931     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1932      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1933     CryptMsgClose(msg);
1934
1935     /* Updating the message byte by byte is legal */
1936     streamInfo.pfnStreamOutput = accumulating_stream_output;
1937     streamInfo.pvArg = &accum;
1938     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1939     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1940         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1941     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1942     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1943     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1944     CryptMsgClose(msg);
1945     todo_wine
1946     check_updates("byte-by-byte empty content", &a4, &accum);
1947     free_updates(&accum);
1948
1949     /* Decoding bogus content fails in non-streaming mode.. */
1950     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1951     SetLastError(0xdeadbeef);
1952     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1953     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1954      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1955     CryptMsgClose(msg);
1956     /* and as the final update in streaming mode.. */
1957     streamInfo.pfnStreamOutput = nop_stream_output;
1958     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1959     SetLastError(0xdeadbeef);
1960     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1961     todo_wine
1962     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1963      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1964     CryptMsgClose(msg);
1965     /* and even as a non-final update in streaming mode. */
1966     streamInfo.pfnStreamOutput = nop_stream_output;
1967     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1968     SetLastError(0xdeadbeef);
1969     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1970     todo_wine
1971     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1972      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1973     CryptMsgClose(msg);
1974
1975     /* An empty message can be opened with undetermined type.. */
1976     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1977     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1978      TRUE);
1979     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1980     CryptMsgClose(msg);
1981     /* but decoding it as an explicitly typed message fails. */
1982     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1983      NULL);
1984     SetLastError(0xdeadbeef);
1985     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1986      TRUE);
1987     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1988      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1989     CryptMsgClose(msg);
1990     /* On the other hand, decoding the bare content of an empty message fails
1991      * with unspecified type..
1992      */
1993     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1994     SetLastError(0xdeadbeef);
1995     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1996      sizeof(dataEmptyBareContent), TRUE);
1997     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1998      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1999     CryptMsgClose(msg);
2000     /* but succeeds with explicit type. */
2001     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2002      NULL);
2003     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2004      sizeof(dataEmptyBareContent), TRUE);
2005     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2006     CryptMsgClose(msg);
2007
2008     /* Decoding valid content with an unsupported OID fails */
2009     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2010     SetLastError(0xdeadbeef);
2011     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2012     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2013      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2014     CryptMsgClose(msg);
2015
2016     /* Similarly, opening an empty hash with unspecified type succeeds.. */
2017     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2018     SetLastError(0xdeadbeef);
2019     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2020     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2021     CryptMsgClose(msg);
2022     /* while with specified type it fails. */
2023     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2024      NULL);
2025     SetLastError(0xdeadbeef);
2026     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2027     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2028      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2029     CryptMsgClose(msg);
2030     /* On the other hand, decoding the bare content of an empty hash message
2031      * fails with unspecified type..
2032      */
2033     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2034     SetLastError(0xdeadbeef);
2035     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2036      sizeof(hashEmptyBareContent), TRUE);
2037     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2038      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2039     CryptMsgClose(msg);
2040     /* but succeeds with explicit type. */
2041     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2042      NULL);
2043     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2044      sizeof(hashEmptyBareContent), TRUE);
2045     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2046     CryptMsgClose(msg);
2047
2048     /* And again, opening a (non-empty) hash message with unspecified type
2049      * succeeds..
2050      */
2051     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2052     SetLastError(0xdeadbeef);
2053     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2054     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2055     CryptMsgClose(msg);
2056     /* while with specified type it fails.. */
2057     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2058      NULL);
2059     SetLastError(0xdeadbeef);
2060     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2061     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2062      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2063     CryptMsgClose(msg);
2064     /* and decoding the bare content of a non-empty hash message fails with
2065      * unspecified type..
2066      */
2067     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2068     SetLastError(0xdeadbeef);
2069     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2070     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2071      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
2072     CryptMsgClose(msg);
2073     /* but succeeds with explicit type. */
2074     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2075      NULL);
2076     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2077     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2078     CryptMsgClose(msg);
2079
2080     /* Opening a (non-empty) hash message with unspecified type and a bogus
2081      * hash value succeeds..
2082      */
2083     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2084     SetLastError(0xdeadbeef);
2085     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2086     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2087     CryptMsgClose(msg);
2088
2089     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2090     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2091     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2092     CryptMsgClose(msg);
2093     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2094     SetLastError(0xdeadbeef);
2095     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2096      sizeof(signedWithCertAndCrlBareContent), TRUE);
2097     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2098      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2099     CryptMsgClose(msg);
2100     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2101      NULL);
2102     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2103      sizeof(signedWithCertAndCrlBareContent), TRUE);
2104     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2105     CryptMsgClose(msg);
2106
2107     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2108      NULL, NULL);
2109     /* The first update succeeds.. */
2110     ret = CryptMsgUpdate(msg, detachedSignedContent,
2111      sizeof(detachedSignedContent), TRUE);
2112     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2113     /* as does a second (probably to update the detached portion).. */
2114     ret = CryptMsgUpdate(msg, detachedSignedContent,
2115      sizeof(detachedSignedContent), TRUE);
2116     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2117     /* while a third fails. */
2118     ret = CryptMsgUpdate(msg, detachedSignedContent,
2119      sizeof(detachedSignedContent), TRUE);
2120     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2121      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2122     CryptMsgClose(msg);
2123 }
2124
2125 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2126  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2127
2128 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2129  const CMSG_SIGNER_INFO *expected)
2130 {
2131     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2132      expected->dwVersion, got->dwVersion);
2133     ok(got->Issuer.cbData == expected->Issuer.cbData,
2134      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2135      got->Issuer.cbData);
2136     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2137      "Unexpected issuer\n");
2138     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2139      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2140      got->SerialNumber.cbData);
2141     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2142      got->SerialNumber.cbData), "Unexpected serial number\n");
2143     /* FIXME: check more things */
2144 }
2145
2146 static const BYTE signedWithCertAndCrlComputedHash[] = {
2147 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2148 0x2f };
2149
2150 static void test_decode_msg_get_param(void)
2151 {
2152     HCRYPTMSG msg;
2153     BOOL ret;
2154     DWORD size = 0, value;
2155     LPBYTE buf;
2156
2157     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2158     SetLastError(0xdeadbeef);
2159     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2160     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2161      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2162     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2163     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2164      sizeof(msgData));
2165     CryptMsgClose(msg);
2166
2167     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2168     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2169     check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2170     check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2171     check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2172      emptyHashParam, sizeof(emptyHashParam));
2173     CryptMsgClose(msg);
2174     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2175     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2176     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2177      sizeof(msgData));
2178     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2179      sizeof(hashParam));
2180     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2181      hashParam, sizeof(hashParam));
2182     /* Curiously, getting the hash of index 1 succeeds, even though there's
2183      * only one hash.
2184      */
2185     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2186     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2187     buf = CryptMemAlloc(size);
2188     if (buf)
2189     {
2190         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2191         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2192         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2193         CryptMemFree(buf);
2194     }
2195     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2196      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2197     value = CMSG_HASHED_DATA_V0;
2198     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2199      sizeof(value));
2200     CryptMsgClose(msg);
2201
2202     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2203     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2204     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2205     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2206      sizeof(msgData));
2207     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2208      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2209     size = sizeof(value);
2210     value = 2112;
2211     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2212     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2213     ok(value == 1, "Expected 1 signer, got %d\n", value);
2214     size = 0;
2215     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2216     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2217     if (ret)
2218         buf = CryptMemAlloc(size);
2219     else
2220         buf = NULL;
2221     if (buf)
2222     {
2223         CMSG_SIGNER_INFO signer = { 0 };
2224
2225         signer.dwVersion = 1;
2226         signer.Issuer.cbData = sizeof(encodedCommonName);
2227         signer.Issuer.pbData = encodedCommonName;
2228         signer.SerialNumber.cbData = sizeof(serialNum);
2229         signer.SerialNumber.pbData = serialNum;
2230         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2231         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2232         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2233         CryptMemFree(buf);
2234     }
2235     /* index is ignored when getting signer count */
2236     size = sizeof(value);
2237     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2238     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2239     ok(value == 1, "Expected 1 signer, got %d\n", value);
2240     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2241     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2242     ok(value == 0, "Expected 0 certs, got %d\n", value);
2243     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2244     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2245     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2246     CryptMsgClose(msg);
2247     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2248      NULL);
2249     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2250      sizeof(signedWithCertAndCrlBareContent), TRUE);
2251     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2252     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2253     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2254     ok(value == 1, "Expected 1 cert, got %d\n", value);
2255     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2256     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2257     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2258     ok(value == 1, "Expected 1 CRL, got %d\n", value);
2259     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2260     check_param("signed with cert and CRL computed hash", msg,
2261      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2262      sizeof(signedWithCertAndCrlComputedHash));
2263     CryptMsgClose(msg);
2264 }
2265
2266 static void test_decode_msg(void)
2267 {
2268     test_decode_msg_update();
2269     test_decode_msg_get_param();
2270 }
2271
2272 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2273 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2274 static BYTE encodedPubKey[] = {
2275 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2276 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2277 0x0d,0x0e,0x0f };
2278 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2279 static BYTE mod_encoded[] = {
2280  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2281  0x01,0x00,0x01 };
2282
2283 static void test_msg_control(void)
2284 {
2285     static char oid_rsa_rsa[] = szOID_RSA_RSA;
2286     BOOL ret;
2287     HCRYPTMSG msg;
2288     DWORD i;
2289     CERT_INFO certInfo = { 0 };
2290     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2291     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2292     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2293
2294     /* Crashes
2295     ret = CryptMsgControl(NULL, 0, 0, NULL);
2296     */
2297
2298     /* Data encode messages don't allow any sort of control.. */
2299     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2300      NULL);
2301     /* either with no prior update.. */
2302     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2303     {
2304         SetLastError(0xdeadbeef);
2305         ret = CryptMsgControl(msg, 0, i, NULL);
2306         ok(!ret && GetLastError() == E_INVALIDARG,
2307          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2308     }
2309     /* or after an update. */
2310     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2311     {
2312         SetLastError(0xdeadbeef);
2313         ret = CryptMsgControl(msg, 0, i, NULL);
2314         ok(!ret && GetLastError() == E_INVALIDARG,
2315          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2316     }
2317     CryptMsgClose(msg);
2318
2319     /* Hash encode messages don't allow any sort of control.. */
2320     hashInfo.cbSize = sizeof(hashInfo);
2321     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2322     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2323      NULL, NULL);
2324     /* either with no prior update.. */
2325     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2326     {
2327         SetLastError(0xdeadbeef);
2328         ret = CryptMsgControl(msg, 0, i, NULL);
2329         ok(!ret && GetLastError() == E_INVALIDARG,
2330          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2331     }
2332     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2333     /* or after an update. */
2334     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2335     {
2336         SetLastError(0xdeadbeef);
2337         ret = CryptMsgControl(msg, 0, i, NULL);
2338         ok(!ret && GetLastError() == E_INVALIDARG,
2339          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2340     }
2341     CryptMsgClose(msg);
2342
2343     /* Signed encode messages likewise don't allow any sort of control.. */
2344     signInfo.cbSize = sizeof(signInfo);
2345     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2346      NULL, NULL);
2347     /* either before an update.. */
2348     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2349     {
2350         SetLastError(0xdeadbeef);
2351         ret = CryptMsgControl(msg, 0, i, NULL);
2352         ok(!ret && GetLastError() == E_INVALIDARG,
2353          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2354     }
2355     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2356     /* or after an update. */
2357     for (i = 1; have_nt && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2358     {
2359         SetLastError(0xdeadbeef);
2360         ret = CryptMsgControl(msg, 0, i, NULL);
2361         ok(!ret && GetLastError() == E_INVALIDARG,
2362          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2363     }
2364     CryptMsgClose(msg);
2365
2366     /* Decode messages behave a bit differently. */
2367     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2368     /* Bad control type */
2369     SetLastError(0xdeadbeef);
2370     ret = CryptMsgControl(msg, 0, 0, NULL);
2371     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2372      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2373     SetLastError(0xdeadbeef);
2374     ret = CryptMsgControl(msg, 1, 0, NULL);
2375     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2376      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2377     /* Can't verify the hash of an indeterminate-type message */
2378     SetLastError(0xdeadbeef);
2379     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2380     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2381      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2382     /* Crashes
2383     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2384      */
2385     /* Can't decrypt an indeterminate-type message */
2386     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2387     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2388      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2389     CryptMsgClose(msg);
2390
2391     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2392      NULL);
2393     /* Can't verify the hash of an empty message */
2394     SetLastError(0xdeadbeef);
2395     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2396     todo_wine
2397     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2398      "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2399     /* Crashes
2400     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2401      */
2402     /* Can't verify the signature of a hash message */
2403     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2404     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2405      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2406     CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2407      TRUE);
2408     /* Oddly enough, this fails */
2409     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2410     todo_wine
2411     ok(!ret, "Expected failure\n");
2412     CryptMsgClose(msg);
2413     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2414      NULL);
2415     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2416     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2417     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2418     /* Can't decrypt an indeterminate-type message */
2419     SetLastError(0xdeadbeef);
2420     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2421     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2422      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2423     CryptMsgClose(msg);
2424
2425     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2426      NULL);
2427     /* Can't verify the hash of a signed message */
2428     SetLastError(0xdeadbeef);
2429     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2430     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2431      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2432     /* Can't decrypt a signed message */
2433     SetLastError(0xdeadbeef);
2434     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2435     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2436      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2437     /* Crash
2438     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2439     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2440      */
2441     CryptMsgUpdate(msg, signedWithCertBareContent,
2442      sizeof(signedWithCertBareContent), TRUE);
2443     /* With an empty cert info, the signer can't be found in the message (and
2444      * the signature can't be verified.
2445      */
2446     SetLastError(0xdeadbeef);
2447     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2448     ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2449      "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2450     /* The cert info is expected to have an issuer, serial number, and public
2451      * key info set.
2452      */
2453     certInfo.SerialNumber.cbData = sizeof(serialNum);
2454     certInfo.SerialNumber.pbData = serialNum;
2455     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2456     certInfo.Issuer.pbData = encodedCommonName;
2457     SetLastError(0xdeadbeef);
2458     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2459     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2460      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2461     CryptMsgClose(msg);
2462     /* This cert has a public key, but it's not in a usable form */
2463     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2464      NULL);
2465     CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2466      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2467     /* Again, cert info needs to have a public key set */
2468     SetLastError(0xdeadbeef);
2469     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2470     ok(!ret &&
2471      (GetLastError() == CRYPT_E_ASN1_EOD ||
2472       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2473      "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2474     /* The public key is supposed to be in encoded form.. */
2475     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2476     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2477     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2478     SetLastError(0xdeadbeef);
2479     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2480     ok(!ret &&
2481      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2482       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2483      "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2484     /* but not as a X509_PUBLIC_KEY_INFO.. */
2485     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2486     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2487     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2488     SetLastError(0xdeadbeef);
2489     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2490     ok(!ret &&
2491      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2492       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2493      "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2494     /* This decodes successfully, but it doesn't match any key in the message */
2495     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2496     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2497     SetLastError(0xdeadbeef);
2498     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2499     /* In Wine's rsaenh, this fails to decode because the key length is too
2500      * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
2501      * now.
2502      */
2503     todo_wine
2504     ok(!ret &&
2505      (GetLastError() == NTE_BAD_SIGNATURE ||
2506       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2507      "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2508     CryptMsgClose(msg);
2509     /* A message with no data doesn't have a valid signature */
2510     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2511     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2512      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2513     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2514     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2515     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2516     SetLastError(0xdeadbeef);
2517     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2518     ok(!ret &&
2519      (GetLastError() == NTE_BAD_SIGNATURE ||
2520       GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2521      "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2522     CryptMsgClose(msg);
2523     /* Finally, this succeeds */
2524     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2525     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2526      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2527     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2528     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2529     CryptMsgClose(msg);
2530 }
2531
2532 /* win9x has much less parameter checks and will crash on many tests
2533  * this code is from test_signed_msg_update()
2534  */
2535 static BOOL detect_nt(void)
2536 {
2537     BOOL ret;
2538     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
2539     CERT_INFO certInfo = { 0 };
2540
2541
2542     certInfo.SerialNumber.cbData = sizeof(serialNum);
2543     certInfo.SerialNumber.pbData = serialNum;
2544     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2545     certInfo.Issuer.pbData = encodedCommonName;
2546     signer.pCertInfo = &certInfo;
2547     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2548
2549     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2550                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
2551     if (!ret && GetLastError() == NTE_EXISTS) {
2552         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
2553                                     PROV_RSA_FULL, 0);
2554     }
2555
2556     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
2557
2558     /* cleanup */
2559     CryptReleaseContext(signer.hCryptProv, 0);
2560     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
2561                           CRYPT_DELETEKEYSET);
2562
2563     return TRUE;
2564 }
2565
2566 static void test_msg_get_and_verify_signer(void)
2567 {
2568     BOOL ret;
2569     HCRYPTMSG msg;
2570     PCCERT_CONTEXT signer;
2571     DWORD signerIndex;
2572     HCERTSTORE store;
2573
2574     /* Crash */
2575     if (0)
2576     {
2577         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
2578         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
2579     }
2580
2581     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2582     /* An empty message has no signer */
2583     SetLastError(0xdeadbeef);
2584     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2585     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2586      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2587     /* The signer is cleared on error */
2588     signer = (PCCERT_CONTEXT)0xdeadbeef;
2589     SetLastError(0xdeadbeef);
2590     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2591     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2592      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2593     ok(!signer, "expected signer to be NULL\n");
2594     /* The signer index is also cleared on error */
2595     signerIndex = 0xdeadbeef;
2596     SetLastError(0xdeadbeef);
2597     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2598     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2599      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2600     ok(!signerIndex, "expected 0, got %d\n", signerIndex);
2601     /* An unsigned message (msgData isn't a signed message at all)
2602      * likewise has no signer.
2603      */
2604     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2605     SetLastError(0xdeadbeef);
2606     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2607     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2608      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2609     CryptMsgClose(msg);
2610
2611     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2612     /* A "signed" message created with no signer cert likewise has no signer */
2613     CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
2614     SetLastError(0xdeadbeef);
2615     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2616     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2617      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2618     CryptMsgClose(msg);
2619
2620     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2621     /* A signed message succeeds, .. */
2622     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2623      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2624     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
2625     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2626     /* the signer index can be retrieved, .. */
2627     signerIndex = 0xdeadbeef;
2628     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
2629     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2630     ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
2631     /* as can the signer cert. */
2632     signer = (PCCERT_CONTEXT)0xdeadbeef;
2633     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
2634     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2635     ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
2636      "expected a valid signer\n");
2637     if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
2638         CertFreeCertificateContext(signer);
2639     /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
2640      */
2641     signerIndex = 0xdeadbeef;
2642     SetLastError(0xdeadbeef);
2643     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
2644      NULL, &signerIndex);
2645     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
2646      "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
2647     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
2648      * message signer not to be found.
2649      */
2650     SetLastError(0xdeadbeef);
2651     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
2652      NULL, NULL);
2653     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2654      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2655     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
2656      * the message signer not to be found.
2657      */
2658     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2659      CERT_STORE_CREATE_NEW_FLAG, NULL);
2660     SetLastError(0xdeadbeef);
2661     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
2662      NULL, NULL);
2663     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
2664      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
2665     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
2666      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
2667      CERT_STORE_ADD_ALWAYS, NULL);
2668     ok(ret, "CertAddEncodedCertificateToStore failed: 0x%08x\n",
2669      GetLastError());
2670     /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
2671      * the signer succeeds.
2672      */
2673     SetLastError(0xdeadbeef);
2674     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
2675      NULL, NULL);
2676     ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
2677     CertCloseStore(store, 0);
2678     CryptMsgClose(msg);
2679 }
2680
2681 START_TEST(msg)
2682 {
2683     init_function_pointers();
2684     have_nt = detect_nt();
2685
2686     /* Basic parameter checking tests */
2687     test_msg_open_to_encode();
2688     test_msg_open_to_decode();
2689     test_msg_get_param();
2690     test_msg_close();
2691     test_msg_control();
2692
2693     /* Message-type specific tests */
2694     test_data_msg();
2695     test_hash_msg();
2696     test_signed_msg();
2697     test_decode_msg();
2698
2699     test_msg_get_and_verify_signer();
2700 }