include/msvcrt: Define more CPU control word flags.
[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     todo_wine
2047     ok(!msg && GetLastError() == E_INVALIDARG,
2048      "expected E_INVALIDARG, got %08x\n", GetLastError());
2049
2050     envelopedInfo.cbSize = sizeof(envelopedInfo);
2051     SetLastError(0xdeadbeef);
2052     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2053      &envelopedInfo, NULL, NULL);
2054     todo_wine
2055     ok(!msg &&
2056      (GetLastError() == CRYPT_E_UNKNOWN_ALGO ||
2057       GetLastError() == E_INVALIDARG), /* Win9x */
2058      "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2059
2060     envelopedInfo.ContentEncryptionAlgorithm.pszObjId = oid_rsa_rc4;
2061     SetLastError(0xdeadbeef);
2062     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2063      &envelopedInfo, NULL, NULL);
2064     todo_wine
2065     ok(msg != NULL ||
2066      broken(!msg), /* Win9x */
2067      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2068     CryptMsgClose(msg);
2069
2070     envelopedInfo.cRecipients = 1;
2071     if (!old_crypt32)
2072     {
2073         SetLastError(0xdeadbeef);
2074         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2075          &envelopedInfo, NULL, NULL);
2076         todo_wine
2077         ok(!msg && GetLastError() == E_INVALIDARG,
2078          "expected E_INVALIDARG, got %08x\n", GetLastError());
2079     }
2080
2081     context = CertCreateCertificateContext(X509_ASN_ENCODING,
2082      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
2083     if (context)
2084     {
2085         envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2086         SetLastError(0xdeadbeef);
2087         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2088          &envelopedInfo, NULL, NULL);
2089         todo_wine
2090         ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2091         CryptMsgClose(msg);
2092         SetLastError(0xdeadbeef);
2093         ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2094          PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
2095         ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2096         SetLastError(0xdeadbeef);
2097         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2098          &envelopedInfo, NULL, NULL);
2099         todo_wine
2100         ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2101         CryptMsgClose(msg);
2102         CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2103         CertFreeCertificateContext(context);
2104     }
2105     else
2106         win_skip("failed to create certificate context, skipping tests\n");
2107 }
2108
2109 static void test_enveloped_msg_update(void)
2110 {
2111     HCRYPTMSG msg;
2112     BOOL ret;
2113     CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2114      { oid_rsa_rc4, { 0, NULL } }, NULL };
2115     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2116
2117     SetLastError(0xdeadbeef);
2118     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2119      &envelopedInfo, NULL, NULL);
2120     todo_wine
2121     ok(msg != NULL ||
2122      broken(!msg), /* Win9x */
2123      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2124     if (msg)
2125     {
2126         SetLastError(0xdeadbeef);
2127         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2128         todo_wine
2129         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2130          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2131         SetLastError(0xdeadbeef);
2132         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2133         todo_wine
2134         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2135         SetLastError(0xdeadbeef);
2136         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2137         todo_wine
2138         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2139          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2140         CryptMsgClose(msg);
2141     }
2142     SetLastError(0xdeadbeef);
2143     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2144      &envelopedInfo, NULL, NULL);
2145     todo_wine
2146     ok(msg != NULL ||
2147      broken(!msg), /* Win9x */
2148      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2149     if (msg)
2150     {
2151         SetLastError(0xdeadbeef);
2152         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2153         todo_wine
2154         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2155          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2156         SetLastError(0xdeadbeef);
2157         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2158         todo_wine
2159         ok(ret ||
2160          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2161          "CryptMsgUpdate failed: %08x\n", GetLastError());
2162         SetLastError(0xdeadbeef);
2163         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2164         todo_wine
2165         ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2166          "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2167         CryptMsgClose(msg);
2168     }
2169     SetLastError(0xdeadbeef);
2170     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2171      CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2172     todo_wine
2173     ok(msg != NULL ||
2174      broken(!msg), /* Win9x */
2175      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2176     if (msg)
2177     {
2178         SetLastError(0xdeadbeef);
2179         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2180         todo_wine
2181         ok(!ret && GetLastError() == E_INVALIDARG,
2182          "expected E_INVALIDARG, got %08x\n", GetLastError());
2183         SetLastError(0xdeadbeef);
2184         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2185         todo_wine
2186         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2187         CryptMsgClose(msg);
2188     }
2189     SetLastError(0xdeadbeef);
2190     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
2191      CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2192     todo_wine
2193     ok(msg != NULL ||
2194      broken(!msg), /* Win9x */
2195      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2196     if (msg)
2197     {
2198         SetLastError(0xdeadbeef);
2199         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2200         todo_wine
2201         ok(!ret && GetLastError() == E_INVALIDARG,
2202          "expected E_INVALIDARG, got %08x\n", GetLastError());
2203         SetLastError(0xdeadbeef);
2204         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2205         todo_wine
2206         ok(ret ||
2207          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2208          "CryptMsgUpdate failed: %08x\n", GetLastError());
2209         CryptMsgClose(msg);
2210     }
2211     SetLastError(0xdeadbeef);
2212     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2213      &envelopedInfo, NULL, &streamInfo);
2214     todo_wine
2215     ok(msg != NULL ||
2216      broken(!msg), /* Win9x */
2217      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2218     if (msg)
2219     {
2220         SetLastError(0xdeadbeef);
2221         ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2222         todo_wine
2223         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2224         SetLastError(0xdeadbeef);
2225         ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2226         todo_wine
2227         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2228         CryptMsgClose(msg);
2229     }
2230     SetLastError(0xdeadbeef);
2231     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2232      &envelopedInfo, NULL, &streamInfo);
2233     todo_wine
2234     ok(msg != NULL ||
2235      broken(!msg), /* Win9x */
2236      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2237     if (msg)
2238     {
2239         SetLastError(0xdeadbeef);
2240         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2241         todo_wine
2242         ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2243         SetLastError(0xdeadbeef);
2244         ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2245         todo_wine
2246         ok(ret ||
2247          broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2248          "CryptMsgUpdate failed: %08x\n", GetLastError());
2249         CryptMsgClose(msg);
2250     }
2251 }
2252
2253 static const BYTE envelopedEmptyBareContent[] = {
2254 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2255 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2256 0x03,0x04,0x05,0x00,0x80,0x00 };
2257 static const BYTE envelopedEmptyContent[] = {
2258 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2259 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2260 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2261 0x03,0x04,0x05,0x00,0x80,0x00 };
2262
2263 static void test_enveloped_msg_encoding(void)
2264 {
2265     HCRYPTMSG msg;
2266     CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2267      { oid_rsa_rc4, { 0, NULL } }, NULL };
2268
2269     SetLastError(0xdeadbeef);
2270     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED,
2271      &envelopedInfo, NULL, NULL);
2272     todo_wine
2273     ok(msg != NULL ||
2274      broken(!msg), /* Win9x */
2275      "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2276     if (msg)
2277     {
2278         check_param("enveloped empty bare content", msg,
2279          CMSG_BARE_CONTENT_PARAM, envelopedEmptyBareContent,
2280          sizeof(envelopedEmptyBareContent));
2281         check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2282          envelopedEmptyContent, sizeof(envelopedEmptyContent));
2283         CryptMsgClose(msg);
2284     }
2285 }
2286
2287 static void test_enveloped_msg(void)
2288 {
2289     test_enveloped_msg_open();
2290     test_enveloped_msg_update();
2291     test_enveloped_msg_encoding();
2292 }
2293
2294 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2295 static const struct update_accum a4 = { 1, &b4 };
2296
2297 static const BYTE bogusOIDContent[] = {
2298 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2299 0x04,0x00 };
2300 static const BYTE bogusHashContent[] = {
2301 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2302 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2303 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2304 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2305 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2306 static const BYTE envelopedBareContentWithoutData[] = {
2307 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2308 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2309 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2310 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2311 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2312 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2313 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2314 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2315 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2316 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2317 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2318 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2319 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2320 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2321 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2322
2323 static void test_decode_msg_update(void)
2324 {
2325     HCRYPTMSG msg;
2326     BOOL ret;
2327     CMSG_STREAM_INFO streamInfo = { 0 };
2328     DWORD i;
2329     struct update_accum accum = { 0, NULL };
2330
2331     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2332     /* Update with a full message in a final update */
2333     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2334     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2335     /* Can't update after a final update */
2336     SetLastError(0xdeadbeef);
2337     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2338     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2339      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2340     CryptMsgClose(msg);
2341
2342     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2343     /* Can't send a non-final update without streaming */
2344     SetLastError(0xdeadbeef);
2345     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2346      FALSE);
2347     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2348      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2349     /* A subsequent final update succeeds */
2350     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2351     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2352     CryptMsgClose(msg);
2353
2354     if (!old_crypt32)
2355     {
2356         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2357         /* Updating a message that has a NULL stream callback fails */
2358         SetLastError(0xdeadbeef);
2359         /* Crashes on some Win9x */
2360         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2361          FALSE);
2362         todo_wine
2363         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2364          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2365          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2366          GetLastError());
2367         /* Changing the callback pointer after the fact yields the same error (so
2368          * the message must copy the stream info, not just store a pointer to it)
2369          */
2370         streamInfo.pfnStreamOutput = nop_stream_output;
2371         SetLastError(0xdeadbeef);
2372         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2373          FALSE);
2374         todo_wine
2375         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2376          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2377          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2378          GetLastError());
2379         CryptMsgClose(msg);
2380     }
2381
2382     /* Empty non-final updates are allowed when streaming.. */
2383     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2384     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2385     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2386     /* but final updates aren't when not enough data has been received. */
2387     SetLastError(0xdeadbeef);
2388     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2389     todo_wine
2390     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2391      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2392     CryptMsgClose(msg);
2393
2394     /* Updating the message byte by byte is legal */
2395     streamInfo.pfnStreamOutput = accumulating_stream_output;
2396     streamInfo.pvArg = &accum;
2397     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2398     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2399         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2400     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2401     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2402     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2403     CryptMsgClose(msg);
2404     todo_wine
2405     check_updates("byte-by-byte empty content", &a4, &accum);
2406     free_updates(&accum);
2407
2408     /* Decoding bogus content fails in non-streaming mode.. */
2409     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2410     SetLastError(0xdeadbeef);
2411     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2412     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2413      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2414      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2415      GetLastError());
2416     CryptMsgClose(msg);
2417     /* and as the final update in streaming mode.. */
2418     streamInfo.pfnStreamOutput = nop_stream_output;
2419     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2420     SetLastError(0xdeadbeef);
2421     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2422     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2423      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2424      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2425      GetLastError());
2426     CryptMsgClose(msg);
2427     /* and even as a non-final update in streaming mode. */
2428     streamInfo.pfnStreamOutput = nop_stream_output;
2429     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2430     SetLastError(0xdeadbeef);
2431     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2432     todo_wine
2433     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2434      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2435      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2436      GetLastError());
2437     CryptMsgClose(msg);
2438
2439     /* An empty message can be opened with undetermined type.. */
2440     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2441     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2442      TRUE);
2443     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2444     CryptMsgClose(msg);
2445     /* but decoding it as an explicitly typed message fails. */
2446     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2447      NULL);
2448     SetLastError(0xdeadbeef);
2449     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2450      TRUE);
2451     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2452      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2453      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2454      GetLastError());
2455     CryptMsgClose(msg);
2456     /* On the other hand, decoding the bare content of an empty message fails
2457      * with unspecified type..
2458      */
2459     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2460     SetLastError(0xdeadbeef);
2461     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2462      sizeof(dataEmptyBareContent), TRUE);
2463     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2464      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2465      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2466      GetLastError());
2467     CryptMsgClose(msg);
2468     /* but succeeds with explicit type. */
2469     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2470      NULL);
2471     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2472      sizeof(dataEmptyBareContent), TRUE);
2473     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2474     CryptMsgClose(msg);
2475
2476     /* Decoding valid content with an unsupported OID fails */
2477     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2478     SetLastError(0xdeadbeef);
2479     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2480     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2481      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2482     CryptMsgClose(msg);
2483
2484     /* Similarly, opening an empty hash with unspecified type succeeds.. */
2485     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2486     SetLastError(0xdeadbeef);
2487     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2488     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2489      "CryptMsgUpdate failed: %08x\n", GetLastError());
2490     CryptMsgClose(msg);
2491     /* while with specified type it fails. */
2492     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2493      NULL);
2494     SetLastError(0xdeadbeef);
2495     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2496     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2497      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2498      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2499      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2500      GetLastError());
2501     CryptMsgClose(msg);
2502     /* On the other hand, decoding the bare content of an empty hash message
2503      * fails with unspecified type..
2504      */
2505     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2506     SetLastError(0xdeadbeef);
2507     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2508      sizeof(hashEmptyBareContent), TRUE);
2509     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2510      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2511      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2512      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2513      GetLastError());
2514     CryptMsgClose(msg);
2515     /* but succeeds with explicit type. */
2516     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2517      NULL);
2518     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2519      sizeof(hashEmptyBareContent), TRUE);
2520     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2521      "CryptMsgUpdate failed: %x\n", GetLastError());
2522     CryptMsgClose(msg);
2523
2524     /* And again, opening a (non-empty) hash message with unspecified type
2525      * succeeds..
2526      */
2527     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2528     SetLastError(0xdeadbeef);
2529     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2530     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2531     CryptMsgClose(msg);
2532     /* while with specified type it fails.. */
2533     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2534      NULL);
2535     SetLastError(0xdeadbeef);
2536     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2537     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2538      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2539      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2540      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2541      GetLastError());
2542     CryptMsgClose(msg);
2543     /* and decoding the bare content of a non-empty hash message fails with
2544      * unspecified type..
2545      */
2546     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2547     SetLastError(0xdeadbeef);
2548     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2549     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2550      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2551      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2552      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2553      GetLastError());
2554     CryptMsgClose(msg);
2555     /* but succeeds with explicit type. */
2556     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2557      NULL);
2558     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2559     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2560     CryptMsgClose(msg);
2561
2562     /* Opening a (non-empty) hash message with unspecified type and a bogus
2563      * hash value succeeds..
2564      */
2565     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2566     SetLastError(0xdeadbeef);
2567     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2568     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2569     CryptMsgClose(msg);
2570
2571     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2572     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2573     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2574     CryptMsgClose(msg);
2575     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2576     SetLastError(0xdeadbeef);
2577     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2578      sizeof(signedWithCertAndCrlBareContent), TRUE);
2579     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2580      GetLastError() == OSS_DATA_ERROR /* Win9x */),
2581      "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2582      GetLastError());
2583     CryptMsgClose(msg);
2584     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2585      NULL);
2586     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2587      sizeof(signedWithCertAndCrlBareContent), TRUE);
2588     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2589     CryptMsgClose(msg);
2590
2591     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2592      NULL, NULL);
2593     /* The first update succeeds.. */
2594     ret = CryptMsgUpdate(msg, detachedSignedContent,
2595      sizeof(detachedSignedContent), TRUE);
2596     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2597     /* as does a second (probably to update the detached portion).. */
2598     ret = CryptMsgUpdate(msg, detachedSignedContent,
2599      sizeof(detachedSignedContent), TRUE);
2600     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2601     /* while a third fails. */
2602     ret = CryptMsgUpdate(msg, detachedSignedContent,
2603      sizeof(detachedSignedContent), TRUE);
2604     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2605      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2606     CryptMsgClose(msg);
2607
2608     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2609     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2610     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2611     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2612     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2613     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2614     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2615     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2616     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2617
2618     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2619     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2620      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2621     CryptMsgClose(msg);
2622
2623     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2624      NULL);
2625     SetLastError(0xdeadbeef);
2626     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2627      sizeof(envelopedEmptyBareContent), TRUE);
2628     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2629     CryptMsgClose(msg);
2630
2631     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2632      NULL);
2633     SetLastError(0xdeadbeef);
2634     ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2635      sizeof(envelopedEmptyContent), TRUE);
2636     todo_wine
2637     ok(!ret &&
2638      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2639       GetLastError() == OSS_DATA_ERROR), /* Win9x */
2640      "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2641     CryptMsgClose(msg);
2642
2643     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2644     SetLastError(0xdeadbeef);
2645     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
2646      sizeof(envelopedEmptyBareContent), TRUE);
2647     ok(!ret &&
2648      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2649       GetLastError() == OSS_DATA_ERROR), /* Win9x */
2650      "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2651     CryptMsgClose(msg);
2652
2653     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2654     SetLastError(0xdeadbeef);
2655     ret = CryptMsgUpdate(msg, envelopedEmptyContent,
2656      sizeof(envelopedEmptyContent), TRUE);
2657     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2658     CryptMsgClose(msg);
2659
2660     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
2661      NULL);
2662     SetLastError(0xdeadbeef);
2663     ret = CryptMsgUpdate(msg, envelopedBareContentWithoutData,
2664      sizeof(envelopedBareContentWithoutData), TRUE);
2665     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2666     CryptMsgClose(msg);
2667 }
2668
2669 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2670  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2671
2672 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2673  const CMSG_SIGNER_INFO *expected)
2674 {
2675     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2676      expected->dwVersion, got->dwVersion);
2677     ok(got->Issuer.cbData == expected->Issuer.cbData,
2678      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2679      got->Issuer.cbData);
2680     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2681      "Unexpected issuer\n");
2682     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2683      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2684      got->SerialNumber.cbData);
2685     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2686      got->SerialNumber.cbData), "Unexpected serial number\n");
2687     /* FIXME: check more things */
2688 }
2689
2690 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2691  const CMSG_CMS_SIGNER_INFO *expected)
2692 {
2693     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2694      expected->dwVersion, got->dwVersion);
2695     ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2696      "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2697      got->SignerId.dwIdChoice);
2698     if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2699     {
2700         if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2701         {
2702             ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2703              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2704              "Expected issuer size %d, got %d\n",
2705              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2706              U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2707             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2708              U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2709              U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2710              "Unexpected issuer\n");
2711             ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2712              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2713              "Expected serial number size %d, got %d\n",
2714              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2715              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2716             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2717              U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2718              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2719              "Unexpected serial number\n");
2720         }
2721         else
2722         {
2723             ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2724              "expected key id size %d, got %d\n",
2725              U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2726             ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2727              U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2728              "unexpected key id\n");
2729         }
2730     }
2731     /* FIXME: check more things */
2732 }
2733
2734 static const BYTE signedWithCertAndCrlComputedHash[] = {
2735 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2736 0x2f };
2737 static BYTE keyIdIssuer[] = {
2738 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2739 0x0a,0x07,0x01,0x04,0x01,0x01 };
2740 static const BYTE publicPrivateKeyPair[] = {
2741 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2742 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2743 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2744 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2745 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2746 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2747 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2748 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2749 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2750 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2751 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2752 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2753 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2754 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2755 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2756 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2757 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2758 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2759 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2760 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2761 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2762 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2763 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2764 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2765 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2766 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2767 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2768 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2769 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2770 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2771 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2772 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2773 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2774 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2775 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2776 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2777 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2778 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2779 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2780 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2781 static const BYTE envelopedMessage[] = {
2782 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2783 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2784 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2785 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2786 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2787 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2788 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2789 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2790 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2791 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2792 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2793 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2794 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2795 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2796 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2797 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2798 0x04,0x5f,0x80,0xf2,0x17 };
2799 static const BYTE envelopedBareMessage[] = {
2800 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2801 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2802 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2803 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2804 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2805 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2806 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2807 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2808 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2809 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2810 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2811 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2812 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2813 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2814 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2815 0x2d,0xa3,0x6e };
2816 static const BYTE envelopedMessageWith3Recps[] = {
2817 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2818 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2819 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2820 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2821 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2822 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2823 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2824 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2825 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2826 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2827 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2828 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2829 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2830 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2831 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2832 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2833 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2834 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2835 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2836 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2837 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2838 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2839 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2840 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2841 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2842 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2843 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2844 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2845 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2846 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2847 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2848 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2849 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2850 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2851 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2852 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2853 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2854 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2855 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2856 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2857 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2858 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2859 static const BYTE serialNumber[] = {
2860 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2861 0x1c };
2862 static const BYTE issuer[] = {
2863 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2864
2865 static void test_decode_msg_get_param(void)
2866 {
2867     HCRYPTMSG msg;
2868     HCRYPTPROV hCryptProv;
2869     HCRYPTKEY key = 0;
2870     BOOL ret;
2871     DWORD size = 0, value;
2872     LPBYTE buf;
2873     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2874
2875     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2876     SetLastError(0xdeadbeef);
2877     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2878     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2879      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2880     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2881     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2882      sizeof(msgData));
2883     CryptMsgClose(msg);
2884
2885     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2886     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2887     if (ret)
2888     {
2889         /* Crashes on some Win9x */
2890         check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2891         check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2892         check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2893          emptyHashParam, sizeof(emptyHashParam));
2894     }
2895     CryptMsgClose(msg);
2896     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2897     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2898     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2899      sizeof(msgData));
2900     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2901      sizeof(hashParam));
2902     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2903      hashParam, sizeof(hashParam));
2904     /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2905      * even though there's only one hash.
2906      */
2907     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2908     ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2909      "CryptMsgGetParam failed: %08x\n", GetLastError());
2910     if (ret)
2911         buf = CryptMemAlloc(size);
2912     else
2913         buf = NULL;
2914     if (buf)
2915     {
2916         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2917         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2918         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2919         CryptMemFree(buf);
2920     }
2921     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2922      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2923     value = CMSG_HASHED_DATA_V0;
2924     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2925      sizeof(value));
2926     CryptMsgClose(msg);
2927
2928     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2929     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2930     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2931     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2932      sizeof(msgData));
2933     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2934      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2935     size = sizeof(value);
2936     value = 2112;
2937     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2938     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2939     ok(value == 1, "Expected 1 signer, got %d\n", value);
2940     size = 0;
2941     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2942     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2943      "CryptMsgGetParam failed: %08x\n", GetLastError());
2944     if (ret)
2945         buf = CryptMemAlloc(size);
2946     else
2947         buf = NULL;
2948     if (buf)
2949     {
2950         CMSG_SIGNER_INFO signer = { 0 };
2951
2952         signer.dwVersion = 1;
2953         signer.Issuer.cbData = sizeof(encodedCommonName);
2954         signer.Issuer.pbData = encodedCommonName;
2955         signer.SerialNumber.cbData = sizeof(serialNum);
2956         signer.SerialNumber.pbData = serialNum;
2957         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2958         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2959         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2960         CryptMemFree(buf);
2961     }
2962     /* Getting the CMS signer info of a PKCS7 message is possible. */
2963     size = 0;
2964     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2965     ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2966      "CryptMsgGetParam failed: %08x\n", GetLastError());
2967     if (ret)
2968         buf = CryptMemAlloc(size);
2969     else
2970         buf = NULL;
2971     if (buf)
2972     {
2973         CMSG_CMS_SIGNER_INFO signer = { 0 };
2974
2975         signer.dwVersion = 1;
2976         signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2977         U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2978          sizeof(encodedCommonName);
2979         U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2980         U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2981          sizeof(serialNum);
2982         U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2983         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2984         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2985         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2986         CryptMemFree(buf);
2987     }
2988     /* index is ignored when getting signer count */
2989     size = sizeof(value);
2990     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2991     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2992     ok(value == 1, "Expected 1 signer, got %d\n", value);
2993     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2994     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2995     ok(value == 0, "Expected 0 certs, got %d\n", value);
2996     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2997     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2998     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2999     CryptMsgClose(msg);
3000     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3001      NULL);
3002     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
3003      sizeof(signedWithCertAndCrlBareContent), TRUE);
3004     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3005     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
3006     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3007     ok(value == 1, "Expected 1 cert, got %d\n", value);
3008     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3009     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
3010     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3011     ok(value == 1, "Expected 1 CRL, got %d\n", value);
3012     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3013     check_param("signed with cert and CRL computed hash", msg,
3014      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
3015      sizeof(signedWithCertAndCrlComputedHash));
3016     CryptMsgClose(msg);
3017
3018     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3019     ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
3020      sizeof(signedKeyIdEmptyContent), TRUE);
3021     if (!ret && GetLastError() == OSS_DATA_ERROR)
3022     {
3023         CryptMsgClose(msg);
3024         win_skip("Subsequent tests crash on some Win9x\n");
3025         return;
3026     }
3027     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3028     size = sizeof(value);
3029     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
3030     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3031     ok(value == 1, "Expected 1 signer, got %d\n", value);
3032     /* Getting the regular (non-CMS) signer info from a CMS message is also
3033      * possible..
3034      */
3035     size = 0;
3036     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
3037     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3038     if (ret)
3039         buf = CryptMemAlloc(size);
3040     else
3041         buf = NULL;
3042     if (buf)
3043     {
3044         CMSG_SIGNER_INFO signer;
3045         BYTE zero = 0;
3046
3047         /* and here's the little oddity:  for a CMS message using the key id
3048          * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3049          * a signer with a zero (not empty) serial number, and whose issuer is
3050          * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3051          * and value of the key id.
3052          */
3053         signer.dwVersion = CMSG_SIGNED_DATA_V3;
3054         signer.Issuer.cbData = sizeof(keyIdIssuer);
3055         signer.Issuer.pbData = keyIdIssuer;
3056         signer.SerialNumber.cbData = 1;
3057         signer.SerialNumber.pbData = &zero;
3058         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
3059         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
3060         CryptMemFree(buf);
3061     }
3062     size = 0;
3063     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
3064     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3065     if (ret)
3066         buf = CryptMemAlloc(size);
3067     else
3068         buf = NULL;
3069     if (buf)
3070     {
3071         CMSG_CMS_SIGNER_INFO signer = { 0 };
3072
3073         signer.dwVersion = CMSG_SIGNED_DATA_V3;
3074         signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
3075         U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3076         U(signer.SignerId).KeyId.pbData = serialNum;
3077         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3078         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
3079         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
3080         CryptMemFree(buf);
3081     }
3082     CryptMsgClose(msg);
3083
3084     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3085      NULL);
3086     CryptMsgUpdate(msg, envelopedEmptyBareContent,
3087      sizeof(envelopedEmptyBareContent), TRUE);
3088     todo_wine
3089     check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3090      0);
3091     CryptMsgClose(msg);
3092
3093     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3094     CryptMsgUpdate(msg, envelopedEmptyContent, sizeof(envelopedEmptyContent),
3095      TRUE);
3096     todo_wine
3097     check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3098     CryptMsgClose(msg);
3099
3100     pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3101      CRYPT_VERIFYCONTEXT);
3102     SetLastError(0xdeadbeef);
3103     ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3104      sizeof(publicPrivateKeyPair), 0, 0, &key);
3105     ok(ret ||
3106      broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3107      "CryptImportKey failed: %08x\n", GetLastError());
3108
3109     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3110     CryptMsgUpdate(msg, envelopedMessage, sizeof(envelopedMessage), TRUE);
3111     todo_wine
3112     check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3113      envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3114     if (key)
3115     {
3116         decryptPara.hCryptProv = hCryptProv;
3117         SetLastError(0xdeadbeef);
3118         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3119         todo_wine
3120         ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3121         decryptPara.hCryptProv = 0;
3122         SetLastError(0xdeadbeef);
3123         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3124         todo_wine
3125         ok(!ret && GetLastError() == CRYPT_E_ALREADY_DECRYPTED,
3126          "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3127         todo_wine
3128         check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3129          sizeof(msgData));
3130     }
3131     else
3132         win_skip("failed to import a key, skipping tests\n");
3133     CryptMsgClose(msg);
3134
3135     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3136      NULL);
3137     CryptMsgUpdate(msg, envelopedBareMessage, sizeof(envelopedBareMessage),
3138      TRUE);
3139     todo_wine
3140     check_param("enveloped bare message before decrypting", msg,
3141      CMSG_CONTENT_PARAM, envelopedBareMessage +
3142      sizeof(envelopedBareMessage) - 4, 4);
3143     if (key)
3144     {
3145         decryptPara.hCryptProv = hCryptProv;
3146         SetLastError(0xdeadbeef);
3147         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3148         todo_wine
3149         ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3150         todo_wine
3151         check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3152          sizeof(msgData));
3153     }
3154     else
3155         win_skip("failed to import a key, skipping tests\n");
3156     CryptMsgClose(msg);
3157
3158     if (key)
3159         CryptDestroyKey(key);
3160     CryptReleaseContext(hCryptProv, 0);
3161
3162     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3163     CryptMsgUpdate(msg, envelopedMessageWith3Recps,
3164      sizeof(envelopedMessageWith3Recps), TRUE);
3165     value = 3;
3166     todo_wine
3167     check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3168      (const BYTE *)&value, sizeof(value));
3169     size = 0;
3170     SetLastError(0xdeadbeef);
3171     ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 3, NULL, &size);
3172     todo_wine
3173     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3174      "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3175     size = 0;
3176     SetLastError(0xdeadbeef);
3177     ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, NULL, &size);
3178     todo_wine
3179     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3180     todo_wine
3181     ok(size >= 142, "unexpected size: %u\n", size);
3182     if (ret)
3183         buf = CryptMemAlloc(size);
3184     else
3185         buf = NULL;
3186     if (buf)
3187     {
3188         CERT_INFO *certInfo = (CERT_INFO *)buf;
3189
3190         SetLastError(0xdeadbeef);
3191         ret = CryptMsgGetParam(msg, CMSG_RECIPIENT_INFO_PARAM, 2, buf, &size);
3192         todo_wine
3193         ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3194         todo_wine
3195         ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3196          "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3197         todo_wine
3198         ok(!memcmp(certInfo->SerialNumber.pbData, serialNumber,
3199          sizeof(serialNumber)), "unexpected serial number\n");
3200         todo_wine
3201         ok(certInfo->Issuer.cbData == sizeof(issuer),
3202          "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3203         todo_wine
3204         ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3205          "unexpected issuer\n");
3206         CryptMemFree(buf);
3207     }
3208     CryptMsgClose(msg);
3209 }
3210
3211 static void test_decode_msg(void)
3212 {
3213     test_decode_msg_update();
3214     test_decode_msg_get_param();
3215 }
3216
3217 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3218 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3219 static BYTE encodedPubKey[] = {
3220 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3221 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3222 0x0d,0x0e,0x0f };
3223 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3224 static BYTE mod_encoded[] = {
3225  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3226  0x01,0x00,0x01 };
3227
3228 static void test_msg_control(void)
3229 {
3230     static char oid_rsa_rsa[] = szOID_RSA_RSA;
3231     BOOL ret;
3232     HCRYPTMSG msg;
3233     DWORD i;
3234     CERT_INFO certInfo = { 0 };
3235     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3236     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3237     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3238
3239     /* Crashes
3240     ret = CryptMsgControl(NULL, 0, 0, NULL);
3241     */
3242
3243     /* Data encode messages don't allow any sort of control.. */
3244     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
3245      NULL);
3246     /* either with no prior update.. */
3247     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3248     {
3249         SetLastError(0xdeadbeef);
3250         ret = CryptMsgControl(msg, 0, i, NULL);
3251         ok(!ret && GetLastError() == E_INVALIDARG,
3252          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3253     }
3254     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3255     /* or after an update. */
3256     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3257     {
3258         SetLastError(0xdeadbeef);
3259         ret = CryptMsgControl(msg, 0, i, NULL);
3260         ok(!ret && GetLastError() == E_INVALIDARG,
3261          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3262     }
3263     CryptMsgClose(msg);
3264
3265     /* Hash encode messages don't allow any sort of control.. */
3266     hashInfo.cbSize = sizeof(hashInfo);
3267     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
3268     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
3269      NULL, NULL);
3270     /* either with no prior update.. */
3271     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3272     {
3273         SetLastError(0xdeadbeef);
3274         ret = CryptMsgControl(msg, 0, i, NULL);
3275         ok(!ret && GetLastError() == E_INVALIDARG,
3276          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3277     }
3278     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3279     /* or after an update. */
3280     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3281     {
3282         SetLastError(0xdeadbeef);
3283         ret = CryptMsgControl(msg, 0, i, NULL);
3284         ok(!ret && GetLastError() == E_INVALIDARG,
3285          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3286     }
3287     CryptMsgClose(msg);
3288
3289     /* Signed encode messages likewise don't allow any sort of control.. */
3290     signInfo.cbSize = sizeof(signInfo);
3291     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
3292      NULL, NULL);
3293     /* either before an update.. */
3294     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3295     {
3296         SetLastError(0xdeadbeef);
3297         ret = CryptMsgControl(msg, 0, i, NULL);
3298         ok(!ret && GetLastError() == E_INVALIDARG,
3299          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3300     }
3301     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
3302     /* or after an update. */
3303     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3304     {
3305         SetLastError(0xdeadbeef);
3306         ret = CryptMsgControl(msg, 0, i, NULL);
3307         ok(!ret && GetLastError() == E_INVALIDARG,
3308          "Expected E_INVALIDARG, got %08x\n", GetLastError());
3309     }
3310     CryptMsgClose(msg);
3311
3312     /* Decode messages behave a bit differently. */
3313     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3314     /* Bad control type */
3315     SetLastError(0xdeadbeef);
3316     ret = CryptMsgControl(msg, 0, 0, NULL);
3317     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3318      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3319     SetLastError(0xdeadbeef);
3320     ret = CryptMsgControl(msg, 1, 0, NULL);
3321     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
3322      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
3323     /* Can't verify the hash of an indeterminate-type message */
3324     SetLastError(0xdeadbeef);
3325     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3326     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3327      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3328     /* Crashes
3329     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
3330      */
3331     /* Can't decrypt an indeterminate-type message */
3332     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3333     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3334      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3335     CryptMsgClose(msg);
3336
3337     if (!old_crypt32)
3338     {
3339         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3340          NULL);
3341         /* Can't verify the hash of an empty message */
3342         SetLastError(0xdeadbeef);
3343         /* Crashes on some Win9x */
3344         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3345         todo_wine
3346         ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3347          "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3348         /* Crashes
3349         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3350          */
3351         /* Can't verify the signature of a hash message */
3352         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3353         ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3354          "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3355         CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
3356          TRUE);
3357         /* Oddly enough, this fails, crashes on some Win9x */
3358         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3359         ok(!ret, "Expected failure\n");
3360         CryptMsgClose(msg);
3361     }
3362     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
3363      NULL);
3364     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
3365     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3366     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3367     /* Can't decrypt an indeterminate-type message */
3368     SetLastError(0xdeadbeef);
3369     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3370     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3371      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3372     CryptMsgClose(msg);
3373
3374     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3375      NULL, NULL);
3376     /* Can't verify the hash of a detached message before it's been updated. */
3377     SetLastError(0xdeadbeef);
3378     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3379     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3380      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3381     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3382      TRUE);
3383     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3384     /* Still can't verify the hash of a detached message with the content
3385      * of the detached hash given..
3386      */
3387     SetLastError(0xdeadbeef);
3388     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3389     ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
3390      "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
3391     /* and giving the content of the message after attempting to verify the
3392      * hash fails.
3393      */
3394     SetLastError(0xdeadbeef);
3395     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3396     todo_wine
3397     ok(!ret &&
3398        (GetLastError() == NTE_BAD_HASH_STATE ||
3399         GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
3400         GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
3401      "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3402      "got %08x\n", GetLastError());
3403     CryptMsgClose(msg);
3404
3405     /* Finally, verifying the hash of a detached message in the correct order:
3406      * 1. Update with the detached hash message
3407      * 2. Update with the content of the message
3408      * 3. Verifying the hash of the message
3409      * succeeds.
3410      */
3411     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3412      NULL, NULL);
3413     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
3414      TRUE);
3415     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3416     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3417     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3418     SetLastError(0xdeadbeef);
3419     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3420     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3421     CryptMsgClose(msg);
3422
3423     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3424      NULL);
3425     /* Can't verify the hash of a signed message */
3426     SetLastError(0xdeadbeef);
3427     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
3428     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3429      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3430     /* Can't decrypt a signed message */
3431     SetLastError(0xdeadbeef);
3432     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3433     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3434      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3435     /* Crash
3436     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
3437     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3438      */
3439     CryptMsgUpdate(msg, signedWithCertBareContent,
3440      sizeof(signedWithCertBareContent), TRUE);
3441     /* With an empty cert info, the signer can't be found in the message (and
3442      * the signature can't be verified.
3443      */
3444     SetLastError(0xdeadbeef);
3445     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3446     ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
3447      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3448      "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
3449      GetLastError());
3450     /* The cert info is expected to have an issuer, serial number, and public
3451      * key info set.
3452      */
3453     certInfo.SerialNumber.cbData = sizeof(serialNum);
3454     certInfo.SerialNumber.pbData = serialNum;
3455     certInfo.Issuer.cbData = sizeof(encodedCommonName);
3456     certInfo.Issuer.pbData = encodedCommonName;
3457     SetLastError(0xdeadbeef);
3458     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3459     ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3460      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3461      "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
3462     CryptMsgClose(msg);
3463     /* This cert has a public key, but it's not in a usable form */
3464     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
3465      NULL);
3466     ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
3467      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
3468     if (ret)
3469     {
3470         /* Crashes on some Win9x */
3471         /* Again, cert info needs to have a public key set */
3472         SetLastError(0xdeadbeef);
3473         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3474         ok(!ret &&
3475          (GetLastError() == CRYPT_E_ASN1_EOD ||
3476           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3477          "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3478         /* The public key is supposed to be in encoded form.. */
3479         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3480         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3481         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
3482         SetLastError(0xdeadbeef);
3483         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3484         ok(!ret &&
3485          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3486           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3487          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3488         /* but not as a X509_PUBLIC_KEY_INFO.. */
3489         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3490         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
3491         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
3492         SetLastError(0xdeadbeef);
3493         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3494         ok(!ret &&
3495          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3496           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3497          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3498         /* This decodes successfully, but it doesn't match any key in the message */
3499         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
3500         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
3501         SetLastError(0xdeadbeef);
3502         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3503         /* In Wine's rsaenh, this fails to decode because the key length is too
3504          * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
3505          * now.
3506          */
3507         todo_wine
3508         ok(!ret &&
3509          (GetLastError() == NTE_BAD_SIGNATURE ||
3510           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3511          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3512     }
3513     CryptMsgClose(msg);
3514     /* A message with no data doesn't have a valid signature */
3515     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3516     ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
3517      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
3518     if (ret)
3519     {
3520         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3521         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
3522         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
3523         SetLastError(0xdeadbeef);
3524         /* Crashes on some Win9x */
3525         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3526         ok(!ret &&
3527          (GetLastError() == NTE_BAD_SIGNATURE ||
3528           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
3529          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
3530     }
3531     CryptMsgClose(msg);
3532     /* Finally, this succeeds */
3533     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3534     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3535      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3536     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3537     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3538      "CryptMsgControl failed: %08x\n", GetLastError());
3539     CryptMsgClose(msg);
3540
3541     /* Test verifying signature of a detached signed message */
3542     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3543      NULL, NULL);
3544     ret = CryptMsgUpdate(msg, detachedSignedContent,
3545      sizeof(detachedSignedContent), TRUE);
3546     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3547     /* Can't verify the sig without having updated the data */
3548     SetLastError(0xdeadbeef);
3549     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3550     ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
3551      GetLastError() == OSS_DATA_ERROR /* Win9x */),
3552      "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
3553      GetLastError());
3554     /* Now that the signature's been checked, can't do the final update */
3555     SetLastError(0xdeadbeef);
3556     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3557     todo_wine
3558     ok((!ret &&
3559      (GetLastError() == NTE_BAD_HASH_STATE ||
3560       GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
3561       GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
3562       broken(ret), /* Win9x */
3563      "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
3564      "got %08x\n", GetLastError());
3565     CryptMsgClose(msg);
3566     /* Updating with the detached portion of the message and the data of the
3567      * the message allows the sig to be verified.
3568      */
3569     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
3570      NULL, NULL);
3571     ret = CryptMsgUpdate(msg, detachedSignedContent,
3572      sizeof(detachedSignedContent), TRUE);
3573     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3574     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3575     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3576     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3577     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3578      "CryptMsgControl failed: %08x\n", GetLastError());
3579     CryptMsgClose(msg);
3580
3581     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3582      NULL);
3583     decryptPara.cbSize = 0;
3584     SetLastError(0xdeadbeef);
3585     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3586     todo_wine
3587     ok(!ret && GetLastError() == E_INVALIDARG,
3588      "expected E_INVALIDARG, got %08x\n", GetLastError());
3589     decryptPara.cbSize = sizeof(decryptPara);
3590     if (!old_crypt32)
3591     {
3592         SetLastError(0xdeadbeef);
3593         ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3594         ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
3595          "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
3596     }
3597     SetLastError(0xdeadbeef);
3598     ret = CryptMsgUpdate(msg, envelopedEmptyBareContent,
3599      sizeof(envelopedEmptyBareContent), TRUE);
3600     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3601     SetLastError(0xdeadbeef);
3602     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3603     todo_wine
3604     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3605      "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3606     CryptMsgClose(msg);
3607
3608     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
3609      NULL);
3610     SetLastError(0xdeadbeef);
3611     ret = CryptMsgUpdate(msg, envelopedBareMessage,
3612      sizeof(envelopedBareMessage), TRUE);
3613     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3614     SetLastError(0xdeadbeef);
3615     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3616     todo_wine
3617     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
3618      "expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
3619     CryptMsgClose(msg);
3620 }
3621
3622 /* win9x has much less parameter checks and will crash on many tests
3623  * this code is from test_signed_msg_update()
3624  */
3625 static BOOL detect_nt(void)
3626 {
3627     BOOL ret;
3628     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3629     CERT_INFO certInfo = { 0 };
3630
3631     if (!pCryptAcquireContextW)
3632         return FALSE;
3633
3634     certInfo.SerialNumber.cbData = sizeof(serialNum);
3635     certInfo.SerialNumber.pbData = serialNum;
3636     certInfo.Issuer.cbData = sizeof(encodedCommonName);
3637     certInfo.Issuer.pbData = encodedCommonName;
3638     signer.pCertInfo = &certInfo;
3639     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3640
3641     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3642                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3643     if (!ret && GetLastError() == NTE_EXISTS) {
3644         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3645                                     PROV_RSA_FULL, 0);
3646     }
3647
3648     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3649
3650     /* cleanup */
3651     CryptReleaseContext(signer.hCryptProv, 0);
3652     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3653                           CRYPT_DELETEKEYSET);
3654
3655     return TRUE;
3656 }
3657
3658 static void test_msg_get_and_verify_signer(void)
3659 {
3660     BOOL ret;
3661     HCRYPTMSG msg;
3662     PCCERT_CONTEXT signer;
3663     DWORD signerIndex;
3664     HCERTSTORE store;
3665
3666     /* Crash */
3667     if (0)
3668     {
3669         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3670         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3671     }
3672
3673     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3674     /* An empty message has no signer */
3675     SetLastError(0xdeadbeef);
3676     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3677     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3678      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3679     /* The signer is cleared on error */
3680     signer = (PCCERT_CONTEXT)0xdeadbeef;
3681     SetLastError(0xdeadbeef);
3682     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3683     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3684      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3685     ok(!signer, "expected signer to be NULL\n");
3686     /* The signer index is also cleared on error */
3687     signerIndex = 0xdeadbeef;
3688     SetLastError(0xdeadbeef);
3689     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3690     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3691      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3692     ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3693     /* An unsigned message (msgData isn't a signed message at all)
3694      * likewise has no signer.
3695      */
3696     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3697     SetLastError(0xdeadbeef);
3698     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3699     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3700      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3701     CryptMsgClose(msg);
3702
3703     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3704     /* A "signed" message created with no signer cert likewise has no signer */
3705     ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3706     if (ret)
3707     {
3708         /* Crashes on most Win9x */
3709         ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3710         ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3711          "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3712     }
3713     CryptMsgClose(msg);
3714
3715     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3716     /* A signed message succeeds, .. */
3717     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3718      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3719     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3720     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3721      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3722     /* the signer index can be retrieved, .. */
3723     signerIndex = 0xdeadbeef;
3724     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3725     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3726      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3727     if (ret)
3728         ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3729     /* as can the signer cert. */
3730     signer = (PCCERT_CONTEXT)0xdeadbeef;
3731     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3732     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3733      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3734     if (ret)
3735         ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3736      "expected a valid signer\n");
3737     if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3738         CertFreeCertificateContext(signer);
3739     /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3740      */
3741     signerIndex = 0xdeadbeef;
3742     SetLastError(0xdeadbeef);
3743     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3744      NULL, &signerIndex);
3745     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3746      "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3747     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3748      * message signer not to be found.
3749      */
3750     SetLastError(0xdeadbeef);
3751     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3752      NULL, NULL);
3753     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3754      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3755      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3756     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3757      * the message signer not to be found.
3758      */
3759     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3760      CERT_STORE_CREATE_NEW_FLAG, NULL);
3761     SetLastError(0xdeadbeef);
3762     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3763      NULL, NULL);
3764     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3765      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3766      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3767     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3768      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3769      CERT_STORE_ADD_ALWAYS, NULL);
3770     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3771      "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3772     /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3773      * the signer succeeds.
3774      */
3775     SetLastError(0xdeadbeef);
3776     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3777      NULL, NULL);
3778     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3779      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3780     CertCloseStore(store, 0);
3781     CryptMsgClose(msg);
3782 }
3783
3784 START_TEST(msg)
3785 {
3786     init_function_pointers();
3787     have_nt = detect_nt();
3788     if (!have_nt)
3789         win_skip("Win9x crashes on some parameter checks\n");
3790
3791     /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3792     if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3793     {
3794         win_skip("Some tests will crash on older crypt32 implementations\n");
3795         old_crypt32 = TRUE;
3796     }
3797
3798     /* Basic parameter checking tests */
3799     test_msg_open_to_encode();
3800     test_msg_open_to_decode();
3801     test_msg_get_param();
3802     test_msg_close();
3803     test_msg_control();
3804
3805     /* Message-type specific tests */
3806     test_data_msg();
3807     test_hash_msg();
3808     test_signed_msg();
3809     test_enveloped_msg();
3810     test_decode_msg();
3811
3812     test_msg_get_and_verify_signer();
3813 }