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