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