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