crypt32/tests: Use pCryptAcquireContextA.
[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     if (context)
2085     {
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     else
2095         win_skip("failed to create certificate context, skipping a test\n");
2096
2097     SetLastError(0xdeadbeef);
2098     ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2099      PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2100     ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2101     SetLastError(0xdeadbeef);
2102     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2103      &envelopedInfo, NULL, NULL);
2104     todo_wine
2105     ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2106     CryptMsgClose(msg);
2107
2108     CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2109     CertFreeCertificateContext(context);
2110 }
2111
2112 static void test_enveloped_msg_update(void)
2113 {
2114     HCRYPTMSG msg;
2115     BOOL ret;
2116     CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2117      { oid_rsa_rc4, { 0, NULL } }, NULL };
2118     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2119
2120     SetLastError(0xdeadbeef);
2121     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2122      &envelopedInfo, NULL, NULL);
2123     todo_wine
2124     ok(msg != NULL ||
2125      broken(!msg), /* Win9x */
2126      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2127     if (msg)
2128     {
2129         SetLastError(0xdeadbeef);
2130         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2131         todo_wine
2132         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2133          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2134         SetLastError(0xdeadbeef);
2135         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2136         todo_wine
2137         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2138         SetLastError(0xdeadbeef);
2139         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2140         todo_wine
2141         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2142          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2143         CryptMsgClose(msg);
2144     }
2145     SetLastError(0xdeadbeef);
2146     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2147      &envelopedInfo, NULL, NULL);
2148     todo_wine
2149     ok(msg != NULL ||
2150      broken(!msg), /* Win9x */
2151      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2152     if (msg)
2153     {
2154         SetLastError(0xdeadbeef);
2155         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2156         todo_wine
2157         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2158          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2159         SetLastError(0xdeadbeef);
2160         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2161         todo_wine
2162         ok(ret ||
2163          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2164          "CryptMsgUpdate failed: %08x\n", GetLastError());
2165         SetLastError(0xdeadbeef);
2166         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2167         todo_wine
2168         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2169          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2170         CryptMsgClose(msg);
2171     }
2172     SetLastError(0xdeadbeef);
2173     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2174      CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2175     todo_wine
2176     ok(msg != NULL ||
2177      broken(!msg), /* Win9x */
2178      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2179     if (msg)
2180     {
2181         SetLastError(0xdeadbeef);
2182         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2183         todo_wine
2184         ok(!ret && GetLastError() == E_INVALIDARG,
2185          "expected E_INVALIDARG, got %08x\n", GetLastError());
2186         SetLastError(0xdeadbeef);
2187         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2188         todo_wine
2189         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2190         CryptMsgClose(msg);
2191     }
2192     SetLastError(0xdeadbeef);
2193     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2194      CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2195     todo_wine
2196     ok(msg != NULL ||
2197      broken(!msg), /* Win9x */
2198      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2199     if (msg)
2200     {
2201         SetLastError(0xdeadbeef);
2202         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2203         todo_wine
2204         ok(!ret && GetLastError() == E_INVALIDARG,
2205          "expected E_INVALIDARG, got %08x\n", GetLastError());
2206         SetLastError(0xdeadbeef);
2207         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2208         todo_wine
2209         ok(ret ||
2210          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2211          "CryptMsgUpdate failed: %08x\n", GetLastError());
2212         CryptMsgClose(msg);
2213     }
2214     SetLastError(0xdeadbeef);
2215     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2216      &envelopedInfo, NULL, &streamInfo);
2217     todo_wine
2218     ok(msg != NULL ||
2219      broken(!msg), /* Win9x */
2220      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2221     if (msg)
2222     {
2223         SetLastError(0xdeadbeef);
2224         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2225         todo_wine
2226         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2227         SetLastError(0xdeadbeef);
2228         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2229         todo_wine
2230         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2231         CryptMsgClose(msg);
2232     }
2233     SetLastError(0xdeadbeef);
2234     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2235      &envelopedInfo, NULL, &streamInfo);
2236     todo_wine
2237     ok(msg != NULL ||
2238      broken(!msg), /* Win9x */
2239      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2240     if (msg)
2241     {
2242         SetLastError(0xdeadbeef);
2243         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2244         todo_wine
2245         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2246         SetLastError(0xdeadbeef);
2247         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2248         todo_wine
2249         ok(ret ||
2250          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2251          "CryptMsgUpdate failed: %08x\n", GetLastError());
2252         CryptMsgClose(msg);
2253     }
2254 }
2255
2256 static const BYTE envelopedEmptyBareContent[] = {
2257 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2258 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2259 0x03,0x04,0x05,0x00,0x80,0x00 };
2260 static const BYTE envelopedEmptyContent[] = {
2261 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2262 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2263 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2264 0x03,0x04,0x05,0x00,0x80,0x00 };
2265
2266 static void test_enveloped_msg_encoding(void)
2267 {
2268     HCRYPTMSG msg;
2269     CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2270      { oid_rsa_rc4, { 0, NULL } }, NULL };
2271
2272     SetLastError(0xdeadbeef);
2273     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2274      &envelopedInfo, NULL, NULL);
2275     todo_wine
2276     ok(msg != NULL ||
2277      broken(!msg), /* Win9x */
2278      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2279     if (msg)
2280     {
2281         check_param("enveloped empty bare content", msg,
2282          CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2283          sizeof(envelopedEmptyBareContent));
2284         check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2285          envelopedEmptyContent, sizeof(envelopedEmptyContent));
2286         CryptMsgClose(msg);
2287     }
2288 }
2289
2290 static void test_enveloped_msg(void)
2291 {
2292     test_enveloped_msg_open();
2293     test_enveloped_msg_update();
2294     test_enveloped_msg_encoding();
2295 }
2296
2297 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2298 static const struct update_accum a4 = { 1, &b4 };
2299
2300 static const BYTE bogusOIDContent[] = {
2301 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2302 0x04,0x00 };
2303 static const BYTE bogusHashContent[] = {
2304 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2305 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2306 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2307 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2308 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2309 static const BYTE envelopedBareContentWithoutData[] = {
2310 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2311 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2312 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2313 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2314 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2315 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2316 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2317 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2318 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2319 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2320 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2321 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2322 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2323 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2324 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2325
2326 static void test_decode_msg_update(void)
2327 {
2328     HCRYPTMSG msg;
2329     BOOL ret;
2330     CMSG_STREAM_INFO streamInfo = { 0 };
2331     DWORD i;
2332     struct update_accum accum = { 0, NULL };
2333
2334     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2335     /* Update with a full message in a final update */
2336     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2337     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2338     /* Can't update after a final update */
2339     SetLastError(0xdeadbeef);
2340     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2341     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2342      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2343     CryptMsgClose(msg);
2344
2345     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2346     /* Can't send a non-final update without streaming */
2347     SetLastError(0xdeadbeef);
2348     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2349      FALSE);
2350     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2351      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2352     /* A subsequent final update succeeds */
2353     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2354     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2355     CryptMsgClose(msg);
2356
2357     if (!old_crypt32)
2358     {
2359         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2360         /* Updating a message that has a NULL stream callback fails */
2361         SetLastError(0xdeadbeef);
2362         /* Crashes on some Win9x */
2363         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2364          FALSE);
2365         todo_wine
2366         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2367          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2368          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2369          GetLastError());
2370         /* Changing the callback pointer after the fact yields the same error (so
2371          * the message must copy the stream info, not just store a pointer to it)
2372          */
2373         streamInfo.pfnStreamOutput = nop_stream_output;
2374         SetLastError(0xdeadbeef);
2375         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2376          FALSE);
2377         todo_wine
2378         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2379          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2380          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2381          GetLastError());
2382         CryptMsgClose(msg);
2383     }
2384
2385     /* Empty non-final updates are allowed when streaming.. */
2386     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2387     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2388     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2389     /* but final updates aren't when not enough data has been received. */
2390     SetLastError(0xdeadbeef);
2391     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2392     todo_wine
2393     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2394      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2395     CryptMsgClose(msg);
2396
2397     /* Updating the message byte by byte is legal */
2398     streamInfo.pfnStreamOutput = accumulating_stream_output;
2399     streamInfo.pvArg = &accum;
2400     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2401     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2402         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2403     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2404     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2405     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2406     CryptMsgClose(msg);
2407     todo_wine
2408     check_updates("byte-by-byte empty content", &a4, &accum);
2409     free_updates(&accum);
2410
2411     /* Decoding bogus content fails in non-streaming mode.. */
2412     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2413     SetLastError(0xdeadbeef);
2414     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2415     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2416      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2417      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2418      GetLastError());
2419     CryptMsgClose(msg);
2420     /* and as the final update in streaming mode.. */
2421     streamInfo.pfnStreamOutput = nop_stream_output;
2422     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2423     SetLastError(0xdeadbeef);
2424     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2425     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2426      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2427      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2428      GetLastError());
2429     CryptMsgClose(msg);
2430     /* and even as a non-final update in streaming mode. */
2431     streamInfo.pfnStreamOutput = nop_stream_output;
2432     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2433     SetLastError(0xdeadbeef);
2434     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2435     todo_wine
2436     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2437      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2438      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2439      GetLastError());
2440     CryptMsgClose(msg);
2441
2442     /* An empty message can be opened with undetermined type.. */
2443     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2444     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2445      TRUE);
2446     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2447     CryptMsgClose(msg);
2448     /* but decoding it as an explicitly typed message fails. */
2449     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2450      NULL);
2451     SetLastError(0xdeadbeef);
2452     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2453      TRUE);
2454     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2455      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2456      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2457      GetLastError());
2458     CryptMsgClose(msg);
2459     /* On the other hand, decoding the bare content of an empty message fails
2460      * with unspecified type..
2461      */
2462     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2463     SetLastError(0xdeadbeef);
2464     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2465      sizeof(dataEmptyBareContent), TRUE);
2466     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2467      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2468      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2469      GetLastError());
2470     CryptMsgClose(msg);
2471     /* but succeeds with explicit type. */
2472     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2473      NULL);
2474     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2475      sizeof(dataEmptyBareContent), TRUE);
2476     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2477     CryptMsgClose(msg);
2478
2479     /* Decoding valid content with an unsupported OID fails */
2480     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2481     SetLastError(0xdeadbeef);
2482     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2483     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2484      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2485     CryptMsgClose(msg);
2486
2487     /* Similarly, opening an empty hash with unspecified type succeeds.. */
2488     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2489     SetLastError(0xdeadbeef);
2490     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2491     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2492      "CryptMsgUpdate failed: %08x\n", GetLastError());
2493     CryptMsgClose(msg);
2494     /* while with specified type it fails. */
2495     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2496      NULL);
2497     SetLastError(0xdeadbeef);
2498     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2499     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2500      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2501      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2502      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2503      GetLastError());
2504     CryptMsgClose(msg);
2505     /* On the other hand, decoding the bare content of an empty hash message
2506      * fails with unspecified type..
2507      */
2508     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2509     SetLastError(0xdeadbeef);
2510     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2511      sizeof(hashEmptyBareContent), TRUE);
2512     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2513      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2514      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2515      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2516      GetLastError());
2517     CryptMsgClose(msg);
2518     /* but succeeds with explicit type. */
2519     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2520      NULL);
2521     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2522      sizeof(hashEmptyBareContent), TRUE);
2523     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2524      "CryptMsgUpdate failed: %x\n", GetLastError());
2525     CryptMsgClose(msg);
2526
2527     /* And again, opening a (non-empty) hash message with unspecified type
2528      * succeeds..
2529      */
2530     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2531     SetLastError(0xdeadbeef);
2532     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2533     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2534     CryptMsgClose(msg);
2535     /* while with specified type it fails.. */
2536     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2537      NULL);
2538     SetLastError(0xdeadbeef);
2539     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2540     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2541      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2542      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2543      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2544      GetLastError());
2545     CryptMsgClose(msg);
2546     /* and decoding the bare content of a non-empty hash message fails with
2547      * unspecified type..
2548      */
2549     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2550     SetLastError(0xdeadbeef);
2551     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2552     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2553      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2554      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2555      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2556      GetLastError());
2557     CryptMsgClose(msg);
2558     /* but succeeds with explicit type. */
2559     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2560      NULL);
2561     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2562     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2563     CryptMsgClose(msg);
2564
2565     /* Opening a (non-empty) hash message with unspecified type and a bogus
2566      * hash value succeeds..
2567      */
2568     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2569     SetLastError(0xdeadbeef);
2570     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2571     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2572     CryptMsgClose(msg);
2573
2574     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2575     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2576     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2577     CryptMsgClose(msg);
2578     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2579     SetLastError(0xdeadbeef);
2580     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2581      sizeof(signedWithCertAndCrlBareContent), TRUE);
2582     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2583      GetLastError() == OSS_DATA_ERROR /* Win9x */),
2584      "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2585      GetLastError());
2586     CryptMsgClose(msg);
2587     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2588      NULL);
2589     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2590      sizeof(signedWithCertAndCrlBareContent), TRUE);
2591     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2592     CryptMsgClose(msg);
2593
2594     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2595      NULL, NULL);
2596     /* The first update succeeds.. */
2597     ret = CryptMsgUpdate(msg, detachedSignedContent,
2598      sizeof(detachedSignedContent), TRUE);
2599     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2600     /* as does a second (probably to update the detached portion).. */
2601     ret = CryptMsgUpdate(msg, detachedSignedContent,
2602      sizeof(detachedSignedContent), TRUE);
2603     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2604     /* while a third fails. */
2605     ret = CryptMsgUpdate(msg, detachedSignedContent,
2606      sizeof(detachedSignedContent), TRUE);
2607     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2608      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2609     CryptMsgClose(msg);
2610
2611     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2612     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2613     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2614     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2615     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2616     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2617     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2618     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2619     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2620
2621     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2622     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2623      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2624     CryptMsgClose(msg);
2625
2626     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2627      NULL);
2628     SetLastError(0xdeadbeef);
2629     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2630      sizeof(envelopedEmptyBareContent), TRUE);
2631     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2632     CryptMsgClose(msg);
2633
2634     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2635      NULL);
2636     SetLastError(0xdeadbeef);
2637     ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2638      sizeof(envelopedEmptyContent), TRUE);
2639     todo_wine
2640     ok(!ret &&
2641      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2642       GetLastError() == OSS_DATA_ERROR), /* Win9x */
2643      "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2644     CryptMsgClose(msg);
2645
2646     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2647     SetLastError(0xdeadbeef);
2648     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2649      sizeof(envelopedEmptyBareContent), TRUE);
2650     ok(!ret &&
2651      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2652       GetLastError() == OSS_DATA_ERROR), /* Win9x */
2653      "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2654     CryptMsgClose(msg);
2655
2656     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2657     SetLastError(0xdeadbeef);
2658     ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2659      sizeof(envelopedEmptyContent), TRUE);
2660     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2661     CryptMsgClose(msg);
2662
2663     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2664      NULL);
2665     SetLastError(0xdeadbeef);
2666     ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2667      sizeof(envelopedBareContentWithoutData), TRUE);
2668     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2669     CryptMsgClose(msg);
2670 }
2671
2672 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2673  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2674
2675 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2676  const CMSG_SIGNER_INFO *expected)
2677 {
2678     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2679      expected->dwVersion, got->dwVersion);
2680     ok(got->Issuer.cbData == expected->Issuer.cbData,
2681      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2682      got->Issuer.cbData);
2683     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2684      "Unexpected issuer\n");
2685     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2686      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2687      got->SerialNumber.cbData);
2688     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2689      got->SerialNumber.cbData), "Unexpected serial number\n");
2690     /* FIXME: check more things */
2691 }
2692
2693 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2694  const CMSG_CMS_SIGNER_INFO *expected)
2695 {
2696     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2697      expected->dwVersion, got->dwVersion);
2698     ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2699      "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2700      got->SignerId.dwIdChoice);
2701     if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2702     {
2703         if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2704         {
2705             ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2706              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2707              "Expected issuer size %d, got %d\n",
2708              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2709              U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2710             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2711              U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2712              U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2713              "Unexpected issuer\n");
2714             ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2715              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2716              "Expected serial number size %d, got %d\n",
2717              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2718              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2719             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2720              U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2721              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2722              "Unexpected serial number\n");
2723         }
2724         else
2725         {
2726             ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2727              "expected key id size %d, got %d\n",
2728              U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2729             ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2730              U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2731              "unexpected key id\n");
2732         }
2733     }
2734     /* FIXME: check more things */
2735 }
2736
2737 static const BYTE signedWithCertAndCrlComputedHash[] = {
2738 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2739 0x2f };
2740 static BYTE keyIdIssuer[] = {
2741 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2742 0x0a,0x07,0x01,0x04,0x01,0x01 };
2743 static const BYTE publicPrivateKeyPair[] = {
2744 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2745 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2746 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2747 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2748 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2749 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2750 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2751 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2752 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2753 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2754 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2755 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2756 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2757 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2758 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2759 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2760 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2761 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2762 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2763 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2764 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2765 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2766 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2767 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2768 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2769 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2770 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2771 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2772 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2773 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2774 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2775 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2776 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2777 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2778 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2779 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2780 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2781 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2782 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2783 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2784 static const BYTE envelopedMessage[] = {
2785 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2786 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2787 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2788 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2789 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2790 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2791 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2792 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2793 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2794 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2795 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2796 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2797 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2798 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2799 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2800 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2801 0x04,0x5f,0x80,0xf2,0x17 };
2802 static const BYTE envelopedBareMessage[] = {
2803 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2804 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2805 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2806 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2807 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2808 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2809 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2810 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2811 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2812 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2813 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2814 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2815 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2816 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2817 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2818 0x2d,0xa3,0x6e };
2819 static const BYTE envelopedMessageWith3Recps[] = {
2820 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2821 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2822 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2823 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2824 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2825 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2826 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2827 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2828 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2829 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2830 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2831 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2832 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2833 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2834 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2835 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2836 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2837 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2838 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2839 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2840 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2841 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2842 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2843 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2844 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2845 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2846 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2847 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2848 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2849 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2850 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2851 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2852 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2853 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2854 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2855 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2856 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2857 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2858 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2859 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2860 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2861 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2862 static const BYTE serialNumber[] = {
2863 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2864 0x1c };
2865 static const BYTE issuer[] = {
2866 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2867
2868 static void test_decode_msg_get_param(void)
2869 {
2870     HCRYPTMSG msg;
2871     HCRYPTPROV hCryptProv;
2872     HCRYPTKEY key = 0;
2873     BOOL ret;
2874     DWORD size = 0, value;
2875     LPBYTE buf;
2876     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2877
2878     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2879     SetLastError(0xdeadbeef);
2880     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2881     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2882      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2883     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2884     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2885      sizeof(msgData));
2886     CryptMsgClose(msg);
2887
2888     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2889     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2890     if (ret)
2891     {
2892         /* Crashes on some Win9x */
2893         check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2894         check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2895         check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2896          emptyHashParam, sizeof(emptyHashParam));
2897     }
2898     CryptMsgClose(msg);
2899     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2900     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2901     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2902      sizeof(msgData));
2903     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2904      sizeof(hashParam));
2905     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2906      hashParam, sizeof(hashParam));
2907     /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2908      * even though there's only one hash.
2909      */
2910     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2911     ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2912      "CryptMsgGetParam failed: %08x\n", GetLastError());
2913     if (ret)
2914         buf = CryptMemAlloc(size);
2915     else
2916         buf = NULL;
2917     if (buf)
2918     {
2919         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2920         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2921         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2922         CryptMemFree(buf);
2923     }
2924     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2925      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2926     value = CMSG_HASHED_DATA_V0;
2927     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2928      sizeof(value));
2929     CryptMsgClose(msg);
2930
2931     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2932     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2933     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2934     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2935      sizeof(msgData));
2936     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2937      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2938     size = sizeof(value);
2939     value = 2112;
2940     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2941     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2942     ok(value == 1, "Expected 1 signer, got %d\n", value);
2943     size = 0;
2944     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2945     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2946      "CryptMsgGetParam failed: %08x\n", GetLastError());
2947     if (ret)
2948         buf = CryptMemAlloc(size);
2949     else
2950         buf = NULL;
2951     if (buf)
2952     {
2953         CMSG_SIGNER_INFO signer = { 0 };
2954
2955         signer.dwVersion = 1;
2956         signer.Issuer.cbData = sizeof(encodedCommonName);
2957         signer.Issuer.pbData = encodedCommonName;
2958         signer.SerialNumber.cbData = sizeof(serialNum);
2959         signer.SerialNumber.pbData = serialNum;
2960         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2961         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2962         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2963         CryptMemFree(buf);
2964     }
2965     /* Getting the CMS signer info of a PKCS7 message is possible. */
2966     size = 0;
2967     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2968     ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2969      "CryptMsgGetParam failed: %08x\n", GetLastError());
2970     if (ret)
2971         buf = CryptMemAlloc(size);
2972     else
2973         buf = NULL;
2974     if (buf)
2975     {
2976         CMSG_CMS_SIGNER_INFO signer = { 0 };
2977
2978         signer.dwVersion = 1;
2979         signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2980         U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2981          sizeof(encodedCommonName);
2982         U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2983         U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2984          sizeof(serialNum);
2985         U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2986         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2987         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2988         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2989         CryptMemFree(buf);
2990     }
2991     /* index is ignored when getting signer count */
2992     size = sizeof(value);
2993     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2994     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2995     ok(value == 1, "Expected 1 signer, got %d\n", value);
2996     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2997     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2998     ok(value == 0, "Expected 0 certs, got %d\n", value);
2999     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3000     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3001     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
3002     CryptMsgClose(msg);
3003     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3004      NULL);
3005     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
3006      sizeof(signedWithCertAndCrlBareContent), TRUE);
3007     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3008     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
3009     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3010     ok(value == 1, "Expected 1 cert, got %d\n", value);
3011     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3012     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3013     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3014     ok(value == 1, "Expected 1 CRL, got %d\n", value);
3015     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3016     check_param("signed with cert and CRL computed hash", msg,
3017      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
3018      sizeof(signedWithCertAndCrlComputedHash));
3019     CryptMsgClose(msg);
3020
3021     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3022     ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3023      sizeof(signedKeyIdEmptyContent), TRUE);
3024     if (!ret && GetLastError() == OSS_DATA_ERROR)
3025     {
3026         CryptMsgClose(msg);
3027         win_skip("Subsequent tests crash on some Win9x\n");
3028         return;
3029     }
3030     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3031     size = sizeof(value);
3032     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3033     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3034     ok(value == 1, "Expected 1 signer, got %d\n", value);
3035     /* Getting the regular (non-CMS) signer info from a CMS message is also
3036      * possible..
3037      */
3038     size = 0;
3039     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3040     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3041     if (ret)
3042         buf = CryptMemAlloc(size);
3043     else
3044         buf = NULL;
3045     if (buf)
3046     {
3047         CMSG_SIGNER_INFO signer;
3048         BYTE zero = 0;
3049
3050         /* and here's the little oddity:  for a CMS message using the key id
3051          * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3052          * a signer with a zero (not empty) serial number, and whose issuer is
3053          * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3054          * and value of the key id.
3055          */
3056         signer.dwVersion = CMSG_SIGNED_DATA_V3;
3057         signer.Issuer.cbData = sizeof(keyIdIssuer);
3058         signer.Issuer.pbData = keyIdIssuer;
3059         signer.SerialNumber.cbData = 1;
3060         signer.SerialNumber.pbData = &zero;
3061         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3062         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3063         CryptMemFree(buf);
3064     }
3065     size = 0;
3066     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3067     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3068     if (ret)
3069         buf = CryptMemAlloc(size);
3070     else
3071         buf = NULL;
3072     if (buf)
3073     {
3074         CMSG_CMS_SIGNER_INFO signer = { 0 };
3075
3076         signer.dwVersion = CMSG_SIGNED_DATA_V3;
3077         signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3078         U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3079         U(signer.SignerId).KeyId.pbData = serialNum;
3080         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3081         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3082         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3083         CryptMemFree(buf);
3084     }
3085     CryptMsgClose(msg);
3086
3087     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3088      NULL);
3089     CryptMsgUpdate(msg, envelopedEmptyBareContent,
3090      sizeof(envelopedEmptyBareContent), TRUE);
3091     todo_wine
3092     check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3093      0);
3094     CryptMsgClose(msg);
3095
3096     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3097     CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3098      TRUE);
3099     todo_wine
3100     check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3101     CryptMsgClose(msg);
3102
3103     pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3104      CRYPT_VERIFYCONTEXT);
3105     SetLastError(0xdeadbeef);
3106     ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3107      sizeof(publicPrivateKeyPair), 0, 0, &key);
3108     ok(ret ||
3109      broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3110      "CryptImportKey failed: %08x\n", GetLastError());
3111
3112     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3113     CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3114     todo_wine
3115     check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3116      envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3117     if (key)
3118     {
3119         decryptPara.hCryptProv = hCryptProv;
3120         SetLastError(0xdeadbeef);
3121         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3122         todo_wine
3123         ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3124         decryptPara.hCryptProv = 0;
3125         SetLastError(0xdeadbeef);
3126         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3127         todo_wine
3128         ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3129          "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3130         todo_wine
3131         check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3132          sizeof(msgData));
3133     }
3134     else
3135         win_skip("failed to import a key, skipping tests\n");
3136     CryptMsgClose(msg);
3137
3138     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3139      NULL);
3140     CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3141      TRUE);
3142     todo_wine
3143     check_param("enveloped bare message before decrypting", msg,
3144      CMSG_CONTENT_PARAM, envelopedBareMessage +
3145      sizeof(envelopedBareMessage) - 4, 4);
3146     if (key)
3147     {
3148         decryptPara.hCryptProv = hCryptProv;
3149         SetLastError(0xdeadbeef);
3150         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3151         todo_wine
3152         ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3153         todo_wine
3154         check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3155          sizeof(msgData));
3156     }
3157     else
3158         win_skip("failed to import a key, skipping tests\n");
3159     CryptMsgClose(msg);
3160
3161     if (key)
3162         CryptDestroyKey(key);
3163     CryptReleaseContext(hCryptProv, 0);
3164
3165     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3166     CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3167      sizeof(envelopedMessageWith3Recps), TRUE);
3168     value = 3;
3169     todo_wine
3170     check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3171      (const BYTE *)&value, sizeof(value));
3172     size = 0;
3173     SetLastError(0xdeadbeef);
3174     ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3175     todo_wine
3176     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3177      "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3178     size = 0;
3179     SetLastError(0xdeadbeef);
3180     ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3181     todo_wine
3182     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3183     todo_wine
3184     ok(size >= 142, "unexpected size: %u\n", size);
3185     if (ret)
3186         buf = CryptMemAlloc(size);
3187     else
3188         buf = NULL;
3189     if (buf)
3190     {
3191         CERT_INFO *certInfo = (CERT_INFO *)buf;
3192
3193         SetLastError(0xdeadbeef);
3194         ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3195         todo_wine
3196         ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3197         todo_wine
3198         ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3199          "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3200         todo_wine
3201         ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3202          sizeof(serialNumber)), "unexpected serial number\n");
3203         todo_wine
3204         ok(certInfo->Issuer.cbData == sizeof(issuer),
3205          "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3206         todo_wine
3207         ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3208          "unexpected issuer\n");
3209         CryptMemFree(buf);
3210     }
3211     CryptMsgClose(msg);
3212 }
3213
3214 static void test_decode_msg(void)
3215 {
3216     test_decode_msg_update();
3217     test_decode_msg_get_param();
3218 }
3219
3220 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3221 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3222 static BYTE encodedPubKey[] = {
3223 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3224 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3225 0x0d,0x0e,0x0f };
3226 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3227 static BYTE mod_encoded[] = {
3228  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3229  0x01,0x00,0x01 };
3230
3231 static void test_msg_control(void)
3232 {
3233     static char oid_rsa_rsa[] = szOID_RSA_RSA;
3234     BOOL ret;
3235     HCRYPTMSG msg;
3236     DWORD i;
3237     CERT_INFO certInfo = { 0 };
3238     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3239     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3240     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3241
3242     /* Crashes
3243     ret = CryptMsgControl(NULL, 0, 0, NULL);
3244     */
3245
3246     /* Data encode messages don't allow any sort of control.. */
3247     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3248      NULL);
3249     /* either with no prior update.. */
3250     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3251     {
3252         SetLastError(0xdeadbeef);
3253         ret = CryptMsgControl(msg, 0, i, NULL);
3254         ok(!ret && GetLastError() == E_INVALIDARG,
3255          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3256     }
3257     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3258     /* or after an update. */
3259     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3260     {
3261         SetLastError(0xdeadbeef);
3262         ret = CryptMsgControl(msg, 0, i, NULL);
3263         ok(!ret && GetLastError() == E_INVALIDARG,
3264          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3265     }
3266     CryptMsgClose(msg);
3267
3268     /* Hash encode messages don't allow any sort of control.. */
3269     hashInfo.cbSize = sizeof(hashInfo);
3270     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3271     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3272      NULL, NULL);
3273     /* either with no prior update.. */
3274     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3275     {
3276         SetLastError(0xdeadbeef);
3277         ret = CryptMsgControl(msg, 0, i, NULL);
3278         ok(!ret && GetLastError() == E_INVALIDARG,
3279          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3280     }
3281     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3282     /* or after an update. */
3283     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3284     {
3285         SetLastError(0xdeadbeef);
3286         ret = CryptMsgControl(msg, 0, i, NULL);
3287         ok(!ret && GetLastError() == E_INVALIDARG,
3288          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3289     }
3290     CryptMsgClose(msg);
3291
3292     /* Signed encode messages likewise don't allow any sort of control.. */
3293     signInfo.cbSize = sizeof(signInfo);
3294     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3295      NULL, NULL);
3296     /* either before an update.. */
3297     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3298     {
3299         SetLastError(0xdeadbeef);
3300         ret = CryptMsgControl(msg, 0, i, NULL);
3301         ok(!ret && GetLastError() == E_INVALIDARG,
3302          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3303     }
3304     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3305     /* or after an update. */
3306     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3307     {
3308         SetLastError(0xdeadbeef);
3309         ret = CryptMsgControl(msg, 0, i, NULL);
3310         ok(!ret && GetLastError() == E_INVALIDARG,
3311          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3312     }
3313     CryptMsgClose(msg);
3314
3315     /* Decode messages behave a bit differently. */
3316     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3317     /* Bad control type */
3318     SetLastError(0xdeadbeef);
3319     ret = CryptMsgControl(msg, 0, 0, NULL);
3320     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3321      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3322     SetLastError(0xdeadbeef);
3323     ret = CryptMsgControl(msg, 1, 0, NULL);
3324     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3325      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3326     /* Can't verify the hash of an indeterminate-type message */
3327     SetLastError(0xdeadbeef);
3328     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3329     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3330      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3331     /* Crashes
3332     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3333      */
3334     /* Can't decrypt an indeterminate-type message */
3335     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3336     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3337      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3338     CryptMsgClose(msg);
3339
3340     if (!old_crypt32)
3341     {
3342         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3343          NULL);
3344         /* Can't verify the hash of an empty message */
3345         SetLastError(0xdeadbeef);
3346         /* Crashes on some Win9x */
3347         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3348         todo_wine
3349         ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3350          "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3351         /* Crashes
3352         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3353          */
3354         /* Can't verify the signature of a hash message */
3355         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3356         ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3357          "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3358         CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3359          TRUE);
3360         /* Oddly enough, this fails, crashes on some Win9x */
3361         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3362         ok(!ret, "Expected failure\n");
3363         CryptMsgClose(msg);
3364     }
3365     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3366      NULL);
3367     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3368     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3369     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3370     /* Can't decrypt an indeterminate-type message */
3371     SetLastError(0xdeadbeef);
3372     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3373     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3374      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3375     CryptMsgClose(msg);
3376
3377     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3378      NULL, NULL);
3379     /* Can't verify the hash of a detached message before it's been updated. */
3380     SetLastError(0xdeadbeef);
3381     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3382     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3383      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3384     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3385      TRUE);
3386     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3387     /* Still can't verify the hash of a detached message with the content
3388      * of the detached hash given..
3389      */
3390     SetLastError(0xdeadbeef);
3391     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3392     ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3393      "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3394     /* and giving the content of the message after attempting to verify the
3395      * hash fails.
3396      */
3397     SetLastError(0xdeadbeef);
3398     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3399     todo_wine
3400     ok(!ret &&
3401        (GetLastError() == NTE_BAD_HASH_STATE ||
3402         GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
3403         GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3404      "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3405      "got %08x\n", GetLastError());
3406     CryptMsgClose(msg);
3407
3408     /* Finally, verifying the hash of a detached message in the correct order:
3409      * 1. Update with the detached hash message
3410      * 2. Update with the content of the message
3411      * 3. Verifying the hash of the message
3412      * succeeds.
3413      */
3414     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3415      NULL, NULL);
3416     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3417      TRUE);
3418     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3419     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3420     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3421     SetLastError(0xdeadbeef);
3422     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3423     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3424     CryptMsgClose(msg);
3425
3426     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3427      NULL);
3428     /* Can't verify the hash of a signed message */
3429     SetLastError(0xdeadbeef);
3430     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3431     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3432      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3433     /* Can't decrypt a signed message */
3434     SetLastError(0xdeadbeef);
3435     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3436     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3437      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3438     /* Crash
3439     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3440     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3441      */
3442     CryptMsgUpdate(msg, signedWithCertBareContent,
3443      sizeof(signedWithCertBareContent), TRUE);
3444     /* With an empty cert info, the signer can't be found in the message (and
3445      * the signature can't be verified.
3446      */
3447     SetLastError(0xdeadbeef);
3448     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3449     ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3450      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3451      "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3452      GetLastError());
3453     /* The cert info is expected to have an issuer, serial number, and public
3454      * key info set.
3455      */
3456     certInfo.SerialNumber.cbData = sizeof(serialNum);
3457     certInfo.SerialNumber.pbData = serialNum;
3458     certInfo.Issuer.cbData = sizeof(encodedCommonName);
3459     certInfo.Issuer.pbData = encodedCommonName;
3460     SetLastError(0xdeadbeef);
3461     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3462     ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3463      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3464      "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3465     CryptMsgClose(msg);
3466     /* This cert has a public key, but it's not in a usable form */
3467     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3468      NULL);
3469     ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3470      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3471     if (ret)
3472     {
3473         /* Crashes on some Win9x */
3474         /* Again, cert info needs to have a public key set */
3475         SetLastError(0xdeadbeef);
3476         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3477         ok(!ret &&
3478          (GetLastError() == CRYPT_E_ASN1_EOD ||
3479           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3480          "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3481         /* The public key is supposed to be in encoded form.. */
3482         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3483         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3484         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3485         SetLastError(0xdeadbeef);
3486         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3487         ok(!ret &&
3488          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3489           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3490          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3491         /* but not as a X509_PUBLIC_KEY_INFO.. */
3492         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3493         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3494         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3495         SetLastError(0xdeadbeef);
3496         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3497         ok(!ret &&
3498          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3499           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3500          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3501         /* This decodes successfully, but it doesn't match any key in the message */
3502         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3503         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3504         SetLastError(0xdeadbeef);
3505         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3506         /* In Wine's rsaenh, this fails to decode because the key length is too
3507          * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
3508          * now.
3509          */
3510         todo_wine
3511         ok(!ret &&
3512          (GetLastError() == NTE_BAD_SIGNATURE ||
3513           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3514          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3515     }
3516     CryptMsgClose(msg);
3517     /* A message with no data doesn't have a valid signature */
3518     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3519     ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3520      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3521     if (ret)
3522     {
3523         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3524         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3525         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3526         SetLastError(0xdeadbeef);
3527         /* Crashes on some Win9x */
3528         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3529         ok(!ret &&
3530          (GetLastError() == NTE_BAD_SIGNATURE ||
3531           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3532          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3533     }
3534     CryptMsgClose(msg);
3535     /* Finally, this succeeds */
3536     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3537     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3538      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3539     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3540     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3541      "CryptMsgControl failed: %08x\n", GetLastError());
3542     CryptMsgClose(msg);
3543
3544     /* Test verifying signature of a detached signed message */
3545     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3546      NULL, NULL);
3547     ret = CryptMsgUpdate(msg, detachedSignedContent,
3548      sizeof(detachedSignedContent), TRUE);
3549     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3550     /* Can't verify the sig without having updated the data */
3551     SetLastError(0xdeadbeef);
3552     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3553     ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3554      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3555      "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3556      GetLastError());
3557     /* Now that the signature's been checked, can't do the final update */
3558     SetLastError(0xdeadbeef);
3559     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3560     todo_wine
3561     ok((!ret &&
3562      (GetLastError() == NTE_BAD_HASH_STATE ||
3563       GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
3564       GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3565       broken(ret), /* Win9x */
3566      "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3567      "got %08x\n", GetLastError());
3568     CryptMsgClose(msg);
3569     /* Updating with the detached portion of the message and the data of the
3570      * the message allows the sig to be verified.
3571      */
3572     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3573      NULL, NULL);
3574     ret = CryptMsgUpdate(msg, detachedSignedContent,
3575      sizeof(detachedSignedContent), TRUE);
3576     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3577     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3578     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3579     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3580     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3581      "CryptMsgControl failed: %08x\n", GetLastError());
3582     CryptMsgClose(msg);
3583
3584     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3585      NULL);
3586     decryptPara.cbSize = 0;
3587     SetLastError(0xdeadbeef);
3588     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3589     todo_wine
3590     ok(!ret && GetLastError() == E_INVALIDARG,
3591      "expected E_INVALIDARG, got %08x\n", GetLastError());
3592     decryptPara.cbSize = sizeof(decryptPara);
3593     if (!old_crypt32)
3594     {
3595         SetLastError(0xdeadbeef);
3596         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3597         ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3598          "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3599     }
3600     SetLastError(0xdeadbeef);
3601     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3602      sizeof(envelopedEmptyBareContent), TRUE);
3603     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3604     SetLastError(0xdeadbeef);
3605     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3606     todo_wine
3607     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3608      "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3609     CryptMsgClose(msg);
3610
3611     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3612      NULL);
3613     SetLastError(0xdeadbeef);
3614     ret = CryptMsgUpdate(msg, envelopedBareMessage,
3615      sizeof(envelopedBareMessage), TRUE);
3616     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3617     SetLastError(0xdeadbeef);
3618     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3619     todo_wine
3620     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3621      "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3622     CryptMsgClose(msg);
3623 }
3624
3625 /* win9x has much less parameter checks and will crash on many tests
3626  * this code is from test_signed_msg_update()
3627  */
3628 static BOOL detect_nt(void)
3629 {
3630     BOOL ret;
3631     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3632     CERT_INFO certInfo = { 0 };
3633
3634     if (!pCryptAcquireContextW)
3635         return FALSE;
3636
3637     certInfo.SerialNumber.cbData = sizeof(serialNum);
3638     certInfo.SerialNumber.pbData = serialNum;
3639     certInfo.Issuer.cbData = sizeof(encodedCommonName);
3640     certInfo.Issuer.pbData = encodedCommonName;
3641     signer.pCertInfo = &certInfo;
3642     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3643
3644     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3645                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3646     if (!ret && GetLastError() == NTE_EXISTS) {
3647         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3648                                     PROV_RSA_FULL, 0);
3649     }
3650
3651     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3652
3653     /* cleanup */
3654     CryptReleaseContext(signer.hCryptProv, 0);
3655     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3656                           CRYPT_DELETEKEYSET);
3657
3658     return TRUE;
3659 }
3660
3661 static void test_msg_get_and_verify_signer(void)
3662 {
3663     BOOL ret;
3664     HCRYPTMSG msg;
3665     PCCERT_CONTEXT signer;
3666     DWORD signerIndex;
3667     HCERTSTORE store;
3668
3669     /* Crash */
3670     if (0)
3671     {
3672         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3673         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3674     }
3675
3676     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3677     /* An empty message has no signer */
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     /* The signer is cleared on error */
3683     signer = (PCCERT_CONTEXT)0xdeadbeef;
3684     SetLastError(0xdeadbeef);
3685     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3686     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3687      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3688     ok(!signer, "expected signer to be NULL\n");
3689     /* The signer index is also cleared on error */
3690     signerIndex = 0xdeadbeef;
3691     SetLastError(0xdeadbeef);
3692     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3693     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3694      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3695     ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3696     /* An unsigned message (msgData isn't a signed message at all)
3697      * likewise has no signer.
3698      */
3699     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3700     SetLastError(0xdeadbeef);
3701     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3702     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3703      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3704     CryptMsgClose(msg);
3705
3706     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3707     /* A "signed" message created with no signer cert likewise has no signer */
3708     ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3709     if (ret)
3710     {
3711         /* Crashes on most Win9x */
3712         ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3713         ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3714          "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3715     }
3716     CryptMsgClose(msg);
3717
3718     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3719     /* A signed message succeeds, .. */
3720     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3721      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3722     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3723     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3724      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3725     /* the signer index can be retrieved, .. */
3726     signerIndex = 0xdeadbeef;
3727     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3728     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3729      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3730     if (ret)
3731         ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3732     /* as can the signer cert. */
3733     signer = (PCCERT_CONTEXT)0xdeadbeef;
3734     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3735     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3736      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3737     if (ret)
3738         ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3739      "expected a valid signer\n");
3740     if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3741         CertFreeCertificateContext(signer);
3742     /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3743      */
3744     signerIndex = 0xdeadbeef;
3745     SetLastError(0xdeadbeef);
3746     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3747      NULL, &signerIndex);
3748     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3749      "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3750     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3751      * message signer not to be found.
3752      */
3753     SetLastError(0xdeadbeef);
3754     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3755      NULL, NULL);
3756     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3757      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3758      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3759     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3760      * the message signer not to be found.
3761      */
3762     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3763      CERT_STORE_CREATE_NEW_FLAG, NULL);
3764     SetLastError(0xdeadbeef);
3765     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3766      NULL, NULL);
3767     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3768      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3769      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3770     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3771      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3772      CERT_STORE_ADD_ALWAYS, NULL);
3773     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3774      "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3775     /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3776      * the signer succeeds.
3777      */
3778     SetLastError(0xdeadbeef);
3779     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3780      NULL, NULL);
3781     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3782      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3783     CertCloseStore(store, 0);
3784     CryptMsgClose(msg);
3785 }
3786
3787 START_TEST(msg)
3788 {
3789     init_function_pointers();
3790     have_nt = detect_nt();
3791     if (!have_nt)
3792         win_skip("Win9x crashes on some parameter checks\n");
3793
3794     /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3795     if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3796     {
3797         win_skip("Some tests will crash on older crypt32 implementations\n");
3798         old_crypt32 = TRUE;
3799     }
3800
3801     /* Basic parameter checking tests */
3802     test_msg_open_to_encode();
3803     test_msg_open_to_decode();
3804     test_msg_get_param();
3805     test_msg_close();
3806     test_msg_control();
3807
3808     /* Message-type specific tests */
3809     test_data_msg();
3810     test_hash_msg();
3811     test_signed_msg();
3812     test_enveloped_msg();
3813     test_decode_msg();
3814
3815     test_msg_get_and_verify_signer();
3816 }