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