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