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