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