crypt32: Allow one update to a decode message after the final update if it's a detach...
[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     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2057      NULL, NULL);
2058     /* The first update succeeds.. */
2059     ret = CryptMsgUpdate(msg, detachedSignedContent,
2060      sizeof(detachedSignedContent), TRUE);
2061     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2062     /* as does a second (probably to update the detached portion).. */
2063     ret = CryptMsgUpdate(msg, detachedSignedContent,
2064      sizeof(detachedSignedContent), TRUE);
2065     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2066     /* while a third fails. */
2067     ret = CryptMsgUpdate(msg, detachedSignedContent,
2068      sizeof(detachedSignedContent), TRUE);
2069     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2070      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2071     CryptMsgClose(msg);
2072 }
2073
2074 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2075  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2076
2077 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2078  const CMSG_SIGNER_INFO *expected)
2079 {
2080     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2081      expected->dwVersion, got->dwVersion);
2082     ok(got->Issuer.cbData == expected->Issuer.cbData,
2083      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2084      got->Issuer.cbData);
2085     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2086      "Unexpected issuer\n");
2087     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2088      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2089      got->SerialNumber.cbData);
2090     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2091      got->SerialNumber.cbData), "Unexpected serial number\n");
2092     /* FIXME: check more things */
2093 }
2094
2095 static const BYTE signedWithCertAndCrlComputedHash[] = {
2096 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2097 0x2f };
2098
2099 static void test_decode_msg_get_param(void)
2100 {
2101     HCRYPTMSG msg;
2102     BOOL ret;
2103     DWORD size = 0, value;
2104     LPBYTE buf;
2105
2106     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2107     SetLastError(0xdeadbeef);
2108     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2109     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2110      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2111     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2112     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2113      sizeof(msgData));
2114     CryptMsgClose(msg);
2115
2116     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2117     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2118     check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2119     check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2120     check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2121      emptyHashParam, sizeof(emptyHashParam));
2122     CryptMsgClose(msg);
2123     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2124     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2125     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2126      sizeof(msgData));
2127     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2128      sizeof(hashParam));
2129     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2130      hashParam, sizeof(hashParam));
2131     /* Curiously, getting the hash of index 1 succeeds, even though there's
2132      * only one hash.
2133      */
2134     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2135     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2136     buf = CryptMemAlloc(size);
2137     if (buf)
2138     {
2139         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2140         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2141         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2142         CryptMemFree(buf);
2143     }
2144     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2145      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2146     value = CMSG_HASHED_DATA_V0;
2147     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2148      sizeof(value));
2149     CryptMsgClose(msg);
2150
2151     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2152     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2153     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2154     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2155      sizeof(msgData));
2156     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2157      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2158     size = sizeof(value);
2159     value = 2112;
2160     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2161     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2162     ok(value == 1, "Expected 1 signer, got %d\n", value);
2163     size = 0;
2164     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2165     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2166     if (ret)
2167         buf = CryptMemAlloc(size);
2168     else
2169         buf = NULL;
2170     if (buf)
2171     {
2172         CMSG_SIGNER_INFO signer = { 0 };
2173
2174         signer.dwVersion = 1;
2175         signer.Issuer.cbData = sizeof(encodedCommonName);
2176         signer.Issuer.pbData = encodedCommonName;
2177         signer.SerialNumber.cbData = sizeof(serialNum);
2178         signer.SerialNumber.pbData = serialNum;
2179         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2180         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2181         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2182         CryptMemFree(buf);
2183     }
2184     /* index is ignored when getting signer count */
2185     size = sizeof(value);
2186     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2187     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2188     ok(value == 1, "Expected 1 signer, got %d\n", value);
2189     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2190     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2191     ok(value == 0, "Expected 0 certs, got %d\n", value);
2192     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2193     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2194     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2195     CryptMsgClose(msg);
2196     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2197      NULL);
2198     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2199      sizeof(signedWithCertAndCrlBareContent), TRUE);
2200     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2201     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2202     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2203     ok(value == 1, "Expected 1 cert, got %d\n", value);
2204     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2205     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2206     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2207     ok(value == 1, "Expected 1 CRL, got %d\n", value);
2208     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2209     check_param("signed with cert and CRL computed hash", msg,
2210      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2211      sizeof(signedWithCertAndCrlComputedHash));
2212     CryptMsgClose(msg);
2213 }
2214
2215 static void test_decode_msg(void)
2216 {
2217     test_decode_msg_update();
2218     test_decode_msg_get_param();
2219 }
2220
2221 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2222 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2223 static BYTE encodedPubKey[] = {
2224 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2225 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2226 0x0d,0x0e,0x0f };
2227 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2228 static BYTE mod_encoded[] = {
2229  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2230  0x01,0x00,0x01 };
2231
2232 static void test_msg_control(void)
2233 {
2234     static char oid_rsa_rsa[] = szOID_RSA_RSA;
2235     BOOL ret;
2236     HCRYPTMSG msg;
2237     DWORD i;
2238     CERT_INFO certInfo = { 0 };
2239     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2240     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2241     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2242
2243     /* Crashes
2244     ret = CryptMsgControl(NULL, 0, 0, NULL);
2245     */
2246
2247     /* Data encode messages don't allow any sort of control.. */
2248     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2249      NULL);
2250     /* either with no prior update.. */
2251     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2252     {
2253         SetLastError(0xdeadbeef);
2254         ret = CryptMsgControl(msg, 0, i, NULL);
2255         ok(!ret && GetLastError() == E_INVALIDARG,
2256          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2257     }
2258     /* or after an update. */
2259     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2260     {
2261         SetLastError(0xdeadbeef);
2262         ret = CryptMsgControl(msg, 0, i, NULL);
2263         ok(!ret && GetLastError() == E_INVALIDARG,
2264          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2265     }
2266     CryptMsgClose(msg);
2267
2268     /* Hash encode messages don't allow any sort of control.. */
2269     hashInfo.cbSize = sizeof(hashInfo);
2270     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2271     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2272      NULL, NULL);
2273     /* either with no prior update.. */
2274     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2275     {
2276         SetLastError(0xdeadbeef);
2277         ret = CryptMsgControl(msg, 0, i, NULL);
2278         ok(!ret && GetLastError() == E_INVALIDARG,
2279          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2280     }
2281     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2282     /* or after an update. */
2283     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2284     {
2285         SetLastError(0xdeadbeef);
2286         ret = CryptMsgControl(msg, 0, i, NULL);
2287         ok(!ret && GetLastError() == E_INVALIDARG,
2288          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2289     }
2290     CryptMsgClose(msg);
2291
2292     /* Signed encode messages likewise don't allow any sort of control.. */
2293     signInfo.cbSize = sizeof(signInfo);
2294     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2295      NULL, NULL);
2296     /* either before an update.. */
2297     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2298     {
2299         SetLastError(0xdeadbeef);
2300         ret = CryptMsgControl(msg, 0, i, NULL);
2301         ok(!ret && GetLastError() == E_INVALIDARG,
2302          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2303     }
2304     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2305     /* or after an update. */
2306     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2307     {
2308         SetLastError(0xdeadbeef);
2309         ret = CryptMsgControl(msg, 0, i, NULL);
2310         ok(!ret && GetLastError() == E_INVALIDARG,
2311          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2312     }
2313     CryptMsgClose(msg);
2314
2315     /* Decode messages behave a bit differently. */
2316     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2317     /* Bad control type */
2318     SetLastError(0xdeadbeef);
2319     ret = CryptMsgControl(msg, 0, 0, NULL);
2320     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2321      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2322     SetLastError(0xdeadbeef);
2323     ret = CryptMsgControl(msg, 1, 0, NULL);
2324     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2325      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2326     /* Can't verify the hash of an indeterminate-type message */
2327     SetLastError(0xdeadbeef);
2328     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2329     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2330      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2331     /* Crashes
2332     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2333      */
2334     /* Can't decrypt an indeterminate-type message */
2335     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2336     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2337      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2338     CryptMsgClose(msg);
2339
2340     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2341      NULL);
2342     /* Can't verify the hash of an empty message */
2343     SetLastError(0xdeadbeef);
2344     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2345     todo_wine
2346     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2347      "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2348     /* Crashes
2349     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2350      */
2351     /* Can't verify the signature of a hash message */
2352     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2353     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2354      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2355     CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2356      TRUE);
2357     /* Oddly enough, this fails */
2358     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2359     todo_wine
2360     ok(!ret, "Expected failure\n");
2361     CryptMsgClose(msg);
2362     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2363      NULL);
2364     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2365     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2366     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2367     /* Can't decrypt an indeterminate-type message */
2368     SetLastError(0xdeadbeef);
2369     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2370     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2371      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2372     CryptMsgClose(msg);
2373
2374     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2375      NULL);
2376     /* Can't verify the hash of a signed message */
2377     SetLastError(0xdeadbeef);
2378     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2379     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2380      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2381     /* Can't decrypt a signed message */
2382     SetLastError(0xdeadbeef);
2383     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2384     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2385      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2386     /* Crash
2387     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2388     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2389      */
2390     CryptMsgUpdate(msg, signedWithCertBareContent,
2391      sizeof(signedWithCertBareContent), TRUE);
2392     /* With an empty cert info, the signer can't be found in the message (and
2393      * the signature can't be verified.
2394      */
2395     SetLastError(0xdeadbeef);
2396     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2397     ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2398      "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2399     /* The cert info is expected to have an issuer, serial number, and public
2400      * key info set.
2401      */
2402     certInfo.SerialNumber.cbData = sizeof(serialNum);
2403     certInfo.SerialNumber.pbData = serialNum;
2404     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2405     certInfo.Issuer.pbData = encodedCommonName;
2406     SetLastError(0xdeadbeef);
2407     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2408     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2409      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2410     CryptMsgClose(msg);
2411     /* This cert has a public key, but it's not in a usable form */
2412     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2413      NULL);
2414     CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2415      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2416     /* Again, cert info needs to have a public key set */
2417     SetLastError(0xdeadbeef);
2418     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2419     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2420      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2421     /* The public key is supposed to be in encoded form.. */
2422     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2423     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2424     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2425     SetLastError(0xdeadbeef);
2426     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2427     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2428      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2429     /* but not as a X509_PUBLIC_KEY_INFO.. */
2430     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2431     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2432     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2433     SetLastError(0xdeadbeef);
2434     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2435     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2436      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2437     /* This decodes successfully, but it doesn't match any key in the message */
2438     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2439     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2440     SetLastError(0xdeadbeef);
2441     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2442     /* In Wine's rsaenh, this fails to decode because the key length is too
2443      * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
2444      * now.
2445      */
2446     todo_wine
2447     ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2448      "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2449     CryptMsgClose(msg);
2450     /* A message with no data doesn't have a valid signature */
2451     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2452     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2453      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2454     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2455     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2456     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2457     SetLastError(0xdeadbeef);
2458     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2459     ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2460      "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2461     CryptMsgClose(msg);
2462     /* Finally, this succeeds */
2463     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2464     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2465      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2466     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2467     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2468     CryptMsgClose(msg);
2469 }
2470
2471 static void test_msg_get_signer_count(void)
2472 {
2473     LONG count;
2474
2475     SetLastError(0xdeadbeef);
2476     count = CryptGetMessageSignerCount(0, NULL, 0);
2477     ok(count == -1, "Expected -1, got %d\n", count);
2478     ok(GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n",
2479      GetLastError());
2480     SetLastError(0xdeadbeef);
2481     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING, NULL, 0);
2482     ok(count == -1, "Expected -1, got %d\n", count);
2483     ok(GetLastError() == CRYPT_E_ASN1_EOD,
2484      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2485     SetLastError(0xdeadbeef);
2486     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2487      dataEmptyBareContent, sizeof(dataEmptyBareContent));
2488     ok(count == -1, "Expected -1, got %d\n", count);
2489     ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2490      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2491     SetLastError(0xdeadbeef);
2492     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2493      dataEmptyContent, sizeof(dataEmptyContent));
2494     ok(count == -1, "Expected -1, got %d\n", count);
2495     ok(GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2496      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2497     SetLastError(0xdeadbeef);
2498     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2499      signedEmptyBareContent, sizeof(signedEmptyBareContent));
2500     ok(count == -1, "Expected -1, got %d\n", count);
2501     ok(GetLastError() == CRYPT_E_ASN1_BADTAG,
2502      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2503     count = CryptGetMessageSignerCount(PKCS_7_ASN_ENCODING,
2504      signedEmptyContent, sizeof(signedEmptyContent));
2505     ok(count == 1, "Expected 1, got %d\n", count);
2506 }
2507
2508 static const BYTE signedWithCertEmptyContent[] = {
2509 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2510 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2511 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,
2512 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2513 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2514 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2515 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2516 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2517 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2518 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
2519 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2520 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
2521 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2522 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
2523 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
2524 0x00 };
2525 static const BYTE signedWithCertContent[] = {
2526 0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
2527 0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
2528 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
2529 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
2530 0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
2531 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
2532 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
2533 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
2534 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
2535 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2536 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
2537 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
2538 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,
2539 0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,
2540 0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,
2541 0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,
2542 0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,
2543 0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,
2544 0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,
2545 0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,
2546 0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
2547 static const BYTE signedWithCertWithPubKeyContent[] = {
2548 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
2549 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
2550 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,
2551 0x98,0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,
2552 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
2553 0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2554 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
2555 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,
2556 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2557 0x6e,0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2558 0x01,0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
2559 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,
2560 0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,
2561 0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
2562 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2563 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
2564 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
2565
2566 static void test_verify_message_signature(void)
2567 {
2568     BOOL ret;
2569     CRYPT_VERIFY_MESSAGE_PARA para = { 0 };
2570     PCCERT_CONTEXT cert;
2571     DWORD cbDecoded;
2572
2573     SetLastError(0xdeadbeef);
2574     ret = CryptVerifyMessageSignature(NULL, 0, NULL, 0, NULL, 0, NULL);
2575     ok(!ret && GetLastError() == E_INVALIDARG,
2576      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2577     SetLastError(0xdeadbeef);
2578     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2579     ok(!ret && GetLastError() == E_INVALIDARG,
2580      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2581     para.cbSize = sizeof(para);
2582     SetLastError(0xdeadbeef);
2583     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2584     ok(!ret && GetLastError() == E_INVALIDARG,
2585      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2586     para.cbSize = 0;
2587     para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
2588     SetLastError(0xdeadbeef);
2589     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2590     ok(!ret && GetLastError() == E_INVALIDARG,
2591      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2592     para.cbSize = sizeof(para);
2593     SetLastError(0xdeadbeef);
2594     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, NULL);
2595     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2596      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2597     /* Check whether cert is set on error */
2598     cert = (PCCERT_CONTEXT)0xdeadbeef;
2599     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, 0, &cert);
2600     ok(cert == NULL, "Expected NULL cert\n");
2601     /* Check whether cbDecoded is set on error */
2602     cbDecoded = 0xdeadbeef;
2603     ret = CryptVerifyMessageSignature(&para, 0, NULL, 0, NULL, &cbDecoded,
2604      NULL);
2605     ok(!cbDecoded, "Expected 0\n");
2606     SetLastError(0xdeadbeef);
2607     ret = CryptVerifyMessageSignature(&para, 0, dataEmptyBareContent,
2608      sizeof(dataEmptyBareContent), NULL, 0, NULL);
2609     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2610      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2611     SetLastError(0xdeadbeef);
2612     ret = CryptVerifyMessageSignature(&para, 0, dataEmptyContent,
2613      sizeof(dataEmptyContent), NULL, 0, NULL);
2614     ok(!ret && GetLastError() == CRYPT_E_UNEXPECTED_MSG_TYPE,
2615      "Expected CRYPT_E_UNEXPECTED_MSG_TYPE, got %08x\n", GetLastError());
2616     SetLastError(0xdeadbeef);
2617     ret = CryptVerifyMessageSignature(&para, 0, signedEmptyBareContent,
2618      sizeof(signedEmptyBareContent), NULL, 0, NULL);
2619     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2620      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2621     SetLastError(0xdeadbeef);
2622     ret = CryptVerifyMessageSignature(&para, 0, signedEmptyContent,
2623      sizeof(signedEmptyContent), NULL, 0, NULL);
2624     ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2625      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2626     SetLastError(0xdeadbeef);
2627     ret = CryptVerifyMessageSignature(&para, 0, signedContent,
2628      sizeof(signedContent), NULL, 0, NULL);
2629     ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2630      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2631     /* FIXME: Windows fails with CRYPT_E_NOT_FOUND for these messages, but
2632      * their signer certs have invalid public keys that fail to decode.  In
2633      * Wine therefore the failure is an ASN error.  Need some messages with
2634      * valid public keys and invalid signatures to check against.
2635      */
2636     ret = CryptVerifyMessageSignature(&para, 0, signedWithCertEmptyContent,
2637      sizeof(signedWithCertEmptyContent), NULL, 0, NULL);
2638     ok(!ret, "Expected failure\n");
2639     ret = CryptVerifyMessageSignature(&para, 0, signedWithCertContent,
2640      sizeof(signedWithCertContent), NULL, 0, NULL);
2641     ok(!ret, "Expected failure\n");
2642     ret = CryptVerifyMessageSignature(&para, 0, signedWithCertWithPubKeyContent,
2643      sizeof(signedWithCertWithPubKeyContent), NULL, 0, NULL);
2644     ok(!ret, "Expected failure\n");
2645 }
2646
2647 START_TEST(msg)
2648 {
2649      init_function_pointers();
2650
2651     /* Basic parameter checking tests */
2652     test_msg_open_to_encode();
2653     test_msg_open_to_decode();
2654     test_msg_get_param();
2655     test_msg_close();
2656     test_msg_control();
2657
2658     /* Message-type specific tests */
2659     test_data_msg();
2660     test_hash_msg();
2661     test_signed_msg();
2662     test_decode_msg();
2663
2664     /* simplified message functions */
2665     test_msg_get_signer_count();
2666     test_verify_message_signature();
2667 }