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 
170     /* Crash
171     ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
172     ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
173     ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
174      */
175 
176     /* Decoded messages */
177     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
178     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
179     /* For decoded messages, the type is always available */
180     size = 0;
181     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
182     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
183     size = sizeof(value);
184     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
185     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
186     /* For this (empty) message, the type isn't set */
187     ok(value == 0, "Expected type 0, got %d\n", value);
188     CryptMsgClose(msg);
189 
190     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
191      NULL);
192     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
193     /* For explicitly typed messages, the type is known. */
194     size = sizeof(value);
195     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
196     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
197     ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
198     for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
199     {
200         size = 0;
201         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
202         ok(!ret, "Parameter %d: expected failure\n", i);
203     }
204     CryptMsgClose(msg);
205 
206     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
207      NULL);
208     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
209     size = sizeof(value);
210     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
211     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
212     ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
213     for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
214     {
215         size = 0;
216         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
217         ok(!ret, "Parameter %d: expected failure\n", i);
218     }
219     CryptMsgClose(msg);
220 
221     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
222      NULL);
223     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
224     size = sizeof(value);
225     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
226     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
227     ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
228     for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
229     {
230         size = 0;
231         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
232         ok(!ret, "Parameter %d: expected failure\n", i);
233     }
234     CryptMsgClose(msg);
235 
236     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
237      NULL);
238     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
239     size = sizeof(value);
240     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
241     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
242     ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
243     for (i = CMSG_CONTENT_PARAM; !old_crypt32 && (i <= CMSG_CMS_SIGNER_INFO_PARAM); i++)
244     {
245         size = 0;
246         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
247         ok(!ret, "Parameter %d: expected failure\n", i);
248     }
249     CryptMsgClose(msg);
250 
251     /* Explicitly typed messages get their types set, even if they're invalid */
252     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
253      NULL);
254     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
255     size = sizeof(value);
256     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
257     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
258     ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
259     CryptMsgClose(msg);
260 
261     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
262     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
263     size = sizeof(value);
264     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &value, &size);
265     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
266     ok(value == 1000, "Expected 1000, got %d\n", value);
267     CryptMsgClose(msg);
268 }
269 
270 static void test_msg_close(void)
271 {
272     BOOL ret;
273     HCRYPTMSG msg;
274 
275     /* NULL succeeds.. */
276     ret = CryptMsgClose(NULL);
277     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
278     /* but an arbitrary pointer crashes. */
279     if (0)
280         ret = CryptMsgClose((HCRYPTMSG)1);
281     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
282      NULL);
283     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
284     ret = CryptMsgClose(msg);
285     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
286 }
287 
288 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
289  const BYTE *expected, DWORD expectedSize)
290 {
291     DWORD size;
292     LPBYTE buf;
293     BOOL ret;
294 
295     size = 0xdeadbeef;
296     ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
297     ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ ||
298      GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */),
299      "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
300     if (!ret)
301     {
302         win_skip("parameter %d not supported, skipping tests\n", param);
303         return;
304     }
305     buf = HeapAlloc(GetProcessHeap(), 0, size);
306     ret = CryptMsgGetParam(msg, param, 0, buf, &size);
307     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
308     ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
309      expectedSize, size);
310     if (size == expectedSize && size)
311         ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
312     HeapFree(GetProcessHeap(), 0, buf);
313 }
314 
315 static void test_data_msg_open(void)
316 {
317     HCRYPTMSG msg;
318     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
319     CMSG_STREAM_INFO streamInfo = { 0 };
320     char oid[] = "1.2.3";
321 
322     /* The data message type takes no additional info */
323     SetLastError(0xdeadbeef);
324     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
325      NULL, NULL);
326     ok(!msg && GetLastError() == E_INVALIDARG,
327      "Expected E_INVALIDARG, got %x\n", GetLastError());
328     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
329      NULL);
330     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
331     CryptMsgClose(msg);
332 
333     /* An empty stream info is allowed. */
334     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
335      &streamInfo);
336     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
337     CryptMsgClose(msg);
338 
339     /* Passing a bogus inner OID succeeds for a non-streamed message.. */
340     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
341      NULL);
342     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
343     CryptMsgClose(msg);
344     /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
345     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
346      CMSG_DATA, NULL, oid, NULL);
347     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
348     CryptMsgClose(msg);
349     /* and when a stream info is given, even though you're not supposed to be
350      * able to use anything but szOID_RSA_data when streaming is being used.
351      */
352     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
353      CMSG_DATA, NULL, oid, &streamInfo);
354     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
355     CryptMsgClose(msg);
356 }
357 
358 static const BYTE msgData[] = { 1, 2, 3, 4 };
359 
360 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
361  BOOL final)
362 {
363     return TRUE;
364 }
365 
366 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
367 
368 static void test_data_msg_update(void)
369 {
370     HCRYPTMSG msg;
371     BOOL ret;
372     CMSG_STREAM_INFO streamInfo = { 0 };
373 
374     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
375      NULL);
376     /* Can't update a message that wasn't opened detached with final = FALSE */
377     SetLastError(0xdeadbeef);
378     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
379     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
380      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381     /* Updating it with final = TRUE succeeds */
382     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
383     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
384     /* Any subsequent update will fail, as the last was final */
385     SetLastError(0xdeadbeef);
386     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
387     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
388      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
389     CryptMsgClose(msg);
390 
391     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
392      NULL);
393     /* Starting with Vista, can update a message with no data. */
394     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
395     ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError());
396     if (ret)
397     {
398         DWORD size;
399 
400         ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
401         ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
402         if (ret)
403         {
404             LPBYTE buf = CryptMemAlloc(size);
405 
406             if (buf)
407             {
408                 ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, buf,
409                  &size);
410                 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
411                 if (ret)
412                 {
413                     ok(size == sizeof(dataEmptyBareContent),
414                      "unexpected size %d\n", size);
415                     ok(!memcmp(buf, dataEmptyBareContent, size),
416                      "unexpected value\n");
417                 }
418                 CryptMemFree(buf);
419             }
420         }
421     }
422     CryptMsgClose(msg);
423 
424     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
425      CMSG_DATA, NULL, NULL, NULL);
426     if (have_nt)
427     {
428         /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
429          * On Win9x, this sometimes succeeds, sometimes fails with
430          * GetLastError() == 0, so it's not worth checking there.
431          */
432         SetLastError(0xdeadbeef);
433         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
434         ok(!ret &&
435          (GetLastError() == E_INVALIDARG ||
436           broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
437          "Expected E_INVALIDARG, got %x\n", GetLastError());
438         SetLastError(0xdeadbeef);
439         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
440         ok(!ret &&
441          (GetLastError() == E_INVALIDARG ||
442           broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
443          "Expected E_INVALIDARG, got %x\n", GetLastError());
444     }
445     else
446         skip("not updating CMSG_DATA with a non-final update\n");
447     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
448     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
449     CryptMsgClose(msg);
450 
451     if (!old_crypt32)
452     {
453         /* Calling update after opening with an empty stream info (with a bogus
454          * output function) yields an error:
455          */
456         /* Crashes on some Win9x */
457         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
458          &streamInfo);
459         SetLastError(0xdeadbeef);
460         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
461         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
462          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
463          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
464          GetLastError());
465         CryptMsgClose(msg);
466     }
467     /* Calling update with a valid output function succeeds, even if the data
468      * exceeds the size specified in the stream info.
469      */
470     streamInfo.pfnStreamOutput = nop_stream_output;
471     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
472      &streamInfo);
473     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
474     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
475     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
476     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
477     CryptMsgClose(msg);
478 }
479 
480 static void test_data_msg_get_param(void)
481 {
482     HCRYPTMSG msg;
483     DWORD size;
484     BOOL ret;
485     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
486 
487     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
488      NULL);
489 
490     /* Content and bare content are always gettable when not streaming */
491     size = 0;
492     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
493     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
494     size = 0;
495     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
496     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
497     /* But for this type of message, the signer and hash aren't applicable,
498      * and the type isn't available.
499      */
500     size = 0;
501     SetLastError(0xdeadbeef);
502     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
503     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
504      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
505     SetLastError(0xdeadbeef);
506     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
507     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
508      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
509     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
510     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
511      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
512     CryptMsgClose(msg);
513 
514     /* Can't get content or bare content when streaming */
515     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
516      NULL, &streamInfo);
517     SetLastError(0xdeadbeef);
518     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
519     ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
520      "Expected E_INVALIDARG, got %x\n", GetLastError());
521     SetLastError(0xdeadbeef);
522     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
523     ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
524      "Expected E_INVALIDARG, got %x\n", GetLastError());
525     CryptMsgClose(msg);
526 }
527 
528 static const BYTE dataEmptyContent[] = {
529 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
530 0x04,0x00 };
531 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
532 static const BYTE dataContent[] = {
533 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
534 0x04,0x04,0x01,0x02,0x03,0x04 };
535 
536 struct update_accum
537 {
538     DWORD cUpdates;
539     CRYPT_DATA_BLOB *updates;
540 };
541 
542 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
543  DWORD cb, BOOL final)
544 {
545     struct update_accum *accum = (struct update_accum *)pvArg;
546     BOOL ret = FALSE;
547 
548     if (accum->cUpdates)
549         accum->updates = CryptMemRealloc(accum->updates,
550          (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
551     else
552         accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
553     if (accum->updates)
554     {
555         CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
556 
557         blob->pbData = CryptMemAlloc(cb);
558         if (blob->pbData)
559         {
560             memcpy(blob->pbData, pb, cb);
561             blob->cbData = cb;
562             ret = TRUE;
563         }
564         accum->cUpdates++;
565     }
566     return ret;
567 }
568 
569 /* The updates of a (bogus) definite-length encoded message */
570 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
571  0x07,0x01,0xa0,0x02,0x04,0x00 };
572 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
573 static CRYPT_DATA_BLOB b1[] = {
574     { sizeof(u1), u1 },
575     { sizeof(u2), u2 },
576     { sizeof(u2), u2 },
577 };
578 static const struct update_accum a1 = { ARRAY_SIZE(b1), b1 };
579 /* The updates of a definite-length encoded message */
580 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
581  0x07,0x01,0xa0,0x06,0x04,0x04 };
582 static CRYPT_DATA_BLOB b2[] = {
583     { sizeof(u3), u3 },
584     { sizeof(u2), u2 },
585 };
586 static const struct update_accum a2 = { ARRAY_SIZE(b2), b2 };
587 /* The updates of an indefinite-length encoded message */
588 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
589  0x07,0x01,0xa0,0x80,0x24,0x80 };
590 static BYTE u5[] = { 0x04,0x04 };
591 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
592 static CRYPT_DATA_BLOB b3[] = {
593     { sizeof(u4), u4 },
594     { sizeof(u5), u5 },
595     { sizeof(u2), u2 },
596     { sizeof(u5), u5 },
597     { sizeof(u2), u2 },
598     { sizeof(u6), u6 },
599 };
600 static const struct update_accum a3 = { ARRAY_SIZE(b3), b3 };
601 
602 static void check_updates(LPCSTR header, const struct update_accum *expected,
603  const struct update_accum *got)
604 {
605     DWORD i;
606 
607     ok(expected->cUpdates == got->cUpdates,
608      "%s: expected %d updates, got %d\n", header, expected->cUpdates,
609      got->cUpdates);
610     if (expected->cUpdates == got->cUpdates)
611         for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
612         {
613             ok(expected->updates[i].cbData == got->updates[i].cbData,
614              "%s, update %d: expected %d bytes, got %d\n", header, i,
615              expected->updates[i].cbData, got->updates[i].cbData);
616             if (expected->updates[i].cbData && expected->updates[i].cbData ==
617              got->updates[i].cbData)
618                 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
619                  got->updates[i].cbData), "%s, update %d: unexpected value\n",
620                  header, i);
621         }
622 }
623 
624 /* Frees the updates stored in accum */
625 static void free_updates(struct update_accum *accum)
626 {
627     DWORD i;
628 
629     for (i = 0; i < accum->cUpdates; i++)
630         CryptMemFree(accum->updates[i].pbData);
631     CryptMemFree(accum->updates);
632     accum->updates = NULL;
633     accum->cUpdates = 0;
634 }
635 
636 static void test_data_msg_encoding(void)
637 {
638     HCRYPTMSG msg;
639     BOOL ret;
640     static char oid[] = "1.2.3";
641     struct update_accum accum = { 0, NULL };
642     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
643 
644     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
645      NULL);
646     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
647      dataEmptyBareContent, sizeof(dataEmptyBareContent));
648     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
649      sizeof(dataEmptyContent));
650     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
651     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
652     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
653      dataBareContent, sizeof(dataBareContent));
654     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
655      sizeof(dataContent));
656     CryptMsgClose(msg);
657     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
658     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
659      CMSG_DATA, NULL, NULL, NULL);
660     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
661      dataEmptyBareContent, sizeof(dataEmptyBareContent));
662     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
663      sizeof(dataEmptyContent));
664     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
665     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
666     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
667      dataBareContent, sizeof(dataBareContent));
668     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
669      sizeof(dataContent));
670     CryptMsgClose(msg);
671     /* The inner OID is apparently ignored */
672     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
673      NULL);
674     check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
675      dataEmptyBareContent, sizeof(dataEmptyBareContent));
676     check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
677      dataEmptyContent, sizeof(dataEmptyContent));
678     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
679     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
680     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
681      dataBareContent, sizeof(dataBareContent));
682     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
683      sizeof(dataContent));
684     CryptMsgClose(msg);
685     /* A streaming message is DER encoded if the length is not 0xffffffff, but
686      * curiously, updates aren't validated to make sure they don't exceed the
687      * stated length.  (The resulting output will of course fail to decode.)
688      */
689     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
690      NULL, &streamInfo);
691     CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
692     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
693     CryptMsgClose(msg);
694     check_updates("bogus data message with definite length", &a1, &accum);
695     free_updates(&accum);
696     /* A valid definite-length encoding: */
697     streamInfo.cbContent = sizeof(msgData);
698     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
699      NULL, &streamInfo);
700     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
701     CryptMsgClose(msg);
702     check_updates("data message with definite length", &a2, &accum);
703     free_updates(&accum);
704     /* An indefinite-length encoding: */
705     streamInfo.cbContent = 0xffffffff;
706     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
707      NULL, &streamInfo);
708     CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
709     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
710     CryptMsgClose(msg);
711     check_updates("data message with indefinite length", &a3, &accum);
712     free_updates(&accum);
713 }
714 
715 static void test_data_msg(void)
716 {
717     test_data_msg_open();
718     test_data_msg_update();
719     test_data_msg_get_param();
720     test_data_msg_encoding();
721 }
722 
723 static void test_hash_msg_open(void)
724 {
725     HCRYPTMSG msg;
726     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
727     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
728 
729     SetLastError(0xdeadbeef);
730     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
731      NULL, NULL);
732     ok(!msg && GetLastError() == E_INVALIDARG,
733      "Expected E_INVALIDARG, got %x\n", GetLastError());
734     hashInfo.cbSize = sizeof(hashInfo);
735     SetLastError(0xdeadbeef);
736     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
737      NULL, NULL);
738     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
739      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
740     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
741     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
742      NULL, NULL);
743     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
744     CryptMsgClose(msg);
745     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
746      CMSG_HASHED, &hashInfo, NULL, NULL);
747     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
748     CryptMsgClose(msg);
749     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
750      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
751     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
752     CryptMsgClose(msg);
753 }
754 
755 static void test_hash_msg_update(void)
756 {
757     HCRYPTMSG msg;
758     BOOL ret;
759     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
760      { oid_rsa_md5, { 0, NULL } }, NULL };
761     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
762 
763     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
764      CMSG_HASHED, &hashInfo, NULL, NULL);
765     /* Detached hashed messages opened in non-streaming mode allow non-final
766      * updates..
767      */
768     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
769     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
770     /* including non-final updates with no data.. */
771     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
772     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
773     /* and final updates with no data. */
774     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
775     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
776     /* But no updates are allowed after the final update. */
777     SetLastError(0xdeadbeef);
778     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
779     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
780      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
781     SetLastError(0xdeadbeef);
782     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
783     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
784      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
785     CryptMsgClose(msg);
786     /* Non-detached messages, in contrast, don't allow non-final updates in
787      * non-streaming mode.
788      */
789     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
790      NULL, NULL);
791     SetLastError(0xdeadbeef);
792     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
793     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
794      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
795     /* Final updates (including empty ones) are allowed. */
796     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
797     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
798     CryptMsgClose(msg);
799     /* And, of course, streaming mode allows non-final updates */
800     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
801      NULL, &streamInfo);
802     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
803     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
804     CryptMsgClose(msg);
805     /* Setting pfnStreamOutput to NULL results in no error.  (In what appears
806      * to be a bug, it isn't actually used - see encoding tests.)
807      */
808     streamInfo.pfnStreamOutput = NULL;
809     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
810      NULL, &streamInfo);
811     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
812     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
813     CryptMsgClose(msg);
814 }
815 
816 static const BYTE emptyHashParam[] = {
817 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
818 0x7e };
819 
820 static void test_hash_msg_get_param(void)
821 {
822     HCRYPTMSG msg;
823     BOOL ret;
824     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
825      { oid_rsa_md5, { 0, NULL } }, NULL };
826     DWORD size, value;
827     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
828     BYTE buf[16];
829 
830     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
831      NULL, NULL);
832     /* Content and bare content are always gettable for non-streamed messages */
833     size = 0;
834     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
835     ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
836      "CryptMsgGetParam failed: %08x\n", GetLastError());
837     size = 0;
838     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
839     ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
840      "CryptMsgGetParam failed: %08x\n", GetLastError());
841     /* For an encoded hash message, the hash data aren't available */
842     SetLastError(0xdeadbeef);
843     ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
844     ok(!ret && (GetLastError() == CRYPT_E_INVALID_MSG_TYPE ||
845      GetLastError() == OSS_LIMITED /* Win9x */),
846      "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
847      GetLastError());
848     /* The hash is also available. */
849     size = 0;
850     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
851     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
852     ok(size == sizeof(buf), "Unexpected size %d\n", size);
853     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
854     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
855     ok(size == sizeof(buf), "Unexpected size %d\n", 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     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1840     check_param("signedWithCertWithValidPubKeyContent", msg,
1841      CMSG_CONTENT_PARAM, signedWithCertWithValidPubKeyContent,
1842      sizeof(signedWithCertWithValidPubKeyContent));
1843     CryptMsgClose(msg);
1844 
1845     CryptDestroyKey(key);
1846     CryptReleaseContext(signer.hCryptProv, 0);
1847     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1848      CRYPT_DELETEKEYSET);
1849 }
1850 
1851 static void test_signed_msg_get_param(void)
1852 {
1853     BOOL ret;
1854     HCRYPTMSG msg;
1855     DWORD size, value = 0;
1856     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1857     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1858     CERT_INFO certInfo = { 0 };
1859 
1860     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1861      NULL, NULL);
1862     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1863 
1864     /* Content and bare content are always gettable */
1865     size = 0;
1866     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1867     ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1868      GetLastError());
1869     if (!ret)
1870     {
1871         skip("message parameters are broken, skipping tests\n");
1872         return;
1873     }
1874     size = 0;
1875     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1876     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1877     /* For "signed" messages, so is the version. */
1878     size = 0;
1879     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1880     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1881     size = sizeof(value);
1882     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1883     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1884     ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1885     /* But for this message, with no signers, the hash and signer aren't
1886      * available.
1887      */
1888     size = 0;
1889     SetLastError(0xdeadbeef);
1890     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1891     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1892      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1893     SetLastError(0xdeadbeef);
1894     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1895     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1896      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1897     /* As usual, the type isn't available. */
1898     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1899     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1900      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1901 
1902     CryptMsgClose(msg);
1903 
1904     certInfo.SerialNumber.cbData = sizeof(serialNum);
1905     certInfo.SerialNumber.pbData = serialNum;
1906     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1907     certInfo.Issuer.pbData = encodedCommonName;
1908     signer.pCertInfo = &certInfo;
1909     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1910     signInfo.cSigners = 1;
1911     signInfo.rgSigners = &signer;
1912 
1913     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1914                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
1915     if (!ret && GetLastError() == NTE_EXISTS) {
1916         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1917                                     PROV_RSA_FULL, 0);
1918     }
1919     ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1920 
1921     if (!ret) {
1922         skip("No context for tests\n");
1923         return;
1924     }
1925 
1926     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1927      NULL, NULL);
1928     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1929 
1930     /* This message, with one signer, has the hash and signer for index 0
1931      * available, but not for other indexes.
1932      */
1933     size = 0;
1934     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1935     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1936     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1937     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1938     size = 0;
1939     SetLastError(0xdeadbeef);
1940     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1941     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1942      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1943     SetLastError(0xdeadbeef);
1944     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1945     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1946      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1947     /* As usual, the type isn't available. */
1948     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1949     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1950      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1951 
1952     CryptMsgClose(msg);
1953 
1954     /* Opening the message using the CMS fields.. */
1955     certInfo.SerialNumber.cbData = 0;
1956     certInfo.Issuer.cbData = 0;
1957     signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1958     U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1959      sizeof(encodedCommonName);
1960     U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1961     U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1962      sizeof(serialNum);
1963     U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1964     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1965      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1966     if (!ret && GetLastError() == NTE_EXISTS)
1967         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1968          PROV_RSA_FULL, 0);
1969     ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1970     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1971      CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1972     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1973     /* still results in the version being 1 when the issuer and serial number
1974      * are used and no additional CMS fields are used.
1975      */
1976     size = sizeof(value);
1977     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
1978     ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE),
1979      "CryptMsgGetParam failed: %08x\n", GetLastError());
1980     if (ret)
1981         ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1982     /* Apparently the encoded signer can be retrieved.. */
1983     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1984     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1985     /* but the signer info, CMS signer info, and cert ID can't be. */
1986     SetLastError(0xdeadbeef);
1987     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
1988     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1989      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1990     SetLastError(0xdeadbeef);
1991     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
1992     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1993      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1994     SetLastError(0xdeadbeef);
1995     ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
1996     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1997      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1998     CryptMsgClose(msg);
1999 
2000     /* Using the KeyId field of the SignerId results in the version becoming
2001      * the CMS version.
2002      */
2003     signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2004     U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2005     U(signer.SignerId).KeyId.pbData = serialNum;
2006     ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2007      PROV_RSA_FULL, CRYPT_NEWKEYSET);
2008     if (!ret && GetLastError() == NTE_EXISTS)
2009         ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2010          PROV_RSA_FULL, 0);
2011     ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
2012     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
2013      CMSG_CRYPT_RELEASE_CONTEXT_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
2014     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
2015     size = sizeof(value);
2016     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, &value, &size);
2017     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2018     if (ret)
2019         ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
2020     /* Even for a CMS message, the signer can be retrieved.. */
2021     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
2022     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2023     /* but the signer info, CMS signer info, and cert ID can't be. */
2024     SetLastError(0xdeadbeef);
2025     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2026     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2027      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2028     SetLastError(0xdeadbeef);
2029     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2030     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2031      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2032     SetLastError(0xdeadbeef);
2033     ret = CryptMsgGetParam(msg, CMSG_SIGNER_CERT_ID_PARAM, 0, NULL, &size);
2034     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2035      "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2036     CryptMsgClose(msg);
2037 
2038     CryptReleaseContext(signer.hCryptProv, 0);
2039     pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2040      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
2041 }
2042 
2043 static void test_signed_msg(void)
2044 {
2045     test_signed_msg_open();
2046     test_signed_msg_update();
2047     test_signed_msg_encoding();
2048     test_signed_msg_get_param();
2049 }
2050 
2051 static char oid_rsa_rc4[] = szOID_RSA_RC4;
2052 
2053 static void test_enveloped_msg_open(void)
2054 {
2055     HCRYPTMSG msg;
2056     BOOL ret;
2057     CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2058     PCCERT_CONTEXT context;
2059 
2060     SetLastError(0xdeadbeef);
2061     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2062      &envelopedInfo, NULL, NULL);
2063     ok(!msg && GetLastError() == E_INVALIDARG,
2064      "expected E_INVALIDARG, got %08x\n", GetLastError());
2065 
2066     envelopedInfo.cbSize = sizeof(envelopedInfo);
2067     SetLastError(0xdeadbeef);
2068     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2069      &envelopedInfo, NULL, NULL);
2070     ok(!msg &&
2071      (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2072       GetLastError() == E_INVALIDARG), /* Win9x */
2073      "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2074 
2075     envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2076     SetLastError(0xdeadbeef);
2077     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2078      &envelopedInfo, NULL, NULL);
2079     ok(msg != NULL ||
2080      broken(!msg), /* Win9x */
2081      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2082     CryptMsgClose(msg);
2083 
2084     envelopedInfo.cRecipients = 1;
2085     if (!old_crypt32)
2086     {
2087         SetLastError(0xdeadbeef);
2088         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2089          &envelopedInfo, NULL, NULL);
2090         ok(!msg && GetLastError() == E_INVALIDARG,
2091          "expected E_INVALIDARG, got %08x\n", GetLastError());
2092     }
2093 
2094     context = CertCreateCertificateContext(X509_ASN_ENCODING,
2095      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2096     if (context)
2097     {
2098         envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2099         SetLastError(0xdeadbeef);
2100         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2101          &envelopedInfo, NULL, NULL);
2102         ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2103         CryptMsgClose(msg);
2104         SetLastError(0xdeadbeef);
2105         ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2106          PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2107         ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2108         SetLastError(0xdeadbeef);
2109         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2110          &envelopedInfo, NULL, NULL);
2111         ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2112         CryptMsgClose(msg);
2113         CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2114         CertFreeCertificateContext(context);
2115     }
2116     else
2117         win_skip("failed to create certificate context, skipping tests\n");
2118 }
2119 
2120 static void test_enveloped_msg_update(void)
2121 {
2122     HCRYPTMSG msg;
2123     BOOL ret;
2124     CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2125      { oid_rsa_rc4, { 0, NULL } }, NULL };
2126     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2127 
2128     SetLastError(0xdeadbeef);
2129     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2130      &envelopedInfo, NULL, NULL);
2131     ok(msg != NULL ||
2132      broken(!msg), /* Win9x */
2133      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2134     if (msg)
2135     {
2136         SetLastError(0xdeadbeef);
2137         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2138         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2139          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2140         SetLastError(0xdeadbeef);
2141         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2142         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2143         SetLastError(0xdeadbeef);
2144         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2145         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2146          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2147         CryptMsgClose(msg);
2148     }
2149     SetLastError(0xdeadbeef);
2150     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2151      &envelopedInfo, NULL, NULL);
2152     ok(msg != NULL ||
2153      broken(!msg), /* Win9x */
2154      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2155     if (msg)
2156     {
2157         SetLastError(0xdeadbeef);
2158         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2159         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2160          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2161         SetLastError(0xdeadbeef);
2162         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2163         ok(ret ||
2164          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2165          "CryptMsgUpdate failed: %08x\n", GetLastError());
2166         SetLastError(0xdeadbeef);
2167         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2168         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2169          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2170         CryptMsgClose(msg);
2171     }
2172     SetLastError(0xdeadbeef);
2173     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2174      CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2175     ok(msg != NULL ||
2176      broken(!msg), /* Win9x */
2177      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2178     if (msg)
2179     {
2180         SetLastError(0xdeadbeef);
2181         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2182         ok(!ret && GetLastError() == E_INVALIDARG,
2183          "expected E_INVALIDARG, got %08x\n", GetLastError());
2184         SetLastError(0xdeadbeef);
2185         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2186         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2187         CryptMsgClose(msg);
2188     }
2189     SetLastError(0xdeadbeef);
2190     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2191      CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2192     ok(msg != NULL ||
2193      broken(!msg), /* Win9x */
2194      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2195     if (msg)
2196     {
2197         SetLastError(0xdeadbeef);
2198         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2199         ok(!ret && GetLastError() == E_INVALIDARG,
2200          "expected E_INVALIDARG, got %08x\n", GetLastError());
2201         SetLastError(0xdeadbeef);
2202         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2203         ok(ret ||
2204          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2205          "CryptMsgUpdate failed: %08x\n", GetLastError());
2206         CryptMsgClose(msg);
2207     }
2208     SetLastError(0xdeadbeef);
2209     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2210      &envelopedInfo, NULL, &streamInfo);
2211     ok(msg != NULL ||
2212      broken(!msg), /* Win9x */
2213      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2214     if (msg)
2215     {
2216         SetLastError(0xdeadbeef);
2217         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2218         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2219         SetLastError(0xdeadbeef);
2220         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2221         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2222         CryptMsgClose(msg);
2223     }
2224     SetLastError(0xdeadbeef);
2225     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2226      &envelopedInfo, NULL, &streamInfo);
2227     ok(msg != NULL ||
2228      broken(!msg), /* Win9x */
2229      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2230     if (msg)
2231     {
2232         SetLastError(0xdeadbeef);
2233         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2234         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2235         SetLastError(0xdeadbeef);
2236         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2237         ok(ret ||
2238          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2239          "CryptMsgUpdate failed: %08x\n", GetLastError());
2240         CryptMsgClose(msg);
2241     }
2242 }
2243 
2244 static const BYTE envelopedEmptyBareContent[] = {
2245 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2246 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2247 0x03,0x04,0x05,0x00,0x80,0x00 };
2248 static const BYTE envelopedEmptyContent[] = {
2249 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2250 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2251 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2252 0x03,0x04,0x05,0x00,0x80,0x00 };
2253 
2254 static void test_enveloped_msg_encoding(void)
2255 {
2256     HCRYPTMSG msg;
2257     CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2258      { oid_rsa_rc4, { 0, NULL } }, NULL };
2259 
2260     SetLastError(0xdeadbeef);
2261     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2262      &envelopedInfo, NULL, NULL);
2263     ok(msg != NULL ||
2264      broken(!msg), /* Win9x */
2265      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2266     if (msg)
2267     {
2268         check_param("enveloped empty bare content", msg,
2269          CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2270          sizeof(envelopedEmptyBareContent));
2271         check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2272          envelopedEmptyContent, sizeof(envelopedEmptyContent));
2273         CryptMsgClose(msg);
2274     }
2275 }
2276 
2277 static void test_enveloped_msg(void)
2278 {
2279     test_enveloped_msg_open();
2280     test_enveloped_msg_update();
2281     test_enveloped_msg_encoding();
2282 }
2283 
2284 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2285 static const struct update_accum a4 = { 1, &b4 };
2286 
2287 static const BYTE bogusOIDContent[] = {
2288 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2289 0x04,0x00 };
2290 static const BYTE bogusHashContent[] = {
2291 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2292 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2293 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2294 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2295 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2296 static const BYTE envelopedBareContentWithoutData[] = {
2297 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2298 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2299 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2300 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2301 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2302 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2303 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2304 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2305 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2306 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2307 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2308 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2309 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2310 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2311 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2312 
2313 static void test_decode_msg_update(void)
2314 {
2315     HCRYPTMSG msg;
2316     BOOL ret;
2317     CMSG_STREAM_INFO streamInfo = { 0 };
2318     DWORD i;
2319     struct update_accum accum = { 0, NULL };
2320 
2321     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2322     /* Update with a full message in a final update */
2323     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2324     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2325     /* Can't update after a final update */
2326     SetLastError(0xdeadbeef);
2327     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2328     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2329      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2330     CryptMsgClose(msg);
2331 
2332     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2333     /* Can't send a non-final update without streaming */
2334     SetLastError(0xdeadbeef);
2335     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2336      FALSE);
2337     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2338      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2339     /* A subsequent final update succeeds */
2340     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2341     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2342     CryptMsgClose(msg);
2343 
2344     if (!old_crypt32)
2345     {
2346         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2347         /* Updating a message that has a NULL stream callback fails */
2348         SetLastError(0xdeadbeef);
2349         /* Crashes on some Win9x */
2350         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2351          FALSE);
2352         todo_wine
2353         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2354          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2355          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2356          GetLastError());
2357         /* Changing the callback pointer after the fact yields the same error (so
2358          * the message must copy the stream info, not just store a pointer to it)
2359          */
2360         streamInfo.pfnStreamOutput = nop_stream_output;
2361         SetLastError(0xdeadbeef);
2362         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2363          FALSE);
2364         todo_wine
2365         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2366          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2367          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2368          GetLastError());
2369         CryptMsgClose(msg);
2370     }
2371 
2372     /* Empty non-final updates are allowed when streaming.. */
2373     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2374     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2375     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2376     /* but final updates aren't when not enough data has been received. */
2377     SetLastError(0xdeadbeef);
2378     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2379     todo_wine
2380     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2381      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2382     CryptMsgClose(msg);
2383 
2384     /* Updating the message byte by byte is legal */
2385     streamInfo.pfnStreamOutput = accumulating_stream_output;
2386     streamInfo.pvArg = &accum;
2387     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2388     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2389         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2390     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2391     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2392     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2393     CryptMsgClose(msg);
2394     todo_wine
2395     check_updates("byte-by-byte empty content", &a4, &accum);
2396     free_updates(&accum);
2397 
2398     /* Decoding bogus content fails in non-streaming mode.. */
2399     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2400     SetLastError(0xdeadbeef);
2401     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2402     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2403      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2404      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2405      GetLastError());
2406     CryptMsgClose(msg);
2407     /* and as the final update in streaming mode.. */
2408     streamInfo.pfnStreamOutput = nop_stream_output;
2409     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2410     SetLastError(0xdeadbeef);
2411     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2412     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2413      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2414      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2415      GetLastError());
2416     CryptMsgClose(msg);
2417     /* and even as a non-final update in streaming mode. */
2418     streamInfo.pfnStreamOutput = nop_stream_output;
2419     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2420     SetLastError(0xdeadbeef);
2421     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2422     todo_wine
2423     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2424      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2425      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2426      GetLastError());
2427     CryptMsgClose(msg);
2428 
2429     /* An empty message can be opened with undetermined type.. */
2430     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2431     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2432      TRUE);
2433     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2434     CryptMsgClose(msg);
2435     /* but decoding it as an explicitly typed message fails. */
2436     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2437      NULL);
2438     SetLastError(0xdeadbeef);
2439     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2440      TRUE);
2441     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2442      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2443      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2444      GetLastError());
2445     CryptMsgClose(msg);
2446     /* On the other hand, decoding the bare content of an empty message fails
2447      * with unspecified type..
2448      */
2449     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2450     SetLastError(0xdeadbeef);
2451     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2452      sizeof(dataEmptyBareContent), TRUE);
2453     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2454      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2455      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2456      GetLastError());
2457     CryptMsgClose(msg);
2458     /* but succeeds with explicit type. */
2459     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2460      NULL);
2461     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2462      sizeof(dataEmptyBareContent), TRUE);
2463     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2464     CryptMsgClose(msg);
2465 
2466     /* Decoding valid content with an unsupported OID fails */
2467     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2468     SetLastError(0xdeadbeef);
2469     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2470     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2471      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2472     CryptMsgClose(msg);
2473 
2474     /* Similarly, opening an empty hash with unspecified type succeeds.. */
2475     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2476     SetLastError(0xdeadbeef);
2477     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2478     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2479      "CryptMsgUpdate failed: %08x\n", GetLastError());
2480     CryptMsgClose(msg);
2481     /* while with specified type it fails. */
2482     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2483      NULL);
2484     SetLastError(0xdeadbeef);
2485     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2486     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2487      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2488      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2489      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2490      GetLastError());
2491     CryptMsgClose(msg);
2492     /* On the other hand, decoding the bare content of an empty hash message
2493      * fails with unspecified type..
2494      */
2495     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2496     SetLastError(0xdeadbeef);
2497     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2498      sizeof(hashEmptyBareContent), TRUE);
2499     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2500      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2501      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2502      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2503      GetLastError());
2504     CryptMsgClose(msg);
2505     /* but succeeds with explicit type. */
2506     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2507      NULL);
2508     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2509      sizeof(hashEmptyBareContent), TRUE);
2510     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2511      "CryptMsgUpdate failed: %x\n", GetLastError());
2512     CryptMsgClose(msg);
2513 
2514     /* And again, opening a (non-empty) hash message with unspecified type
2515      * succeeds..
2516      */
2517     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2518     SetLastError(0xdeadbeef);
2519     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2520     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2521     CryptMsgClose(msg);
2522     /* while with specified type it fails.. */
2523     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2524      NULL);
2525     SetLastError(0xdeadbeef);
2526     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2527     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2528      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2529      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2530      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2531      GetLastError());
2532     CryptMsgClose(msg);
2533     /* and decoding the bare content of a non-empty hash message fails with
2534      * unspecified type..
2535      */
2536     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2537     SetLastError(0xdeadbeef);
2538     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2539     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2540      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2541      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2542      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2543      GetLastError());
2544     CryptMsgClose(msg);
2545     /* but succeeds with explicit type. */
2546     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2547      NULL);
2548     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2549     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2550     CryptMsgClose(msg);
2551 
2552     /* Opening a (non-empty) hash message with unspecified type and a bogus
2553      * hash value succeeds..
2554      */
2555     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2556     SetLastError(0xdeadbeef);
2557     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2558     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2559     CryptMsgClose(msg);
2560 
2561     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2562     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2563     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2564     CryptMsgClose(msg);
2565     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2566     SetLastError(0xdeadbeef);
2567     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2568      sizeof(signedWithCertAndCrlBareContent), TRUE);
2569     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2570      GetLastError() == OSS_DATA_ERROR /* Win9x */),
2571      "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2572      GetLastError());
2573     CryptMsgClose(msg);
2574     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2575      NULL);
2576     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2577      sizeof(signedWithCertAndCrlBareContent), TRUE);
2578     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2579     CryptMsgClose(msg);
2580 
2581     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2582      NULL, NULL);
2583     /* The first update succeeds.. */
2584     ret = CryptMsgUpdate(msg, detachedSignedContent,
2585      sizeof(detachedSignedContent), TRUE);
2586     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2587     /* as does a second (probably to update the detached portion).. */
2588     ret = CryptMsgUpdate(msg, detachedSignedContent,
2589      sizeof(detachedSignedContent), TRUE);
2590     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2591     /* while a third fails. */
2592     ret = CryptMsgUpdate(msg, detachedSignedContent,
2593      sizeof(detachedSignedContent), TRUE);
2594     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2595      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2596     CryptMsgClose(msg);
2597 
2598     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2599     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2600     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2601     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2602     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2603     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2604     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2605     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2606     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2607 
2608     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2609     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2610      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2611     CryptMsgClose(msg);
2612 
2613     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2614      NULL);
2615     SetLastError(0xdeadbeef);
2616     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2617      sizeof(envelopedEmptyBareContent), TRUE);
2618     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2619     CryptMsgClose(msg);
2620 
2621     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2622      NULL);
2623     SetLastError(0xdeadbeef);
2624     ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2625      sizeof(envelopedEmptyContent), TRUE);
2626     ok(!ret &&
2627      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2628       GetLastError() == OSS_DATA_ERROR), /* Win9x */
2629      "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2630     CryptMsgClose(msg);
2631 
2632     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2633     SetLastError(0xdeadbeef);
2634     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2635      sizeof(envelopedEmptyBareContent), TRUE);
2636     ok(!ret &&
2637      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2638       GetLastError() == OSS_DATA_ERROR), /* Win9x */
2639      "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2640     CryptMsgClose(msg);
2641 
2642     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2643     SetLastError(0xdeadbeef);
2644     ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2645      sizeof(envelopedEmptyContent), TRUE);
2646     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2647     CryptMsgClose(msg);
2648 
2649     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2650      NULL);
2651     SetLastError(0xdeadbeef);
2652     ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2653      sizeof(envelopedBareContentWithoutData), TRUE);
2654     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2655     CryptMsgClose(msg);
2656 }
2657 
2658 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2659  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2660 
2661 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2662  const CMSG_SIGNER_INFO *expected)
2663 {
2664     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2665      expected->dwVersion, got->dwVersion);
2666     ok(got->Issuer.cbData == expected->Issuer.cbData,
2667      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2668      got->Issuer.cbData);
2669     ok(!memcmp(got->Issuer.pbData, expected->Issuer.pbData, got->Issuer.cbData),
2670      "Unexpected issuer\n");
2671     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2672      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2673      got->SerialNumber.cbData);
2674     ok(!memcmp(got->SerialNumber.pbData, expected->SerialNumber.pbData,
2675      got->SerialNumber.cbData), "Unexpected serial number\n");
2676     /* FIXME: check more things */
2677 }
2678 
2679 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2680  const CMSG_CMS_SIGNER_INFO *expected)
2681 {
2682     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2683      expected->dwVersion, got->dwVersion);
2684     ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2685      "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2686      got->SignerId.dwIdChoice);
2687     if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2688     {
2689         if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2690         {
2691             ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2692              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2693              "Expected issuer size %d, got %d\n",
2694              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2695              U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2696             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2697              U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2698              U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2699              "Unexpected issuer\n");
2700             ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2701              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2702              "Expected serial number size %d, got %d\n",
2703              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2704              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2705             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2706              U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2707              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2708              "Unexpected serial number\n");
2709         }
2710         else
2711         {
2712             ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2713              "expected key id size %d, got %d\n",
2714              U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2715             ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2716              U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2717              "unexpected key id\n");
2718         }
2719     }
2720     /* FIXME: check more things */
2721 }
2722 
2723 static const BYTE signedWithCertAndCrlComputedHash[] = {
2724 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2725 0x2f };
2726 static BYTE keyIdIssuer[] = {
2727 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2728 0x0a,0x07,0x01,0x04,0x01,0x01 };
2729 static const BYTE publicPrivateKeyPair[] = {
2730 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2731 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2732 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2733 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2734 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2735 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2736 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2737 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2738 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2739 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2740 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2741 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2742 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2743 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2744 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2745 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2746 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2747 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2748 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2749 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2750 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2751 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2752 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2753 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2754 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2755 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2756 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2757 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2758 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2759 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2760 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2761 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2762 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2763 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2764 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2765 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2766 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2767 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2768 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2769 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2770 static const BYTE envelopedMessage[] = {
2771 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2772 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2773 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2774 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2775 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2776 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2777 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2778 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2779 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2780 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2781 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2782 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2783 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2784 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2785 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2786 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2787 0x04,0x5f,0x80,0xf2,0x17 };
2788 static const BYTE envelopedBareMessage[] = {
2789 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2790 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2791 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2792 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2793 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2794 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2795 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2796 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2797 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2798 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2799 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2800 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2801 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2802 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2803 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2804 0x2d,0xa3,0x6e };
2805 static const BYTE envelopedMessageWith3Recps[] = {
2806 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2807 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2808 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2809 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2810 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2811 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2812 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2813 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2814 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2815 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2816 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2817 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2818 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2819 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2820 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2821 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2822 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2823 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2824 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2825 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2826 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2827 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2828 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2829 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2830 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2831 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2832 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2833 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2834 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2835 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2836 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2837 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2838 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2839 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2840 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2841 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2842 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2843 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2844 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2845 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2846 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2847 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2848 static const BYTE serialNumber[] = {
2849 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2850 0x1c };
2851 static const BYTE issuer[] = {
2852 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2853 
2854 static void test_decode_msg_get_param(void)
2855 {
2856     HCRYPTMSG msg;
2857     HCRYPTPROV hCryptProv;
2858     HCRYPTKEY key = 0;
2859     BOOL ret;
2860     DWORD size = 0, value, req_size;
2861     LPBYTE buf;
2862     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2863 
2864     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2865     SetLastError(0xdeadbeef);
2866     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2867     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2868      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2869     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2870     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2871     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2872      sizeof(msgData));
2873     CryptMsgClose(msg);
2874 
2875     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2876     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2877     if (ret)
2878     {
2879         /* Crashes on some Win9x */
2880         check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2881         check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2882         check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2883          emptyHashParam, sizeof(emptyHashParam));
2884     }
2885     CryptMsgClose(msg);
2886     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2887     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2888     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2889     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2890      sizeof(msgData));
2891     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2892      sizeof(hashParam));
2893     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2894      hashParam, sizeof(hashParam));
2895     /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2896      * even though there's only one hash.
2897      */
2898     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2899     ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2900      "CryptMsgGetParam failed: %08x\n", GetLastError());
2901     if (ret)
2902         buf = CryptMemAlloc(size);
2903     else
2904         buf = NULL;
2905     if (buf)
2906     {
2907         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2908         ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2909         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2910         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2911         CryptMemFree(buf);
2912     }
2913     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2914      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2915     value = CMSG_HASHED_DATA_V0;
2916     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2917      sizeof(value));
2918     CryptMsgClose(msg);
2919 
2920     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2921     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2922     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2923     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2924      sizeof(msgData));
2925     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2926      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2927     size = sizeof(value);
2928     value = 2112;
2929     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2930     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2931     ok(value == 1, "Expected 1 signer, got %d\n", value);
2932     size = 0;
2933     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2934     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2935      "CryptMsgGetParam failed: %08x\n", GetLastError());
2936     if (ret)
2937         buf = CryptMemAlloc(size);
2938     else
2939         buf = NULL;
2940     if (buf)
2941     {
2942         CMSG_SIGNER_INFO signer = { 0 };
2943 
2944         signer.dwVersion = 1;
2945         signer.Issuer.cbData = sizeof(encodedCommonName);
2946         signer.Issuer.pbData = encodedCommonName;
2947         signer.SerialNumber.cbData = sizeof(serialNum);
2948         signer.SerialNumber.pbData = serialNum;
2949         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2950         req_size = size;
2951         size += 10;
2952         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2953         ok(size == req_size, "size = %u, expected %u\n", size, req_size);
2954         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2955         CryptMemFree(buf);
2956     }
2957     /* Getting the CMS signer info of a PKCS7 message is possible. */
2958     size = 0;
2959     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2960     ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2961      "CryptMsgGetParam failed: %08x\n", GetLastError());
2962     if (ret)
2963         buf = CryptMemAlloc(size);
2964     else
2965         buf = NULL;
2966     if (buf)
2967     {
2968         CMSG_CMS_SIGNER_INFO signer = { 0 };
2969 
2970         signer.dwVersion = 1;
2971         signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2972         U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2973          sizeof(encodedCommonName);
2974         U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2975         U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2976          sizeof(serialNum);
2977         U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2978         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2979         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2980         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2981         CryptMemFree(buf);
2982     }
2983     /* index is ignored when getting signer count */
2984     size = sizeof(value);
2985     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2986     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2987     ok(value == 1, "Expected 1 signer, got %d\n", value);
2988     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2989     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2990     ok(value == 0, "Expected 0 certs, got %d\n", value);
2991     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2992     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2993     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2994     CryptMsgClose(msg);
2995     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2996      NULL);
2997     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2998      sizeof(signedWithCertAndCrlBareContent), TRUE);
2999     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3000     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
3001     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3002     ok(value == 1, "Expected 1 cert, got %d\n", value);
3003     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3004     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3005     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3006     ok(value == 1, "Expected 1 CRL, got %d\n", value);
3007     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3008     check_param("signed with cert and CRL computed hash", msg,
3009      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
3010      sizeof(signedWithCertAndCrlComputedHash));
3011     CryptMsgClose(msg);
3012 
3013     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3014     ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3015      sizeof(signedKeyIdEmptyContent), TRUE);
3016     if (!ret && GetLastError() == OSS_DATA_ERROR)
3017     {
3018         CryptMsgClose(msg);
3019         win_skip("Subsequent tests crash on some Win9x\n");
3020         return;
3021     }
3022     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3023     size = sizeof(value);
3024     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3025     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3026     ok(value == 1, "Expected 1 signer, got %d\n", value);
3027     /* Getting the regular (non-CMS) signer info from a CMS message is also
3028      * possible..
3029      */
3030     size = 0;
3031     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3032     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3033     if (ret)
3034         buf = CryptMemAlloc(size);
3035     else
3036         buf = NULL;
3037     if (buf)
3038     {
3039         CMSG_SIGNER_INFO signer;
3040         BYTE zero = 0;
3041 
3042         /* and here's the little oddity:  for a CMS message using the key id
3043          * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3044          * a signer with a zero (not empty) serial number, and whose issuer is
3045          * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3046          * and value of the key id.
3047          */
3048         signer.dwVersion = CMSG_SIGNED_DATA_V3;
3049         signer.Issuer.cbData = sizeof(keyIdIssuer);
3050         signer.Issuer.pbData = keyIdIssuer;
3051         signer.SerialNumber.cbData = 1;
3052         signer.SerialNumber.pbData = &zero;
3053         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3054         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3055         CryptMemFree(buf);
3056     }
3057     size = 0;
3058     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3059     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3060     if (ret)
3061         buf = CryptMemAlloc(size);
3062     else
3063         buf = NULL;
3064     if (buf)
3065     {
3066         CMSG_CMS_SIGNER_INFO signer = { 0 };
3067 
3068         signer.dwVersion = CMSG_SIGNED_DATA_V3;
3069         signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3070         U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3071         U(signer.SignerId).KeyId.pbData = serialNum;
3072         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3073         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3074         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3075         CryptMemFree(buf);
3076     }
3077     CryptMsgClose(msg);
3078 
3079     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3080      NULL);
3081     CryptMsgUpdate(msg, envelopedEmptyBareContent,
3082      sizeof(envelopedEmptyBareContent), TRUE);
3083     check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3084      0);
3085     CryptMsgClose(msg);
3086 
3087     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3088     CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3089      TRUE);
3090     check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3091     CryptMsgClose(msg);
3092 
3093     pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3094      CRYPT_VERIFYCONTEXT);
3095     SetLastError(0xdeadbeef);
3096     ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3097      sizeof(publicPrivateKeyPair), 0, 0, &key);
3098     ok(ret ||
3099      broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3100      "CryptImportKey failed: %08x\n", GetLastError());
3101 
3102     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3103     CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3104     check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3105      envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3106     if (key)
3107     {
3108         decryptPara.hCryptProv = hCryptProv;
3109         SetLastError(0xdeadbeef);
3110         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3111         ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3112         decryptPara.hCryptProv = 0;
3113         SetLastError(0xdeadbeef);
3114         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3115         ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3116          "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3117         check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3118          sizeof(msgData));
3119     }
3120     else
3121         win_skip("failed to import a key, skipping tests\n");
3122     CryptMsgClose(msg);
3123 
3124     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3125      NULL);
3126     CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3127      TRUE);
3128     check_param("enveloped bare message before decrypting", msg,
3129      CMSG_CONTENT_PARAM, envelopedBareMessage +
3130      sizeof(envelopedBareMessage) - 4, 4);
3131     if (key)
3132     {
3133         decryptPara.hCryptProv = hCryptProv;
3134         SetLastError(0xdeadbeef);
3135         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3136         ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3137         check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3138          sizeof(msgData));
3139     }
3140     else
3141         win_skip("failed to import a key, skipping tests\n");
3142     CryptMsgClose(msg);
3143 
3144     if (key)
3145         CryptDestroyKey(key);
3146     CryptReleaseContext(hCryptProv, 0);
3147 
3148     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3149     CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3150      sizeof(envelopedMessageWith3Recps), TRUE);
3151     value = 3;
3152     check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3153      (const BYTE *)&value, sizeof(value));
3154     size = 0;
3155     SetLastError(0xdeadbeef);
3156     ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3157     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3158      "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3159     size = 0;
3160     SetLastError(0xdeadbeef);
3161     ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3162     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3163     ok(size >= 142, "unexpected size: %u\n", size);
3164     if (ret)
3165         buf = CryptMemAlloc(size);
3166     else
3167         buf = NULL;
3168     if (buf)
3169     {
3170         CERT_INFO *certInfo = (CERT_INFO *)buf;
3171 
3172         SetLastError(0xdeadbeef);
3173         ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3174         ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3175         ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3176          "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3177         ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3178          sizeof(serialNumber)), "unexpected serial number\n");
3179         ok(certInfo->Issuer.cbData == sizeof(issuer),
3180          "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3181         ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3182          "unexpected issuer\n");
3183         CryptMemFree(buf);
3184     }
3185     CryptMsgClose(msg);
3186 }
3187 
3188 static void test_decode_msg(void)
3189 {
3190     test_decode_msg_update();
3191     test_decode_msg_get_param();
3192 }
3193 
3194 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3195 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3196 static BYTE encodedPubKey[] = {
3197 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3198 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3199 0x0d,0x0e,0x0f };
3200 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3201 static BYTE mod_encoded[] = {
3202  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3203  0x01,0x00,0x01 };
3204 
3205 static void test_msg_control(void)
3206 {
3207     static char oid_rsa_rsa[] = szOID_RSA_RSA;
3208     BOOL ret;
3209     HCRYPTMSG msg;
3210     DWORD i;
3211     CERT_INFO certInfo = { 0 };
3212     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3213     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3214     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3215 
3216     /* Crashes
3217     ret = CryptMsgControl(NULL, 0, 0, NULL);
3218     */
3219 
3220     /* Data encode messages don't allow any sort of control.. */
3221     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3222      NULL);
3223     /* either with no prior update.. */
3224     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3225     {
3226         SetLastError(0xdeadbeef);
3227         ret = CryptMsgControl(msg, 0, i, NULL);
3228         ok(!ret && GetLastError() == E_INVALIDARG,
3229          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3230     }
3231     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3232     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3233     /* or after an update. */
3234     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3235     {
3236         SetLastError(0xdeadbeef);
3237         ret = CryptMsgControl(msg, 0, i, NULL);
3238         ok(!ret && GetLastError() == E_INVALIDARG,
3239          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3240     }
3241     CryptMsgClose(msg);
3242 
3243     /* Hash encode messages don't allow any sort of control.. */
3244     hashInfo.cbSize = sizeof(hashInfo);
3245     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3246     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3247      NULL, NULL);
3248     /* either with no prior update.. */
3249     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3250     {
3251         SetLastError(0xdeadbeef);
3252         ret = CryptMsgControl(msg, 0, i, NULL);
3253         ok(!ret && GetLastError() == E_INVALIDARG,
3254          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3255     }
3256     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3257     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3258     /* or after an update. */
3259     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3260     {
3261         SetLastError(0xdeadbeef);
3262         ret = CryptMsgControl(msg, 0, i, NULL);
3263         ok(!ret && GetLastError() == E_INVALIDARG,
3264          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3265     }
3266     CryptMsgClose(msg);
3267 
3268     /* Signed encode messages likewise don't allow any sort of control.. */
3269     signInfo.cbSize = sizeof(signInfo);
3270     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3271      NULL, NULL);
3272     /* either before an update.. */
3273     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3274     {
3275         SetLastError(0xdeadbeef);
3276         ret = CryptMsgControl(msg, 0, i, NULL);
3277         ok(!ret && GetLastError() == E_INVALIDARG,
3278          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3279     }
3280     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3281     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3282     /* or after an update. */
3283     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3284     {
3285         SetLastError(0xdeadbeef);
3286         ret = CryptMsgControl(msg, 0, i, NULL);
3287         ok(!ret && GetLastError() == E_INVALIDARG,
3288          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3289     }
3290     CryptMsgClose(msg);
3291 
3292     /* Decode messages behave a bit differently. */
3293     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3294     /* Bad control type */
3295     SetLastError(0xdeadbeef);
3296     ret = CryptMsgControl(msg, 0, 0, NULL);
3297     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3298      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3299     SetLastError(0xdeadbeef);
3300     ret = CryptMsgControl(msg, 1, 0, NULL);
3301     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3302      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3303     /* Can't verify the hash of an indeterminate-type message */
3304     SetLastError(0xdeadbeef);
3305     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3306     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3307      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3308     /* Crashes
3309     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3310      */
3311     /* Can't decrypt an indeterminate-type message */
3312     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3313     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3314      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3315     CryptMsgClose(msg);
3316 
3317     if (!old_crypt32)
3318     {
3319         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3320          NULL);
3321         /* Can't verify the hash of an empty message */
3322         SetLastError(0xdeadbeef);
3323         /* Crashes on some Win9x */
3324         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3325         todo_wine
3326         ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3327          "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3328         /* Crashes
3329         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3330          */
3331         /* Can't verify the signature of a hash message */
3332         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3333         ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3334          "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3335         CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3336          TRUE);
3337         /* Oddly enough, this fails, crashes on some Win9x */
3338         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3339         ok(!ret, "Expected failure\n");
3340         CryptMsgClose(msg);
3341     }
3342     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3343      NULL);
3344     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3345     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3346     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3347     /* Can't decrypt an indeterminate-type message */
3348     SetLastError(0xdeadbeef);
3349     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3350     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3351      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3352     CryptMsgClose(msg);
3353 
3354     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3355      NULL, NULL);
3356     /* Can't verify the hash of a detached message before it's been updated. */
3357     SetLastError(0xdeadbeef);
3358     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3359     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3360      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3361     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3362      TRUE);
3363     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3364     /* Still can't verify the hash of a detached message with the content
3365      * of the detached hash given..
3366      */
3367     SetLastError(0xdeadbeef);
3368     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3369     ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3370      "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3371     /* and giving the content of the message after attempting to verify the
3372      * hash fails.
3373      */
3374     SetLastError(0xdeadbeef);
3375     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3376     todo_wine
3377     ok(!ret &&
3378        (GetLastError() == NTE_BAD_HASH_STATE ||
3379         GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
3380         GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3381      "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3382      "got %08x\n", GetLastError());
3383     CryptMsgClose(msg);
3384 
3385     /* Finally, verifying the hash of a detached message in the correct order:
3386      * 1. Update with the detached hash message
3387      * 2. Update with the content of the message
3388      * 3. Verifying the hash of the message
3389      * succeeds.
3390      */
3391     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3392      NULL, NULL);
3393     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3394      TRUE);
3395     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3396     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3397     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3398     SetLastError(0xdeadbeef);
3399     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3400     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3401     CryptMsgClose(msg);
3402 
3403     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3404      NULL);
3405     /* Can't verify the hash of a signed message */
3406     SetLastError(0xdeadbeef);
3407     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3408     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3409      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3410     /* Can't decrypt a signed message */
3411     SetLastError(0xdeadbeef);
3412     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3413     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3414      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3415     /* Crash
3416     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3417     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3418      */
3419     CryptMsgUpdate(msg, signedWithCertBareContent,
3420      sizeof(signedWithCertBareContent), TRUE);
3421     /* With an empty cert info, the signer can't be found in the message (and
3422      * the signature can't be verified.
3423      */
3424     SetLastError(0xdeadbeef);
3425     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3426     ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3427      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3428      "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3429      GetLastError());
3430     /* The cert info is expected to have an issuer, serial number, and public
3431      * key info set.
3432      */
3433     certInfo.SerialNumber.cbData = sizeof(serialNum);
3434     certInfo.SerialNumber.pbData = serialNum;
3435     certInfo.Issuer.cbData = sizeof(encodedCommonName);
3436     certInfo.Issuer.pbData = encodedCommonName;
3437     SetLastError(0xdeadbeef);
3438     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3439     ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3440      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3441      "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3442     CryptMsgClose(msg);
3443     /* This cert has a public key, but it's not in a usable form */
3444     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3445      NULL);
3446     ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3447      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3448     if (ret)
3449     {
3450         /* Crashes on some Win9x */
3451         /* Again, cert info needs to have a public key set */
3452         SetLastError(0xdeadbeef);
3453         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3454         ok(!ret &&
3455          (GetLastError() == CRYPT_E_ASN1_EOD ||
3456           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3457          "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3458         /* The public key is supposed to be in encoded form.. */
3459         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3460         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3461         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3462         SetLastError(0xdeadbeef);
3463         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3464         ok(!ret &&
3465          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3466           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3467          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3468         /* but not as a X509_PUBLIC_KEY_INFO.. */
3469         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3470         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3471         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3472         SetLastError(0xdeadbeef);
3473         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3474         ok(!ret &&
3475          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3476           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3477          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3478         /* This decodes successfully, but it doesn't match any key in the message */
3479         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3480         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3481         SetLastError(0xdeadbeef);
3482         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3483         /* In Wine's rsaenh, this fails to decode because the key length is too
3484          * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
3485          * now.
3486          */
3487         todo_wine
3488         ok(!ret &&
3489          (GetLastError() == NTE_BAD_SIGNATURE ||
3490           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3491          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3492     }
3493     CryptMsgClose(msg);
3494     /* A message with no data doesn't have a valid signature */
3495     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3496     ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3497      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3498     if (ret)
3499     {
3500         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3501         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3502         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3503         SetLastError(0xdeadbeef);
3504         /* Crashes on some Win9x */
3505         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3506         ok(!ret &&
3507          (GetLastError() == NTE_BAD_SIGNATURE ||
3508           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3509          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3510     }
3511     CryptMsgClose(msg);
3512     /* Finally, this succeeds */
3513     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3514     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3515      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3516     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3517     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3518      "CryptMsgControl failed: %08x\n", GetLastError());
3519     CryptMsgClose(msg);
3520 
3521     /* Test verifying signature of a detached signed message */
3522     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3523      NULL, NULL);
3524     ret = CryptMsgUpdate(msg, detachedSignedContent,
3525      sizeof(detachedSignedContent), TRUE);
3526     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3527     /* Can't verify the sig without having updated the data */
3528     SetLastError(0xdeadbeef);
3529     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3530     ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3531      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3532      "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3533      GetLastError());
3534     /* Now that the signature's been checked, can't do the final update */
3535     SetLastError(0xdeadbeef);
3536     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3537     todo_wine
3538     ok((!ret &&
3539      (GetLastError() == NTE_BAD_HASH_STATE ||
3540       GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
3541       GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3542       broken(ret), /* Win9x */
3543      "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3544      "got %08x\n", GetLastError());
3545     CryptMsgClose(msg);
3546     /* Updating with the detached portion of the message and the data of the
3547      * the message allows the sig to be verified.
3548      */
3549     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3550      NULL, NULL);
3551     ret = CryptMsgUpdate(msg, detachedSignedContent,
3552      sizeof(detachedSignedContent), TRUE);
3553     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3554     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3555     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3556     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3557     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3558      "CryptMsgControl failed: %08x\n", GetLastError());
3559     CryptMsgClose(msg);
3560 
3561     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3562      NULL);
3563     decryptPara.cbSize = 0;
3564     SetLastError(0xdeadbeef);
3565     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3566     ok(!ret && GetLastError() == E_INVALIDARG,
3567      "expected E_INVALIDARG, got %08x\n", GetLastError());
3568     decryptPara.cbSize = sizeof(decryptPara);
3569     if (!old_crypt32)
3570     {
3571         SetLastError(0xdeadbeef);
3572         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3573         ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3574          "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3575     }
3576     SetLastError(0xdeadbeef);
3577     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3578      sizeof(envelopedEmptyBareContent), TRUE);
3579     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3580     SetLastError(0xdeadbeef);
3581     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3582     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3583      "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3584     CryptMsgClose(msg);
3585 
3586     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3587      NULL);
3588     SetLastError(0xdeadbeef);
3589     ret = CryptMsgUpdate(msg, envelopedBareMessage,
3590      sizeof(envelopedBareMessage), TRUE);
3591     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3592     SetLastError(0xdeadbeef);
3593     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3594     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3595      "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3596     CryptMsgClose(msg);
3597 }
3598 
3599 /* win9x has much less parameter checks and will crash on many tests
3600  * this code is from test_signed_msg_update()
3601  */
3602 static BOOL detect_nt(void)
3603 {
3604     BOOL ret;
3605     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3606     CERT_INFO certInfo = { 0 };
3607 
3608     if (!pCryptAcquireContextW)
3609         return FALSE;
3610 
3611     certInfo.SerialNumber.cbData = sizeof(serialNum);
3612     certInfo.SerialNumber.pbData = serialNum;
3613     certInfo.Issuer.cbData = sizeof(encodedCommonName);
3614     certInfo.Issuer.pbData = encodedCommonName;
3615     signer.pCertInfo = &certInfo;
3616     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3617 
3618     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3619                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3620     if (!ret && GetLastError() == NTE_EXISTS) {
3621         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3622                                     PROV_RSA_FULL, 0);
3623     }
3624 
3625     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3626 
3627     /* cleanup */
3628     CryptReleaseContext(signer.hCryptProv, 0);
3629     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3630                           CRYPT_DELETEKEYSET);
3631 
3632     return TRUE;
3633 }
3634 
3635 static void test_msg_get_and_verify_signer(void)
3636 {
3637     BOOL ret;
3638     HCRYPTMSG msg;
3639     PCCERT_CONTEXT signer;
3640     DWORD signerIndex;
3641     HCERTSTORE store;
3642 
3643     /* Crash */
3644     if (0)
3645     {
3646         CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3647         CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3648     }
3649 
3650     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3651     /* An empty message has no signer */
3652     SetLastError(0xdeadbeef);
3653     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3654     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3655      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3656     /* The signer is cleared on error */
3657     signer = (PCCERT_CONTEXT)0xdeadbeef;
3658     SetLastError(0xdeadbeef);
3659     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3660     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3661      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3662     ok(!signer, "expected signer to be NULL\n");
3663     /* The signer index is also cleared on error */
3664     signerIndex = 0xdeadbeef;
3665     SetLastError(0xdeadbeef);
3666     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3667     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3668      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3669     ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3670     /* An unsigned message (msgData isn't a signed message at all)
3671      * likewise has no signer.
3672      */
3673     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3674     SetLastError(0xdeadbeef);
3675     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3676     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3677      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3678     CryptMsgClose(msg);
3679 
3680     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3681     /* A "signed" message created with no signer cert likewise has no signer */
3682     ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3683     if (ret)
3684     {
3685         /* Crashes on most Win9x */
3686         ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3687         ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3688          "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3689     }
3690     CryptMsgClose(msg);
3691 
3692     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3693     /* A signed message succeeds, .. */
3694     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3695      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3696     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3697     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3698      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3699     /* the signer index can be retrieved, .. */
3700     signerIndex = 0xdeadbeef;
3701     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3702     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3703      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3704     if (ret)
3705         ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3706     /* as can the signer cert. */
3707     signer = (PCCERT_CONTEXT)0xdeadbeef;
3708     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3709     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3710      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3711     if (ret)
3712         ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3713      "expected a valid signer\n");
3714     if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3715         CertFreeCertificateContext(signer);
3716     /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3717      */
3718     signerIndex = 0xdeadbeef;
3719     SetLastError(0xdeadbeef);
3720     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3721      NULL, &signerIndex);
3722     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3723      "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3724     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3725      * message signer not to be found.
3726      */
3727     SetLastError(0xdeadbeef);
3728     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3729      NULL, NULL);
3730     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3731      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3732      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3733     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3734      * the message signer not to be found.
3735      */
3736     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3737      CERT_STORE_CREATE_NEW_FLAG, NULL);
3738     SetLastError(0xdeadbeef);
3739     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3740      NULL, NULL);
3741     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3742      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3743      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3744     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3745      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3746      CERT_STORE_ADD_ALWAYS, NULL);
3747     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3748      "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3749     /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3750      * the signer succeeds.
3751      */
3752     SetLastError(0xdeadbeef);
3753     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3754      NULL, NULL);
3755     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3756      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3757     CertCloseStore(store, 0);
3758     CryptMsgClose(msg);
3759 }
3760 
3761 START_TEST(msg)
3762 {
3763     init_function_pointers();
3764     have_nt = detect_nt();
3765     if (!have_nt)
3766         win_skip("Win9x crashes on some parameter checks\n");
3767 
3768     /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3769     if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3770     {
3771         win_skip("Some tests will crash on older crypt32 implementations\n");
3772         old_crypt32 = TRUE;
3773     }
3774 
3775     /* Basic parameter checking tests */
3776     test_msg_open_to_encode();
3777     test_msg_open_to_decode();
3778     test_msg_get_param();
3779     test_msg_close();
3780     test_msg_control();
3781 
3782     /* Message-type specific tests */
3783     test_data_msg();
3784     test_hash_msg();
3785     test_signed_msg();
3786     test_enveloped_msg();
3787     test_decode_msg();
3788 
3789     test_msg_get_and_verify_signer();
3790 }
3791