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