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