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