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