crypt32: Revert 8ed5a777de6c9797a285829e07d7a27b3ed01257.
[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 CRYPT_DATA_BLOB b4 = { 0, NULL };
2035 static const struct update_accum a4 = { 1, &b4 };
2036
2037 static const BYTE bogusOIDContent[] = {
2038 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2039 0x04,0x00 };
2040 static const BYTE bogusHashContent[] = {
2041 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2042 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2043 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2044 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2045 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2046
2047 static void test_decode_msg_update(void)
2048 {
2049     HCRYPTMSG msg;
2050     BOOL ret;
2051     CMSG_STREAM_INFO streamInfo = { 0 };
2052     DWORD i;
2053     struct update_accum accum = { 0, NULL };
2054
2055     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2056     /* Update with a full message in a final update */
2057     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2058     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2059     /* Can't update after a final update */
2060     SetLastError(0xdeadbeef);
2061     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2062     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2063      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2064     CryptMsgClose(msg);
2065
2066     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2067     /* Can't send a non-final update without streaming */
2068     SetLastError(0xdeadbeef);
2069     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2070      FALSE);
2071     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2072      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2073     /* A subsequent final update succeeds */
2074     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
2075     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2076     CryptMsgClose(msg);
2077
2078     if (!old_crypt32)
2079     {
2080         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2081         /* Updating a message that has a NULL stream callback fails */
2082         SetLastError(0xdeadbeef);
2083         /* Crashes on some Win9x */
2084         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2085          FALSE);
2086         todo_wine
2087         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2088          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2089          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2090          GetLastError());
2091         /* Changing the callback pointer after the fact yields the same error (so
2092          * the message must copy the stream info, not just store a pointer to it)
2093          */
2094         streamInfo.pfnStreamOutput = nop_stream_output;
2095         SetLastError(0xdeadbeef);
2096         ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2097          FALSE);
2098         todo_wine
2099         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
2100          GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2101          "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2102          GetLastError());
2103         CryptMsgClose(msg);
2104     }
2105
2106     /* Empty non-final updates are allowed when streaming.. */
2107     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2108     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2109     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2110     /* but final updates aren't when not enough data has been received. */
2111     SetLastError(0xdeadbeef);
2112     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2113     todo_wine
2114     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
2115      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2116     CryptMsgClose(msg);
2117
2118     /* Updating the message byte by byte is legal */
2119     streamInfo.pfnStreamOutput = accumulating_stream_output;
2120     streamInfo.pvArg = &accum;
2121     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2122     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2123         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
2124     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2125     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2126     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2127     CryptMsgClose(msg);
2128     todo_wine
2129     check_updates("byte-by-byte empty content", &a4, &accum);
2130     free_updates(&accum);
2131
2132     /* Decoding bogus content fails in non-streaming mode.. */
2133     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2134     SetLastError(0xdeadbeef);
2135     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2136     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2137      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2138      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2139      GetLastError());
2140     CryptMsgClose(msg);
2141     /* and as the final update in streaming mode.. */
2142     streamInfo.pfnStreamOutput = nop_stream_output;
2143     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2144     SetLastError(0xdeadbeef);
2145     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2146     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2147      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2148      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2149      GetLastError());
2150     CryptMsgClose(msg);
2151     /* and even as a non-final update in streaming mode. */
2152     streamInfo.pfnStreamOutput = nop_stream_output;
2153     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2154     SetLastError(0xdeadbeef);
2155     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2156     todo_wine
2157     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2158      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2159      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2160      GetLastError());
2161     CryptMsgClose(msg);
2162
2163     /* An empty message can be opened with undetermined type.. */
2164     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2165     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2166      TRUE);
2167     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2168     CryptMsgClose(msg);
2169     /* but decoding it as an explicitly typed message fails. */
2170     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2171      NULL);
2172     SetLastError(0xdeadbeef);
2173     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
2174      TRUE);
2175     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2176      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2177      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2178      GetLastError());
2179     CryptMsgClose(msg);
2180     /* On the other hand, decoding the bare content of an empty message fails
2181      * with unspecified type..
2182      */
2183     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2184     SetLastError(0xdeadbeef);
2185     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2186      sizeof(dataEmptyBareContent), TRUE);
2187     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2188      GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2189      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2190      GetLastError());
2191     CryptMsgClose(msg);
2192     /* but succeeds with explicit type. */
2193     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
2194      NULL);
2195     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
2196      sizeof(dataEmptyBareContent), TRUE);
2197     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2198     CryptMsgClose(msg);
2199
2200     /* Decoding valid content with an unsupported OID fails */
2201     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2202     SetLastError(0xdeadbeef);
2203     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
2204     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2205      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2206     CryptMsgClose(msg);
2207
2208     /* Similarly, opening an empty hash with unspecified type succeeds.. */
2209     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2210     SetLastError(0xdeadbeef);
2211     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2212     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2213      "CryptMsgUpdate failed: %08x\n", GetLastError());
2214     CryptMsgClose(msg);
2215     /* while with specified type it fails. */
2216     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2217      NULL);
2218     SetLastError(0xdeadbeef);
2219     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2220     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2221      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2222      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2223      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2224      GetLastError());
2225     CryptMsgClose(msg);
2226     /* On the other hand, decoding the bare content of an empty hash message
2227      * fails with unspecified type..
2228      */
2229     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2230     SetLastError(0xdeadbeef);
2231     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2232      sizeof(hashEmptyBareContent), TRUE);
2233     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2234      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2235      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2236      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2237      GetLastError());
2238     CryptMsgClose(msg);
2239     /* but succeeds with explicit type. */
2240     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2241      NULL);
2242     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
2243      sizeof(hashEmptyBareContent), TRUE);
2244     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2245      "CryptMsgUpdate failed: %x\n", GetLastError());
2246     CryptMsgClose(msg);
2247
2248     /* And again, opening a (non-empty) hash message with unspecified type
2249      * succeeds..
2250      */
2251     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2252     SetLastError(0xdeadbeef);
2253     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2254     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2255     CryptMsgClose(msg);
2256     /* while with specified type it fails.. */
2257     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2258      NULL);
2259     SetLastError(0xdeadbeef);
2260     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2261     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2262      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2263      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2264      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2265      GetLastError());
2266     CryptMsgClose(msg);
2267     /* and decoding the bare content of a non-empty hash message fails with
2268      * unspecified type..
2269      */
2270     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2271     SetLastError(0xdeadbeef);
2272     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2273     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2274      GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2275      GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2276      "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2277      GetLastError());
2278     CryptMsgClose(msg);
2279     /* but succeeds with explicit type. */
2280     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2281      NULL);
2282     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2283     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2284     CryptMsgClose(msg);
2285
2286     /* Opening a (non-empty) hash message with unspecified type and a bogus
2287      * hash value succeeds..
2288      */
2289     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2290     SetLastError(0xdeadbeef);
2291     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
2292     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2293     CryptMsgClose(msg);
2294
2295     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2296     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2297     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2298     CryptMsgClose(msg);
2299     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2300     SetLastError(0xdeadbeef);
2301     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2302      sizeof(signedWithCertAndCrlBareContent), TRUE);
2303     ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2304      GetLastError() == OSS_DATA_ERROR /* Win9x */),
2305      "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2306      GetLastError());
2307     CryptMsgClose(msg);
2308     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2309      NULL);
2310     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2311      sizeof(signedWithCertAndCrlBareContent), TRUE);
2312     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2313     CryptMsgClose(msg);
2314
2315     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2316      NULL, NULL);
2317     /* The first update succeeds.. */
2318     ret = CryptMsgUpdate(msg, detachedSignedContent,
2319      sizeof(detachedSignedContent), TRUE);
2320     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2321     /* as does a second (probably to update the detached portion).. */
2322     ret = CryptMsgUpdate(msg, detachedSignedContent,
2323      sizeof(detachedSignedContent), TRUE);
2324     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2325     /* while a third fails. */
2326     ret = CryptMsgUpdate(msg, detachedSignedContent,
2327      sizeof(detachedSignedContent), TRUE);
2328     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2329      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2330     CryptMsgClose(msg);
2331
2332     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, NULL, &streamInfo);
2333     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2334     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2335     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2336     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2337     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), FALSE);
2338     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2339     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2340     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2341
2342     ret = CryptMsgUpdate(msg, detachedSignedContent, sizeof(detachedSignedContent), TRUE);
2343     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
2344      "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2345     CryptMsgClose(msg);
2346 }
2347
2348 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2349  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2350
2351 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2352  const CMSG_SIGNER_INFO *expected)
2353 {
2354     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2355      expected->dwVersion, got->dwVersion);
2356     ok(got->Issuer.cbData == expected->Issuer.cbData,
2357      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2358      got->Issuer.cbData);
2359     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
2360      "Unexpected issuer\n");
2361     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2362      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2363      got->SerialNumber.cbData);
2364     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
2365      got->SerialNumber.cbData), "Unexpected serial number\n");
2366     /* FIXME: check more things */
2367 }
2368
2369 static void compare_cms_signer_info(const CMSG_CMS_SIGNER_INFO *got,
2370  const CMSG_CMS_SIGNER_INFO *expected)
2371 {
2372     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2373      expected->dwVersion, got->dwVersion);
2374     ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2375      "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2376      got->SignerId.dwIdChoice);
2377     if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2378     {
2379         if (got->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER)
2380         {
2381             ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2382              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2383              "Expected issuer size %d, got %d\n",
2384              U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2385              U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2386             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2387              U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2388              U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2389              "Unexpected issuer\n");
2390             ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2391              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2392              "Expected serial number size %d, got %d\n",
2393              U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2394              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2395             ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2396              U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2397              U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2398              "Unexpected serial number\n");
2399         }
2400         else
2401         {
2402             ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2403              "expected key id size %d, got %d\n",
2404              U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2405             ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2406              U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2407              "unexpected key id\n");
2408         }
2409     }
2410     /* FIXME: check more things */
2411 }
2412
2413 static const BYTE signedWithCertAndCrlComputedHash[] = {
2414 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2415 0x2f };
2416 static BYTE keyIdIssuer[] = {
2417 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2418 0x0a,0x07,0x01,0x04,0x01,0x01 };
2419
2420 static void test_decode_msg_get_param(void)
2421 {
2422     HCRYPTMSG msg;
2423     BOOL ret;
2424     DWORD size = 0, value;
2425     LPBYTE buf;
2426
2427     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2428     SetLastError(0xdeadbeef);
2429     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2430     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2431      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2432     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2433     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2434      sizeof(msgData));
2435     CryptMsgClose(msg);
2436
2437     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2438     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2439     if (ret)
2440     {
2441         /* Crashes on some Win9x */
2442         check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2443         check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2444         check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2445          emptyHashParam, sizeof(emptyHashParam));
2446     }
2447     CryptMsgClose(msg);
2448     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2449     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2450     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2451      sizeof(msgData));
2452     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2453      sizeof(hashParam));
2454     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2455      hashParam, sizeof(hashParam));
2456     /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2457      * even though there's only one hash.
2458      */
2459     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2460     ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2461      "CryptMsgGetParam failed: %08x\n", GetLastError());
2462     if (ret)
2463         buf = CryptMemAlloc(size);
2464     else
2465         buf = NULL;
2466     if (buf)
2467     {
2468         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2469         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2470         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2471         CryptMemFree(buf);
2472     }
2473     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2474      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2475     value = CMSG_HASHED_DATA_V0;
2476     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2477      sizeof(value));
2478     CryptMsgClose(msg);
2479
2480     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2481     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2482     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2483     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2484      sizeof(msgData));
2485     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2486      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2487     size = sizeof(value);
2488     value = 2112;
2489     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2490     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2491     ok(value == 1, "Expected 1 signer, got %d\n", value);
2492     size = 0;
2493     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2494     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2495      "CryptMsgGetParam failed: %08x\n", GetLastError());
2496     if (ret)
2497         buf = CryptMemAlloc(size);
2498     else
2499         buf = NULL;
2500     if (buf)
2501     {
2502         CMSG_SIGNER_INFO signer = { 0 };
2503
2504         signer.dwVersion = 1;
2505         signer.Issuer.cbData = sizeof(encodedCommonName);
2506         signer.Issuer.pbData = encodedCommonName;
2507         signer.SerialNumber.cbData = sizeof(serialNum);
2508         signer.SerialNumber.pbData = serialNum;
2509         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2510         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2511         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2512         CryptMemFree(buf);
2513     }
2514     /* Getting the CMS signer info of a PKCS7 message is possible. */
2515     size = 0;
2516     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2517     ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2518      "CryptMsgGetParam failed: %08x\n", GetLastError());
2519     if (ret)
2520         buf = CryptMemAlloc(size);
2521     else
2522         buf = NULL;
2523     if (buf)
2524     {
2525         CMSG_CMS_SIGNER_INFO signer = { 0 };
2526
2527         signer.dwVersion = 1;
2528         signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
2529         U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2530          sizeof(encodedCommonName);
2531         U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2532         U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2533          sizeof(serialNum);
2534         U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2535         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2536         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2537         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2538         CryptMemFree(buf);
2539     }
2540     /* index is ignored when getting signer count */
2541     size = sizeof(value);
2542     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2543     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2544     ok(value == 1, "Expected 1 signer, got %d\n", value);
2545     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2546     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2547     ok(value == 0, "Expected 0 certs, got %d\n", value);
2548     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2549     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2550     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2551     CryptMsgClose(msg);
2552     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2553      NULL);
2554     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2555      sizeof(signedWithCertAndCrlBareContent), TRUE);
2556     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2557     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2558     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2559     ok(value == 1, "Expected 1 cert, got %d\n", value);
2560     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2561     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2562     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2563     ok(value == 1, "Expected 1 CRL, got %d\n", value);
2564     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2565     check_param("signed with cert and CRL computed hash", msg,
2566      CMSG_COMPUTED_HASH_PARAM, signedWithCertAndCrlComputedHash,
2567      sizeof(signedWithCertAndCrlComputedHash));
2568     CryptMsgClose(msg);
2569
2570     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2571     ret = CryptMsgUpdate(msg, signedKeyIdEmptyContent,
2572      sizeof(signedKeyIdEmptyContent), TRUE);
2573     if (!ret && GetLastError() == OSS_DATA_ERROR)
2574     {
2575         /* Subsequent tests crashes on some Win9x, so bail out */
2576         CryptMsgClose(msg);
2577         return;
2578     }
2579     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2580     size = sizeof(value);
2581     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2582     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2583     ok(value == 1, "Expected 1 signer, got %d\n", value);
2584     /* Getting the regular (non-CMS) signer info from a CMS message is also
2585      * possible..
2586      */
2587     size = 0;
2588     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2589     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2590     if (ret)
2591         buf = CryptMemAlloc(size);
2592     else
2593         buf = NULL;
2594     if (buf)
2595     {
2596         CMSG_SIGNER_INFO signer;
2597         BYTE zero = 0;
2598
2599         /* and here's the little oddity:  for a CMS message using the key id
2600          * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
2601          * a signer with a zero (not empty) serial number, and whose issuer is
2602          * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
2603          * and value of the key id.
2604          */
2605         signer.dwVersion = CMSG_SIGNED_DATA_V3;
2606         signer.Issuer.cbData = sizeof(keyIdIssuer);
2607         signer.Issuer.pbData = keyIdIssuer;
2608         signer.SerialNumber.cbData = 1;
2609         signer.SerialNumber.pbData = &zero;
2610         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2611         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2612         CryptMemFree(buf);
2613     }
2614     size = 0;
2615     ret = CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, NULL, &size);
2616     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2617     if (ret)
2618         buf = CryptMemAlloc(size);
2619     else
2620         buf = NULL;
2621     if (buf)
2622     {
2623         CMSG_CMS_SIGNER_INFO signer = { 0 };
2624
2625         signer.dwVersion = CMSG_SIGNED_DATA_V3;
2626         signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2627         U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2628         U(signer.SignerId).KeyId.pbData = serialNum;
2629         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2630         CryptMsgGetParam(msg, CMSG_CMS_SIGNER_INFO_PARAM, 0, buf, &size);
2631         compare_cms_signer_info((CMSG_CMS_SIGNER_INFO *)buf, &signer);
2632         CryptMemFree(buf);
2633     }
2634     CryptMsgClose(msg);
2635 }
2636
2637 static void test_decode_msg(void)
2638 {
2639     test_decode_msg_update();
2640     test_decode_msg_get_param();
2641 }
2642
2643 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2644 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2645 static BYTE encodedPubKey[] = {
2646 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2647 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2648 0x0d,0x0e,0x0f };
2649 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2650 static BYTE mod_encoded[] = {
2651  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2652  0x01,0x00,0x01 };
2653
2654 static void test_msg_control(void)
2655 {
2656     static char oid_rsa_rsa[] = szOID_RSA_RSA;
2657     BOOL ret;
2658     HCRYPTMSG msg;
2659     DWORD i;
2660     CERT_INFO certInfo = { 0 };
2661     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2662     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2663     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2664
2665     /* Crashes
2666     ret = CryptMsgControl(NULL, 0, 0, NULL);
2667     */
2668
2669     /* Data encode messages don't allow any sort of control.. */
2670     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2671      NULL);
2672     /* either with no prior update.. */
2673     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2674     {
2675         SetLastError(0xdeadbeef);
2676         ret = CryptMsgControl(msg, 0, i, NULL);
2677         ok(!ret && GetLastError() == E_INVALIDARG,
2678          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2679     }
2680     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2681     /* or after an update. */
2682     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2683     {
2684         SetLastError(0xdeadbeef);
2685         ret = CryptMsgControl(msg, 0, i, NULL);
2686         ok(!ret && GetLastError() == E_INVALIDARG,
2687          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2688     }
2689     CryptMsgClose(msg);
2690
2691     /* Hash encode messages don't allow any sort of control.. */
2692     hashInfo.cbSize = sizeof(hashInfo);
2693     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2694     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2695      NULL, NULL);
2696     /* either with no prior update.. */
2697     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2698     {
2699         SetLastError(0xdeadbeef);
2700         ret = CryptMsgControl(msg, 0, i, NULL);
2701         ok(!ret && GetLastError() == E_INVALIDARG,
2702          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2703     }
2704     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2705     /* or after an update. */
2706     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2707     {
2708         SetLastError(0xdeadbeef);
2709         ret = CryptMsgControl(msg, 0, i, NULL);
2710         ok(!ret && GetLastError() == E_INVALIDARG,
2711          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2712     }
2713     CryptMsgClose(msg);
2714
2715     /* Signed encode messages likewise don't allow any sort of control.. */
2716     signInfo.cbSize = sizeof(signInfo);
2717     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2718      NULL, NULL);
2719     /* either before an update.. */
2720     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2721     {
2722         SetLastError(0xdeadbeef);
2723         ret = CryptMsgControl(msg, 0, i, NULL);
2724         ok(!ret && GetLastError() == E_INVALIDARG,
2725          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2726     }
2727     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2728     /* or after an update. */
2729     for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
2730     {
2731         SetLastError(0xdeadbeef);
2732         ret = CryptMsgControl(msg, 0, i, NULL);
2733         ok(!ret && GetLastError() == E_INVALIDARG,
2734          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2735     }
2736     CryptMsgClose(msg);
2737
2738     /* Decode messages behave a bit differently. */
2739     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2740     /* Bad control type */
2741     SetLastError(0xdeadbeef);
2742     ret = CryptMsgControl(msg, 0, 0, NULL);
2743     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2744      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2745     SetLastError(0xdeadbeef);
2746     ret = CryptMsgControl(msg, 1, 0, NULL);
2747     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2748      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2749     /* Can't verify the hash of an indeterminate-type message */
2750     SetLastError(0xdeadbeef);
2751     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2752     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2753      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2754     /* Crashes
2755     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2756      */
2757     /* Can't decrypt an indeterminate-type message */
2758     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2759     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2760      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2761     CryptMsgClose(msg);
2762
2763     if (!old_crypt32)
2764     {
2765         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2766          NULL);
2767         /* Can't verify the hash of an empty message */
2768         SetLastError(0xdeadbeef);
2769         /* Crashes on some Win9x */
2770         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2771         todo_wine
2772         ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2773          "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2774         /* Crashes
2775         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2776          */
2777         /* Can't verify the signature of a hash message */
2778         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2779         ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2780          "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2781         CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2782          TRUE);
2783         /* Oddly enough, this fails, crashes on some Win9x */
2784         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2785         ok(!ret, "Expected failure\n");
2786         CryptMsgClose(msg);
2787     }
2788     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2789      NULL);
2790     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2791     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2792     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2793     /* Can't decrypt an indeterminate-type message */
2794     SetLastError(0xdeadbeef);
2795     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2796     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2797      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2798     CryptMsgClose(msg);
2799
2800     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2801      NULL, NULL);
2802     /* Can't verify the hash of a detached message before it's been updated. */
2803     SetLastError(0xdeadbeef);
2804     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2805     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2806      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2807     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2808      TRUE);
2809     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2810     /* Still can't verify the hash of a detached message with the content
2811      * of the detached hash given..
2812      */
2813     SetLastError(0xdeadbeef);
2814     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2815     ok(!ret && GetLastError() == CRYPT_E_HASH_VALUE,
2816      "Expected CRYPT_E_HASH_VALUE, got %08x\n", GetLastError());
2817     /* and giving the content of the message after attempting to verify the
2818      * hash fails.
2819      */
2820     SetLastError(0xdeadbeef);
2821     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2822     todo_wine
2823     ok(!ret &&
2824        (GetLastError() == NTE_BAD_HASH_STATE ||
2825         GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
2826         GetLastError() == CRYPT_E_MSG_ERROR), /* Vista */
2827      "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2828      "got %08x\n", GetLastError());
2829     CryptMsgClose(msg);
2830
2831     /* Finally, verifying the hash of a detached message in the correct order:
2832      * 1. Update with the detached hash message
2833      * 2. Update with the content of the message
2834      * 3. Verifying the hash of the message
2835      * succeeds.
2836      */
2837     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2838      NULL, NULL);
2839     ret = CryptMsgUpdate(msg, detachedHashContent, sizeof(detachedHashContent),
2840      TRUE);
2841     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2842     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2843     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2844     SetLastError(0xdeadbeef);
2845     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2846     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2847     CryptMsgClose(msg);
2848
2849     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2850      NULL);
2851     /* Can't verify the hash of a signed message */
2852     SetLastError(0xdeadbeef);
2853     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2854     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2855      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2856     /* Can't decrypt a signed message */
2857     SetLastError(0xdeadbeef);
2858     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2859     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2860      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2861     /* Crash
2862     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2863     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2864      */
2865     CryptMsgUpdate(msg, signedWithCertBareContent,
2866      sizeof(signedWithCertBareContent), TRUE);
2867     /* With an empty cert info, the signer can't be found in the message (and
2868      * the signature can't be verified.
2869      */
2870     SetLastError(0xdeadbeef);
2871     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2872     ok(!ret && (GetLastError() == CRYPT_E_SIGNER_NOT_FOUND ||
2873      GetLastError() == OSS_DATA_ERROR /* Win9x */),
2874      "Expected CRYPT_E_SIGNER_NOT_FOUND or OSS_DATA_ERROR, got %08x\n",
2875      GetLastError());
2876     /* The cert info is expected to have an issuer, serial number, and public
2877      * key info set.
2878      */
2879     certInfo.SerialNumber.cbData = sizeof(serialNum);
2880     certInfo.SerialNumber.pbData = serialNum;
2881     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2882     certInfo.Issuer.pbData = encodedCommonName;
2883     SetLastError(0xdeadbeef);
2884     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2885     ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2886      GetLastError() == OSS_DATA_ERROR /* Win9x */),
2887      "Expected CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, got %08x\n", GetLastError());
2888     CryptMsgClose(msg);
2889     /* This cert has a public key, but it's not in a usable form */
2890     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2891      NULL);
2892     ret = CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2893      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2894     if (ret)
2895     {
2896         /* Crashes on some Win9x */
2897         /* Again, cert info needs to have a public key set */
2898         SetLastError(0xdeadbeef);
2899         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2900         ok(!ret &&
2901          (GetLastError() == CRYPT_E_ASN1_EOD ||
2902           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2903          "Expected CRYPT_E_ASN1_EOD or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2904         /* The public key is supposed to be in encoded form.. */
2905         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2906         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2907         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2908         SetLastError(0xdeadbeef);
2909         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2910         ok(!ret &&
2911          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2912           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2913          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2914         /* but not as a X509_PUBLIC_KEY_INFO.. */
2915         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2916         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2917         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2918         SetLastError(0xdeadbeef);
2919         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2920         ok(!ret &&
2921          (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2922           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2923          "Expected CRYPT_E_ASN1_BADTAG or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2924         /* This decodes successfully, but it doesn't match any key in the message */
2925         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2926         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2927         SetLastError(0xdeadbeef);
2928         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2929         /* In Wine's rsaenh, this fails to decode because the key length is too
2930          * small.  Not sure if that's a bug in rsaenh, so leaving todo_wine for
2931          * now.
2932          */
2933         todo_wine
2934         ok(!ret &&
2935          (GetLastError() == NTE_BAD_SIGNATURE ||
2936           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2937          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2938     }
2939     CryptMsgClose(msg);
2940     /* A message with no data doesn't have a valid signature */
2941     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2942     ret = CryptMsgUpdate(msg, signedWithCertWithValidPubKeyEmptyContent,
2943      sizeof(signedWithCertWithValidPubKeyEmptyContent), TRUE);
2944     if (ret)
2945     {
2946         certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2947         certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(pubKey);
2948         certInfo.SubjectPublicKeyInfo.PublicKey.pbData = pubKey;
2949         SetLastError(0xdeadbeef);
2950         /* Crashes on some Win9x */
2951         ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2952         ok(!ret &&
2953          (GetLastError() == NTE_BAD_SIGNATURE ||
2954           GetLastError() == TRUST_E_NOSIGNATURE /* Vista */),
2955          "Expected NTE_BAD_SIGNATURE or TRUST_E_NOSIGNATURE, got %08x\n", GetLastError());
2956     }
2957     CryptMsgClose(msg);
2958     /* Finally, this succeeds */
2959     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2960     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
2961      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
2962     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2963     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2964      "CryptMsgControl failed: %08x\n", GetLastError());
2965     CryptMsgClose(msg);
2966
2967     /* Test verifying signature of a detached signed message */
2968     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2969      NULL, NULL);
2970     ret = CryptMsgUpdate(msg, detachedSignedContent,
2971      sizeof(detachedSignedContent), TRUE);
2972     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2973     /* Can't verify the sig without having updated the data */
2974     SetLastError(0xdeadbeef);
2975     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2976     ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE ||
2977      GetLastError() == OSS_DATA_ERROR /* Win9x */),
2978      "expected NTE_BAD_SIGNATURE or OSS_DATA_ERROR, got %08x\n",
2979      GetLastError());
2980     /* Now that the signature's been checked, can't do the final update */
2981     SetLastError(0xdeadbeef);
2982     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2983     todo_wine
2984     ok((!ret &&
2985      (GetLastError() == NTE_BAD_HASH_STATE ||
2986       GetLastError() == NTE_BAD_ALGID ||    /* Win9x */
2987       GetLastError() == CRYPT_E_MSG_ERROR)) || /* Vista */
2988       broken(ret), /* Win9x */
2989      "expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, "
2990      "got %08x\n", GetLastError());
2991     CryptMsgClose(msg);
2992     /* Updating with the detached portion of the message and the data of the
2993      * the message allows the sig to be verified.
2994      */
2995     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0,
2996      NULL, NULL);
2997     ret = CryptMsgUpdate(msg, detachedSignedContent,
2998      sizeof(detachedSignedContent), TRUE);
2999     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3000     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3001     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3002     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
3003     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3004      "CryptMsgControl failed: %08x\n", GetLastError());
3005     CryptMsgClose(msg);
3006 }
3007
3008 /* win9x has much less parameter checks and will crash on many tests
3009  * this code is from test_signed_msg_update()
3010  */
3011 static BOOL detect_nt(void)
3012 {
3013     BOOL ret;
3014     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
3015     CERT_INFO certInfo = { 0 };
3016
3017     if (!pCryptAcquireContextW)
3018         return FALSE;
3019
3020     certInfo.SerialNumber.cbData = sizeof(serialNum);
3021     certInfo.SerialNumber.pbData = serialNum;
3022     certInfo.Issuer.cbData = sizeof(encodedCommonName);
3023     certInfo.Issuer.pbData = encodedCommonName;
3024     signer.pCertInfo = &certInfo;
3025     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
3026
3027     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3028                                 PROV_RSA_FULL, CRYPT_NEWKEYSET);
3029     if (!ret && GetLastError() == NTE_EXISTS) {
3030         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
3031                                     PROV_RSA_FULL, 0);
3032     }
3033
3034     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) return FALSE;
3035
3036     /* cleanup */
3037     CryptReleaseContext(signer.hCryptProv, 0);
3038     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
3039                           CRYPT_DELETEKEYSET);
3040
3041     return TRUE;
3042 }
3043
3044 static void test_msg_get_and_verify_signer(void)
3045 {
3046     BOOL ret;
3047     HCRYPTMSG msg;
3048     PCCERT_CONTEXT signer;
3049     DWORD signerIndex;
3050     HCERTSTORE store;
3051
3052     /* Crash */
3053     if (0)
3054     {
3055         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, NULL);
3056         ret = CryptMsgGetAndVerifySigner(NULL, 0, NULL, 0, NULL, &signerIndex);
3057     }
3058
3059     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3060     /* An empty message has no signer */
3061     SetLastError(0xdeadbeef);
3062     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3063     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3064      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3065     /* The signer is cleared on error */
3066     signer = (PCCERT_CONTEXT)0xdeadbeef;
3067     SetLastError(0xdeadbeef);
3068     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3069     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3070      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3071     ok(!signer, "expected signer to be NULL\n");
3072     /* The signer index is also cleared on error */
3073     signerIndex = 0xdeadbeef;
3074     SetLastError(0xdeadbeef);
3075     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3076     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3077      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3078     ok(!signerIndex, "expected 0, got %d\n", signerIndex);
3079     /* An unsigned message (msgData isn't a signed message at all)
3080      * likewise has no signer.
3081      */
3082     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
3083     SetLastError(0xdeadbeef);
3084     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3085     ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3086      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3087     CryptMsgClose(msg);
3088
3089     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3090     /* A "signed" message created with no signer cert likewise has no signer */
3091     ret = CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
3092     if (ret)
3093     {
3094         /* Crashes on most Win9x */
3095         ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3096         ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
3097          "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3098     }
3099     CryptMsgClose(msg);
3100
3101     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
3102     /* A signed message succeeds, .. */
3103     CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
3104      sizeof(signedWithCertWithValidPubKeyContent), TRUE);
3105     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
3106     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3107      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3108     /* the signer index can be retrieved, .. */
3109     signerIndex = 0xdeadbeef;
3110     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
3111     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3112      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3113     if (ret)
3114         ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
3115     /* as can the signer cert. */
3116     signer = (PCCERT_CONTEXT)0xdeadbeef;
3117     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
3118     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3119      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3120     if (ret)
3121         ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
3122      "expected a valid signer\n");
3123     if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
3124         CertFreeCertificateContext(signer);
3125     /* Specifying CMSG_USE_SIGNER_INDEX_FLAG and an invalid signer index fails
3126      */
3127     signerIndex = 0xdeadbeef;
3128     SetLastError(0xdeadbeef);
3129     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
3130      NULL, &signerIndex);
3131     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
3132      "expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
3133     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
3134      * message signer not to be found.
3135      */
3136     SetLastError(0xdeadbeef);
3137     ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
3138      NULL, NULL);
3139     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3140      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3141      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3142     /* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
3143      * the message signer not to be found.
3144      */
3145     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
3146      CERT_STORE_CREATE_NEW_FLAG, NULL);
3147     SetLastError(0xdeadbeef);
3148     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3149      NULL, NULL);
3150     ok(!ret && (GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER ||
3151      broken(GetLastError() == OSS_DATA_ERROR /* Win9x */)),
3152      "expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
3153     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
3154      v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
3155      CERT_STORE_ADD_ALWAYS, NULL);
3156     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win98 */),
3157      "CertAddEncodedCertificateToStore failed: 0x%08x\n", GetLastError());
3158     /* Specifying CMSG_TRUSTED_SIGNER_FLAG with a cert store that contains
3159      * the signer succeeds.
3160      */
3161     SetLastError(0xdeadbeef);
3162     ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
3163      NULL, NULL);
3164     ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3165      "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
3166     CertCloseStore(store, 0);
3167     CryptMsgClose(msg);
3168 }
3169
3170 START_TEST(msg)
3171 {
3172     init_function_pointers();
3173     have_nt = detect_nt();
3174     if (!have_nt)
3175         win_skip("Win9x crashes on some parameter checks\n");
3176
3177     /* I_CertUpdateStore can be used for verification if crypt32 is new enough */
3178     if (!GetProcAddress(GetModuleHandleA("crypt32.dll"), "I_CertUpdateStore"))
3179     {
3180         win_skip("Some tests will crash on older crypt32 implementations\n");
3181         old_crypt32 = TRUE;
3182     }
3183
3184     /* Basic parameter checking tests */
3185     test_msg_open_to_encode();
3186     test_msg_open_to_decode();
3187     test_msg_get_param();
3188     test_msg_close();
3189     test_msg_control();
3190
3191     /* Message-type specific tests */
3192     test_data_msg();
3193     test_hash_msg();
3194     test_signed_msg();
3195     test_decode_msg();
3196
3197     test_msg_get_and_verify_signer();
3198 }