crypt32: Implement verifying the hash of a decoded hash message.
[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 #include <wincrypt.h>
27
28 #include "wine/test.h"
29
30 static char oid_rsa_md5[] = szOID_RSA_MD5;
31
32 static BOOL (WINAPI * pCryptAcquireContextW)
33                         (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
34
35 static void init_function_pointers(void)
36 {
37     HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
38
39 #define GET_PROC(dll, func) \
40     p ## func = (void *)GetProcAddress(dll, #func); \
41     if(!p ## func) \
42       trace("GetProcAddress(%s) failed\n", #func);
43
44     GET_PROC(hAdvapi32, CryptAcquireContextW)
45
46 #undef GET_PROC
47 }
48
49 static void test_msg_open_to_encode(void)
50 {
51     HCRYPTMSG msg;
52
53     /* Crash
54     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
55      NULL, NULL);
56     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
57      NULL);
58     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
59      NULL);
60      */
61
62     /* Bad encodings */
63     SetLastError(0xdeadbeef);
64     msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
65     ok(!msg && GetLastError() == E_INVALIDARG,
66      "Expected E_INVALIDARG, got %x\n", GetLastError());
67     SetLastError(0xdeadbeef);
68     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
69     ok(!msg && GetLastError() == E_INVALIDARG,
70      "Expected E_INVALIDARG, got %x\n", GetLastError());
71
72     /* Bad message types */
73     SetLastError(0xdeadbeef);
74     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
75     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
76      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
77     SetLastError(0xdeadbeef);
78     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
79      NULL, NULL, NULL);
80     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
81      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
82     SetLastError(0xdeadbeef);
83     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
84      CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
85     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
86      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
87     SetLastError(0xdeadbeef);
88     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
89      NULL, NULL);
90     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
91      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
92 }
93
94 static void test_msg_open_to_decode(void)
95 {
96     HCRYPTMSG msg;
97     CMSG_STREAM_INFO streamInfo = { 0 };
98
99     SetLastError(0xdeadbeef);
100     msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
101     ok(!msg && GetLastError() == E_INVALIDARG,
102      "Expected E_INVALIDARG, got %x\n", GetLastError());
103
104     /* Bad encodings */
105     SetLastError(0xdeadbeef);
106     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
107     ok(!msg && GetLastError() == E_INVALIDARG,
108      "Expected E_INVALIDARG, got %x\n", GetLastError());
109     SetLastError(0xdeadbeef);
110     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
111     ok(!msg && GetLastError() == E_INVALIDARG,
112      "Expected E_INVALIDARG, got %x\n", GetLastError());
113
114     /* The message type can be explicit... */
115     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
116      NULL);
117     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
118     CryptMsgClose(msg);
119     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
120      NULL);
121     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
122     CryptMsgClose(msg);
123     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
124      NULL);
125     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
126     CryptMsgClose(msg);
127     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
128      NULL);
129     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
130     CryptMsgClose(msg);
131     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
132      CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
133     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
134     CryptMsgClose(msg);
135     /* or implicit.. */
136     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
137     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
138     CryptMsgClose(msg);
139     /* or even invalid. */
140     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
141      NULL);
142     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
143     CryptMsgClose(msg);
144     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
145     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
146     CryptMsgClose(msg);
147
148     /* And even though the stream info parameter "must be set to NULL" for
149      * CMSG_HASHED, it's still accepted.
150      */
151     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
152      &streamInfo);
153     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
154     CryptMsgClose(msg);
155 }
156
157 static void test_msg_get_param(void)
158 {
159     BOOL ret;
160     HCRYPTMSG msg;
161     DWORD size, i, value;
162     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
163     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
164
165     /* Crash
166     ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
167     ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
168     ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
169      */
170
171     /* Decoded messages */
172     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
173     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
174     /* For decoded messages, the type is always available */
175     size = 0;
176     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
177     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
178     size = sizeof(value);
179     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
180     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
181     /* For this (empty) message, the type isn't set */
182     ok(value == 0, "Expected type 0, got %d\n", value);
183     CryptMsgClose(msg);
184
185     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
186      NULL);
187     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
188     /* For explicitly typed messages, the type is known. */
189     size = sizeof(value);
190     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
191     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
192     ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
193     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
194     {
195         size = 0;
196         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
197         ok(!ret, "Parameter %d: expected failure\n", i);
198     }
199     CryptMsgClose(msg);
200
201     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
202      NULL);
203     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
204     size = sizeof(value);
205     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
206     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
207     ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
208     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
209     {
210         size = 0;
211         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
212         ok(!ret, "Parameter %d: expected failure\n", i);
213     }
214     CryptMsgClose(msg);
215
216     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
217      NULL);
218     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
219     size = sizeof(value);
220     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
221     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
222     ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
223     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
224     {
225         size = 0;
226         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
227         ok(!ret, "Parameter %d: expected failure\n", i);
228     }
229     CryptMsgClose(msg);
230
231     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
232      NULL);
233     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
234     size = sizeof(value);
235     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
236     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
237     ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
238     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
239     {
240         size = 0;
241         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
242         ok(!ret, "Parameter %d: expected failure\n", i);
243     }
244     CryptMsgClose(msg);
245
246     /* Explicitly typed messages get their types set, even if they're invalid */
247     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
248      NULL);
249     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
250     size = sizeof(value);
251     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
252     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
253     ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
254     CryptMsgClose(msg);
255
256     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
257     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
258     size = sizeof(value);
259     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
260     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
261     ok(value == 1000, "Expected 1000, got %d\n", value);
262     CryptMsgClose(msg);
263 }
264
265 static void test_msg_close(void)
266 {
267     BOOL ret;
268     HCRYPTMSG msg;
269
270     /* NULL succeeds.. */
271     ret = CryptMsgClose(NULL);
272     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
273     /* but an arbitrary pointer crashes. */
274     if (0)
275         ret = CryptMsgClose((HCRYPTMSG)1);
276     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
277      NULL);
278     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
279     ret = CryptMsgClose(msg);
280     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
281 }
282
283 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
284  const BYTE *expected, DWORD expectedSize)
285 {
286     DWORD size;
287     LPBYTE buf;
288     BOOL ret;
289
290     size = 0xdeadbeef;
291     ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
292     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
293     buf = HeapAlloc(GetProcessHeap(), 0, size);
294     ret = CryptMsgGetParam(msg, param, 0, buf, &size);
295     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
296     ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
297      expectedSize, size);
298     if (size == expectedSize && size)
299         ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
300     HeapFree(GetProcessHeap(), 0, buf);
301 }
302
303 static void test_data_msg_open(void)
304 {
305     HCRYPTMSG msg;
306     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
307     CMSG_STREAM_INFO streamInfo = { 0 };
308     char oid[] = "1.2.3";
309
310     /* The data message type takes no additional info */
311     SetLastError(0xdeadbeef);
312     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
313      NULL, NULL);
314     ok(!msg && GetLastError() == E_INVALIDARG,
315      "Expected E_INVALIDARG, got %x\n", GetLastError());
316     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
317      NULL);
318     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
319     CryptMsgClose(msg);
320
321     /* An empty stream info is allowed. */
322     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
323      &streamInfo);
324     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
325     CryptMsgClose(msg);
326
327     /* Passing a bogus inner OID succeeds for a non-streamed message.. */
328     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
329      NULL);
330     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
331     CryptMsgClose(msg);
332     /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
333     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
334      CMSG_DATA, NULL, oid, NULL);
335     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
336     CryptMsgClose(msg);
337     /* and when a stream info is given, even though you're not supposed to be
338      * able to use anything but szOID_RSA_data when streaming is being used.
339      */
340     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
341      CMSG_DATA, NULL, oid, &streamInfo);
342     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
343     CryptMsgClose(msg);
344 }
345
346 static const BYTE msgData[] = { 1, 2, 3, 4 };
347
348 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
349  BOOL final)
350 {
351     return TRUE;
352 }
353
354 static void test_data_msg_update(void)
355 {
356     HCRYPTMSG msg;
357     BOOL ret;
358     CMSG_STREAM_INFO streamInfo = { 0 };
359
360     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
361      NULL);
362     /* Can't update a message that wasn't opened detached with final = FALSE */
363     SetLastError(0xdeadbeef);
364     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
365     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
366      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
367     /* Updating it with final = TRUE succeeds */
368     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
369     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
370     /* Any subsequent update will fail, as the last was final */
371     SetLastError(0xdeadbeef);
372     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
373     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
374      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
375     CryptMsgClose(msg);
376
377     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
378      NULL);
379     /* Can't update a message with no data */
380     SetLastError(0xdeadbeef);
381     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
382     ok(!ret && GetLastError() == E_INVALIDARG,
383      "Expected E_INVALIDARG, got %x\n", GetLastError());
384     /* Curiously, a valid update will now fail as well, presumably because of
385      * the last (invalid, but final) update.
386      */
387     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
388     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
389      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
390     CryptMsgClose(msg);
391
392     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
393      CMSG_DATA, NULL, NULL, NULL);
394     /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
395     SetLastError(0xdeadbeef);
396     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
397     ok(!ret && GetLastError() == E_INVALIDARG,
398      "Expected E_INVALIDARG, got %x\n", GetLastError());
399     SetLastError(0xdeadbeef);
400     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
401     ok(!ret && GetLastError() == E_INVALIDARG,
402      "Expected E_INVALIDARG, got %x\n", GetLastError());
403     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
404     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
405     CryptMsgClose(msg);
406
407     /* Calling update after opening with an empty stream info (with a bogus
408      * output function) yields an error:
409      */
410     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
411      &streamInfo);
412     SetLastError(0xdeadbeef);
413     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
414     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
415      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
416     CryptMsgClose(msg);
417     /* Calling update with a valid output function succeeds, even if the data
418      * exceeds the size specified in the stream info.
419      */
420     streamInfo.pfnStreamOutput = nop_stream_output;
421     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
422      &streamInfo);
423     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
424     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
425     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
426     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
427     CryptMsgClose(msg);
428 }
429
430 static void test_data_msg_get_param(void)
431 {
432     HCRYPTMSG msg;
433     DWORD size;
434     BOOL ret;
435     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
436
437     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
438      NULL);
439
440     /* Content and bare content are always gettable when not streaming */
441     size = 0;
442     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
443     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
444     size = 0;
445     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
446     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
447     /* But for this type of message, the signer and hash aren't applicable,
448      * and the type isn't available.
449      */
450     size = 0;
451     SetLastError(0xdeadbeef);
452     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
453     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
454      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
455     SetLastError(0xdeadbeef);
456     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
457     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
458      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
459     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
460     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
461      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
462     CryptMsgClose(msg);
463
464     /* Can't get content or bare content when streaming */
465     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
466      NULL, &streamInfo);
467     SetLastError(0xdeadbeef);
468     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
469     ok(!ret && GetLastError() == E_INVALIDARG,
470      "Expected E_INVALIDARG, got %x\n", GetLastError());
471     SetLastError(0xdeadbeef);
472     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
473     ok(!ret && GetLastError() == E_INVALIDARG,
474      "Expected E_INVALIDARG, got %x\n", GetLastError());
475     CryptMsgClose(msg);
476 }
477
478 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
479 static const BYTE dataEmptyContent[] = {
480 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
481 0x04,0x00 };
482 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
483 static const BYTE dataContent[] = {
484 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
485 0x04,0x04,0x01,0x02,0x03,0x04 };
486
487 struct update_accum
488 {
489     DWORD cUpdates;
490     CRYPT_DATA_BLOB *updates;
491 };
492
493 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
494  DWORD cb, BOOL final)
495 {
496     struct update_accum *accum = (struct update_accum *)pvArg;
497     BOOL ret = FALSE;
498
499     if (accum->cUpdates)
500         accum->updates = CryptMemRealloc(accum->updates,
501          (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
502     else
503         accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
504     if (accum->updates)
505     {
506         CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
507
508         blob->pbData = CryptMemAlloc(cb);
509         if (blob->pbData)
510         {
511             memcpy(blob->pbData, pb, cb);
512             blob->cbData = cb;
513             ret = TRUE;
514         }
515         accum->cUpdates++;
516     }
517     return ret;
518 }
519
520 /* The updates of a (bogus) definite-length encoded message */
521 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
522  0x07,0x01,0xa0,0x02,0x04,0x00 };
523 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
524 static CRYPT_DATA_BLOB b1[] = {
525     { sizeof(u1), u1 },
526     { sizeof(u2), u2 },
527     { sizeof(u2), u2 },
528 };
529 static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
530 /* The updates of a definite-length encoded message */
531 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
532  0x07,0x01,0xa0,0x06,0x04,0x04 };
533 static CRYPT_DATA_BLOB b2[] = {
534     { sizeof(u3), u3 },
535     { sizeof(u2), u2 },
536 };
537 static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
538 /* The updates of an indefinite-length encoded message */
539 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
540  0x07,0x01,0xa0,0x80,0x24,0x80 };
541 static BYTE u5[] = { 0x04,0x04 };
542 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
543 static CRYPT_DATA_BLOB b3[] = {
544     { sizeof(u4), u4 },
545     { sizeof(u5), u5 },
546     { sizeof(u2), u2 },
547     { sizeof(u5), u5 },
548     { sizeof(u2), u2 },
549     { sizeof(u6), u6 },
550 };
551 static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
552
553 static void check_updates(LPCSTR header, const struct update_accum *expected,
554  const struct update_accum *got)
555 {
556     DWORD i;
557
558     ok(expected->cUpdates == got->cUpdates,
559      "%s: expected %d updates, got %d\n", header, expected->cUpdates,
560      got->cUpdates);
561     if (expected->cUpdates == got->cUpdates)
562         for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
563         {
564             ok(expected->updates[i].cbData == got->updates[i].cbData,
565              "%s, update %d: expected %d bytes, got %d\n", header, i,
566              expected->updates[i].cbData, got->updates[i].cbData);
567             if (expected->updates[i].cbData && expected->updates[i].cbData ==
568              got->updates[i].cbData)
569                 ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
570                  got->updates[i].cbData), "%s, update %d: unexpected value\n",
571                  header, i);
572         }
573 }
574
575 /* Frees the updates stored in accum */
576 static void free_updates(struct update_accum *accum)
577 {
578     DWORD i;
579
580     for (i = 0; i < accum->cUpdates; i++)
581         CryptMemFree(accum->updates[i].pbData);
582     CryptMemFree(accum->updates);
583     accum->updates = NULL;
584     accum->cUpdates = 0;
585 }
586
587 static void test_data_msg_encoding(void)
588 {
589     HCRYPTMSG msg;
590     BOOL ret;
591     static char oid[] = "1.2.3";
592     struct update_accum accum = { 0, NULL };
593     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
594
595     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
596      NULL);
597     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
598      dataEmptyBareContent, sizeof(dataEmptyBareContent));
599     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
600      sizeof(dataEmptyContent));
601     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
602     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
603     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
604      dataBareContent, sizeof(dataBareContent));
605     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
606      sizeof(dataContent));
607     CryptMsgClose(msg);
608     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
609     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
610      CMSG_DATA, NULL, NULL, NULL);
611     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
612      dataEmptyBareContent, sizeof(dataEmptyBareContent));
613     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
614      sizeof(dataEmptyContent));
615     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
616     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
617     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
618      dataBareContent, sizeof(dataBareContent));
619     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
620      sizeof(dataContent));
621     CryptMsgClose(msg);
622     /* The inner OID is apparently ignored */
623     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, oid,
624      NULL);
625     check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
626      dataEmptyBareContent, sizeof(dataEmptyBareContent));
627     check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
628      dataEmptyContent, sizeof(dataEmptyContent));
629     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
630     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
631     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
632      dataBareContent, sizeof(dataBareContent));
633     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
634      sizeof(dataContent));
635     CryptMsgClose(msg);
636     /* A streaming message is DER encoded if the length is not 0xffffffff, but
637      * curiously, updates aren't validated to make sure they don't exceed the
638      * stated length.  (The resulting output will of course fail to decode.)
639      */
640     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
641      NULL, &streamInfo);
642     CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
643     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
644     CryptMsgClose(msg);
645     check_updates("bogus data message with definite length", &a1, &accum);
646     free_updates(&accum);
647     /* A valid definite-length encoding: */
648     streamInfo.cbContent = sizeof(msgData);
649     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
650      NULL, &streamInfo);
651     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
652     CryptMsgClose(msg);
653     check_updates("data message with definite length", &a2, &accum);
654     free_updates(&accum);
655     /* An indefinite-length encoding: */
656     streamInfo.cbContent = 0xffffffff;
657     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL,
658      NULL, &streamInfo);
659     CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
660     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
661     CryptMsgClose(msg);
662     todo_wine
663     check_updates("data message with indefinite length", &a3, &accum);
664     free_updates(&accum);
665 }
666
667 static void test_data_msg(void)
668 {
669     test_data_msg_open();
670     test_data_msg_update();
671     test_data_msg_get_param();
672     test_data_msg_encoding();
673 }
674
675 static void test_hash_msg_open(void)
676 {
677     HCRYPTMSG msg;
678     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
679     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
680
681     SetLastError(0xdeadbeef);
682     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
683      NULL, NULL);
684     ok(!msg && GetLastError() == E_INVALIDARG,
685      "Expected E_INVALIDARG, got %x\n", GetLastError());
686     hashInfo.cbSize = sizeof(hashInfo);
687     SetLastError(0xdeadbeef);
688     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
689      NULL, NULL);
690     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
691      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
692     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
693     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
694      NULL, NULL);
695     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
696     CryptMsgClose(msg);
697     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
698      CMSG_HASHED, &hashInfo, NULL, NULL);
699     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
700     CryptMsgClose(msg);
701     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
702      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
703     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
704     CryptMsgClose(msg);
705 }
706
707 static void test_hash_msg_update(void)
708 {
709     HCRYPTMSG msg;
710     BOOL ret;
711     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
712      { oid_rsa_md5, { 0, NULL } }, NULL };
713     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
714
715     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
716      CMSG_HASHED, &hashInfo, NULL, NULL);
717     /* Detached hashed messages opened in non-streaming mode allow non-final
718      * updates..
719      */
720     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
721     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
722     /* including non-final updates with no data.. */
723     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
724     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
725     /* and final updates with no data. */
726     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
727     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
728     /* But no updates are allowed after the final update. */
729     SetLastError(0xdeadbeef);
730     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
731     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
732      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
733     SetLastError(0xdeadbeef);
734     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
735     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
736      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
737     CryptMsgClose(msg);
738     /* Non-detached messages, in contrast, don't allow non-final updates in
739      * non-streaming mode.
740      */
741     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
742      NULL, NULL);
743     SetLastError(0xdeadbeef);
744     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
745     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
746      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
747     /* Final updates (including empty ones) are allowed. */
748     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
749     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
750     CryptMsgClose(msg);
751     /* And, of course, streaming mode allows non-final updates */
752     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
753      NULL, &streamInfo);
754     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
755     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
756     CryptMsgClose(msg);
757     /* Setting pfnStreamOutput to NULL results in no error.  (In what appears
758      * to be a bug, it isn't actually used - see encoding tests.)
759      */
760     streamInfo.pfnStreamOutput = NULL;
761     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
762      NULL, &streamInfo);
763     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
764     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
765     CryptMsgClose(msg);
766 }
767
768 static const BYTE emptyHashParam[] = {
769 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
770 0x7e };
771
772 static void test_hash_msg_get_param(void)
773 {
774     HCRYPTMSG msg;
775     BOOL ret;
776     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
777      { oid_rsa_md5, { 0, NULL } }, NULL };
778     DWORD size, value;
779     CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
780     BYTE buf[16];
781
782     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
783      NULL, NULL);
784     /* Content and bare content are always gettable for non-streamed messages */
785     size = 0;
786     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
787     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
788     size = 0;
789     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
790     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
791     /* For an encoded hash message, the hash data aren't available */
792     SetLastError(0xdeadbeef);
793     ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
794     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
795      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
796     /* The hash is also available. */
797     size = 0;
798     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
799     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
800     ok(size == sizeof(buf), "Unexpected size %d\n", size);
801     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
802     if (size == sizeof(buf))
803         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
804     /* By getting the hash, further updates are not allowed */
805     SetLastError(0xdeadbeef);
806     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
807     ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
808      "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
809     /* Even after a final update, the hash data aren't available */
810     SetLastError(0xdeadbeef);
811     ret = CryptMsgGetParam(msg, CMSG_HASH_DATA_PARAM, 0, NULL, &size);
812     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
813      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
814     /* The version is also available, and should be zero for this message. */
815     size = 0;
816     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
817     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
818     size = sizeof(value);
819     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
820     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
821     ok(value == 0, "Expected version 0, got %d\n", value);
822     /* As usual, the type isn't available. */
823     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
824     ok(!ret, "Expected failure\n");
825     CryptMsgClose(msg);
826
827     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
828      NULL, &streamInfo);
829     /* Streamed messages don't allow you to get the content or bare content. */
830     SetLastError(0xdeadbeef);
831     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
832     ok(!ret && GetLastError() == E_INVALIDARG,
833      "Expected E_INVALIDARG, got %x\n", GetLastError());
834     SetLastError(0xdeadbeef);
835     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
836     ok(!ret && GetLastError() == E_INVALIDARG,
837      "Expected E_INVALIDARG, got %x\n", GetLastError());
838     /* The hash is still available. */
839     size = 0;
840     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
841     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
842     ok(size == sizeof(buf), "Unexpected size %d\n", size);
843     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, buf, &size);
844     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
845     if (size == sizeof(buf))
846         ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
847     /* After updating the hash, further updates aren't allowed on streamed
848      * messages either.
849      */
850     SetLastError(0xdeadbeef);
851     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
852     ok(!ret && GetLastError() == NTE_BAD_HASH_STATE,
853      "Expected NTE_BAD_HASH_STATE, got %x\n", GetLastError());
854     CryptMsgClose(msg);
855 }
856
857 static const BYTE hashEmptyBareContent[] = {
858 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
859 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
860 static const BYTE hashEmptyContent[] = {
861 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
862 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
863 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
864 static const BYTE hashBareContent[] = {
865 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
866 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
867 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
868 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
869 static const BYTE hashContent[] = {
870 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
871 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
872 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
873 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
874 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
875
876 static const BYTE detachedHashNonFinalBareContent[] = {
877 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
878 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
879 0x07,0x01,0x04,0x00 };
880 static const BYTE detachedHashNonFinalContent[] = {
881 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
882 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
883 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
884 0x07,0x01,0x04,0x00 };
885 static const BYTE detachedHashBareContent[] = {
886 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
887 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
888 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
889 0x9d,0x2a,0x8f,0x26,0x2f };
890 static const BYTE detachedHashContent[] = {
891 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
892 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
893 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
894 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
895 0x9d,0x2a,0x8f,0x26,0x2f };
896
897 static void test_hash_msg_encoding(void)
898 {
899     HCRYPTMSG msg;
900     CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
901     BOOL ret;
902     struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
903     CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
904
905     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
906     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
907      NULL, NULL);
908     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
909      hashEmptyBareContent, sizeof(hashEmptyBareContent));
910     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
911      hashEmptyContent, sizeof(hashEmptyContent));
912     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
913     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
914     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
915      hashBareContent, sizeof(hashBareContent));
916     check_param("hash content", msg, CMSG_CONTENT_PARAM,
917      hashContent, sizeof(hashContent));
918     CryptMsgClose(msg);
919     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
920     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
921      CMSG_HASHED, &hashInfo, NULL, NULL);
922     check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
923      hashEmptyBareContent, sizeof(hashEmptyBareContent));
924     check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
925      hashEmptyContent, sizeof(hashEmptyContent));
926     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
927     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
928     check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
929      hashBareContent, sizeof(hashBareContent));
930     check_param("hash content", msg, CMSG_CONTENT_PARAM,
931      hashContent, sizeof(hashContent));
932     CryptMsgClose(msg);
933     /* Same test, but with CMSG_DETACHED_FLAG set */
934     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
935      CMSG_HASHED, &hashInfo, NULL, NULL);
936     check_param("detached hash empty bare content", msg,
937      CMSG_BARE_CONTENT_PARAM, hashEmptyBareContent,
938      sizeof(hashEmptyBareContent));
939     check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
940      hashEmptyContent, sizeof(hashEmptyContent));
941     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
942     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
943     check_param("detached hash not final bare content", msg,
944      CMSG_BARE_CONTENT_PARAM, detachedHashNonFinalBareContent,
945      sizeof(detachedHashNonFinalBareContent));
946     check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
947      detachedHashNonFinalContent, sizeof(detachedHashNonFinalContent));
948     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
949     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
950     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
951      detachedHashBareContent, sizeof(detachedHashBareContent));
952     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
953      detachedHashContent, sizeof(detachedHashContent));
954     check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
955      detachedHashBareContent, sizeof(detachedHashBareContent));
956     check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
957      detachedHashContent, sizeof(detachedHashContent));
958     CryptMsgClose(msg);
959     /* In what appears to be a bug, streamed updates to hash messages don't
960      * call the output function.
961      */
962     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
963      NULL, &streamInfo);
964     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
965     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
966     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
967     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
968     CryptMsgClose(msg);
969     check_updates("empty hash message", &empty_accum, &accum);
970     free_updates(&accum);
971
972     streamInfo.cbContent = sizeof(msgData);
973     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
974      NULL, &streamInfo);
975     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
976     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
977     CryptMsgClose(msg);
978     check_updates("hash message", &empty_accum, &accum);
979     free_updates(&accum);
980
981     streamInfo.cbContent = sizeof(msgData);
982     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
983      CMSG_HASHED, &hashInfo, NULL, &streamInfo);
984     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
985     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
986     CryptMsgClose(msg);
987     check_updates("detached hash message", &empty_accum, &accum);
988     free_updates(&accum);
989 }
990
991 static void test_hash_msg(void)
992 {
993     test_hash_msg_open();
994     test_hash_msg_update();
995     test_hash_msg_get_param();
996     test_hash_msg_encoding();
997 }
998
999 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1000  'm','p',0 };
1001 static BYTE serialNum[] = { 1 };
1002 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1003  0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1004
1005 static void test_signed_msg_open(void)
1006 {
1007     HCRYPTMSG msg;
1008     BOOL ret;
1009     CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1010     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1011     CERT_INFO certInfo = { 0 };
1012
1013     SetLastError(0xdeadbeef);
1014     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1015      NULL, NULL);
1016     ok(!msg && GetLastError() == E_INVALIDARG,
1017      "Expected E_INVALIDARG, got %x\n", GetLastError());
1018     signInfo.cbSize = sizeof(signInfo);
1019     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1020      NULL, NULL);
1021     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1022     CryptMsgClose(msg);
1023
1024     signInfo.cSigners = 1;
1025     signInfo.rgSigners = &signer;
1026     /* With signer.pCertInfo unset, attempting to open this message this
1027      * crashes.
1028      */
1029     signer.pCertInfo = &certInfo;
1030     /* The cert info must contain a serial number and an issuer. */
1031     SetLastError(0xdeadbeef);
1032     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1033      NULL, NULL);
1034     ok(!msg && GetLastError() == E_INVALIDARG,
1035      "Expected E_INVALIDARG, got %x\n", GetLastError());
1036     certInfo.SerialNumber.cbData = sizeof(serialNum);
1037     certInfo.SerialNumber.pbData = serialNum;
1038     SetLastError(0xdeadbeef);
1039     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1040      NULL, NULL);
1041     ok(!msg && GetLastError() == E_INVALIDARG,
1042      "Expected E_INVALIDARG, got %x\n", GetLastError());
1043     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1044     certInfo.Issuer.pbData = encodedCommonName;
1045     SetLastError(0xdeadbeef);
1046     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1047      NULL, NULL);
1048     ok(!msg && GetLastError() == E_INVALIDARG,
1049      "Expected E_INVALIDARG, got %x\n", GetLastError());
1050
1051     /* The signer's hCryptProv must be set to something.  Whether it's usable
1052      * or not will be checked after the hash algorithm is checked (see next
1053      * test.)
1054      */
1055     signer.hCryptProv = 1;
1056     SetLastError(0xdeadbeef);
1057     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1058      NULL, NULL);
1059     ok(!msg && GetLastError() == CRYPT_E_UNKNOWN_ALGO,
1060      "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1061     /* The signer's hash algorithm must also be set. */
1062     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1063     SetLastError(0xdeadbeef);
1064     /* Crashes in advapi32 in wine, don't do it */
1065     if (0) {
1066         msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED,
1067          &signInfo, NULL, NULL);
1068         ok(!msg && GetLastError() == ERROR_INVALID_PARAMETER,
1069          "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1070     }
1071     /* The signer's hCryptProv must also be valid. */
1072     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1073      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1074     if (!ret && GetLastError() == NTE_EXISTS)
1075         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1076          PROV_RSA_FULL, 0);
1077     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1078     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1079      NULL, NULL);
1080     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1081     CryptMsgClose(msg);
1082
1083     CryptReleaseContext(signer.hCryptProv, 0);
1084     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1085      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1086 }
1087
1088 static const BYTE privKey[] = {
1089  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1090  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1091  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1092  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1093  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1094  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1095  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1096  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1097  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1098  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1099  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1100  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1101  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1102  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1103  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1104  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1105  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1106  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1107  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1108  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1109  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1110  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1111  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1112  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1113
1114 static void test_signed_msg_update(void)
1115 {
1116     HCRYPTMSG msg;
1117     BOOL ret;
1118     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1119     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1120     CERT_INFO certInfo = { 0 };
1121     HCRYPTKEY key;
1122
1123     certInfo.SerialNumber.cbData = sizeof(serialNum);
1124     certInfo.SerialNumber.pbData = serialNum;
1125     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1126     certInfo.Issuer.pbData = encodedCommonName;
1127     signer.pCertInfo = &certInfo;
1128     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1129     signInfo.cSigners = 1;
1130     signInfo.rgSigners = &signer;
1131     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1132      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1133     if (!ret && GetLastError() == NTE_EXISTS)
1134         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1135          PROV_RSA_FULL, 0);
1136     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1137     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1138      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1139     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1140     /* Detached CMSG_SIGNED allows non-final updates. */
1141     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1142     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1143     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1144     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1145     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1146     /* The final update requires a private key in the hCryptProv, in order to
1147      * generate the signature.
1148      */
1149     SetLastError(0xdeadbeef);
1150     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1151     ok(!ret && (GetLastError() == NTE_BAD_KEYSET ||
1152      GetLastError() == NTE_NO_KEY),
1153      "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1154     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1155      0, 0, &key);
1156     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1157     /* The final update should be able to succeed now that a key exists, but
1158      * the previous (invalid) final update prevents it.
1159      */
1160     SetLastError(0xdeadbeef);
1161     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1162     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1163      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1164     CryptMsgClose(msg);
1165
1166     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1167      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1168     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1169     /* Detached CMSG_SIGNED allows non-final updates. */
1170     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1171     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1172     /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1173     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1174     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1175     /* Now that the private key exists, the final update can succeed (even
1176      * with no data.)
1177      */
1178     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1179     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1180     /* But no updates are allowed after the final update. */
1181     SetLastError(0xdeadbeef);
1182     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1183     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1184      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1185     SetLastError(0xdeadbeef);
1186     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1187     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1188      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1189     CryptMsgClose(msg);
1190
1191     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1192      NULL, NULL);
1193     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1194     /* Non-detached messages don't allow non-final updates.. */
1195     SetLastError(0xdeadbeef);
1196     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1197     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1198      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1199     /* but they do allow final ones. */
1200     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1201     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1202     CryptMsgClose(msg);
1203     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1204      NULL, NULL);
1205     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1206     /* They also allow final updates with no data. */
1207     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1208     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1209     CryptMsgClose(msg);
1210
1211     CryptDestroyKey(key);
1212     CryptReleaseContext(signer.hCryptProv, 0);
1213     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1214      CRYPT_DELETEKEYSET);
1215 }
1216
1217 static const BYTE signedEmptyBareContent[] = {
1218 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1219 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1220 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1221 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1222 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1223 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1224 static const BYTE signedEmptyContent[] = {
1225 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1226 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1227 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1228 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1229 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1230 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1231 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1232 static const BYTE detachedSignedBareContent[] = {
1233 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1234 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1235 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1236 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1237 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1238 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1239 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1240 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1241 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1242 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1243 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1244 static const BYTE detachedSignedContent[] = {
1245 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1246 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1247 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1248 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1249 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1250 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1251 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1252 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1253 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1254 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1255 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1256 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1257 static const BYTE signedBareContent[] = {
1258 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1259 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1260 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1261 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1262 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1263 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1264 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1265 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1266 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1267 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1268 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1269 static const BYTE signedContent[] = {
1270 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1271 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1272 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1273 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1274 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1275 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1276 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1277 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1278 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1279 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1280 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1281 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1282 0x0d };
1283 static const BYTE signedHash[] = {
1284 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1285 0x2f };
1286 static const BYTE signedEncodedSigner[] = {
1287 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1288 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1289 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1290 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1291 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1292 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1293 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1294 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1295 static const BYTE signedWithAuthAttrsBareContent[] = {
1296 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1297 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1298 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1299 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1300 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1301 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1302 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1303 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1304 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1305 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1306 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1307 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1308 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1309 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1310 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1311 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1312 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1313 0xff,0xc6,0x33,0x63,0x34 };
1314 static BYTE cert[] = {
1315 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1316 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1317 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1318 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1319 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1320 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1321 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1322 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1323 0xff,0x02,0x01,0x01 };
1324 static BYTE v1CertWithPubKey[] = {
1325 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1326 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1327 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1328 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1329 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1330 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1331 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1332 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1333 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1334 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1335 0x01,0x01 };
1336 static const BYTE signedWithCertEmptyBareContent[] = {
1337 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1338 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1339 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1340 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1341 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1342 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1343 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1344 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1345 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1346 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1347 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1348 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1349 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1350 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1351 static const BYTE signedWithCertBareContent[] = {
1352 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1353 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1354 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1355 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1356 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1357 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1358 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1359 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1360 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1361 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1362 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1363 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1364 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1365 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1366 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1367 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1368 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1369 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1370 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1371 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1372 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1373 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1374 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1375 0x30,0x30,0x30,0x30,0x5a };
1376 static const BYTE signedWithCrlEmptyBareContent[] = {
1377 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1378 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1379 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1380 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1381 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1382 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1383 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1384 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1385 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1386 static const BYTE signedWithCrlBareContent[] = {
1387 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1388 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1389 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1390 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1391 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1392 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1393 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1394 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1395 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1396 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1397 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1398 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1399 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1400 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1401 0xa8,0x0d };
1402 static const BYTE signedWithCertAndCrlEmptyBareContent[] = {
1403 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1404 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1405 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1406 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1407 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1408 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1409 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1410 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1411 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1412 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1413 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1414 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1415 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1416 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1417 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1418 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1419 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1420 0x04,0x00 };
1421 static const BYTE signedWithCertAndCrlBareContent[] = {
1422 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1423 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1424 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1425 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1426 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1427 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1428 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1429 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1430 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1431 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1432 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1433 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1434 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1435 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1436 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1437 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1438 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1439 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1440 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1441 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1442 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1443 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1444 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1445 static const BYTE signedWithCertWithPubKeyBareContent[] = {
1446 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1447 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1448 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1449 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1450 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1451 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1452 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1453 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1454 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1455 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1456 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1457 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1458 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1459 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1460 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1461 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1462
1463 static void test_signed_msg_encoding(void)
1464 {
1465     HCRYPTMSG msg;
1466     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1467     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1468     CERT_INFO certInfo = { 0 };
1469     CERT_BLOB encodedCert = { sizeof(cert), cert };
1470     CRL_BLOB encodedCrl = { sizeof(crl), crl };
1471     char oid_common_name[] = szOID_COMMON_NAME;
1472     CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
1473      encodedCommonName };
1474     CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1475     BOOL ret;
1476     HCRYPTKEY key;
1477     DWORD size;
1478
1479     certInfo.SerialNumber.cbData = sizeof(serialNum);
1480     certInfo.SerialNumber.pbData = serialNum;
1481     certInfo.Issuer.cbData = sizeof(encodedCommonName);
1482     certInfo.Issuer.pbData = encodedCommonName;
1483     signer.pCertInfo = &certInfo;
1484     signer.HashAlgorithm.pszObjId = oid_rsa_md5;
1485     signInfo.cSigners = 1;
1486     signInfo.rgSigners = &signer;
1487     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1488      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1489     if (!ret && GetLastError() == NTE_EXISTS)
1490         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1491          PROV_RSA_FULL, 0);
1492     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1493     ret = CryptImportKey(signer.hCryptProv, (LPBYTE)privKey, sizeof(privKey),
1494      0, 0, &key);
1495     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1496
1497     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
1498      CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1499     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1500
1501     check_param("detached signed empty bare content", msg,
1502      CMSG_BARE_CONTENT_PARAM, signedEmptyBareContent,
1503      sizeof(signedEmptyBareContent));
1504     check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1505      signedEmptyContent, sizeof(signedEmptyContent));
1506     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1507     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1508     check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1509      signedHash, sizeof(signedHash));
1510     check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1511      detachedSignedBareContent, sizeof(detachedSignedBareContent));
1512     check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1513      detachedSignedContent, sizeof(detachedSignedContent));
1514     SetLastError(0xdeadbeef);
1515     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1516     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1517      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1518     check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1519      signedEncodedSigner, sizeof(signedEncodedSigner));
1520
1521     CryptMsgClose(msg);
1522
1523     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1524      NULL, NULL);
1525     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1526
1527     check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1528      signedEmptyBareContent, sizeof(signedEmptyBareContent));
1529     check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1530      signedEmptyContent, sizeof(signedEmptyContent));
1531     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1532     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1533     check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1534      signedBareContent, sizeof(signedBareContent));
1535     check_param("signed content", msg, CMSG_CONTENT_PARAM,
1536      signedContent, sizeof(signedContent));
1537
1538     CryptMsgClose(msg);
1539
1540     signer.cAuthAttr = 1;
1541     signer.rgAuthAttr = &attr;
1542     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1543      NULL, NULL);
1544     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1545
1546     CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1547     check_param("signed with auth attrs bare content", msg,
1548      CMSG_BARE_CONTENT_PARAM, signedWithAuthAttrsBareContent,
1549      sizeof(signedWithAuthAttrsBareContent));
1550
1551     CryptMsgClose(msg);
1552
1553     signer.cAuthAttr = 0;
1554     signInfo.rgCertEncoded = &encodedCert;
1555     signInfo.cCertEncoded = 1;
1556     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1557      NULL, NULL);
1558     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1559
1560     check_param("signed with cert empty bare content", msg,
1561      CMSG_BARE_CONTENT_PARAM, signedWithCertEmptyBareContent,
1562      sizeof(signedWithCertEmptyBareContent));
1563     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1564     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1565     check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1566      signedWithCertBareContent, sizeof(signedWithCertBareContent));
1567
1568     CryptMsgClose(msg);
1569
1570     signInfo.cCertEncoded = 0;
1571     signInfo.rgCrlEncoded = &encodedCrl;
1572     signInfo.cCrlEncoded = 1;
1573     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1574      NULL, NULL);
1575     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1576
1577     check_param("signed with crl empty bare content", msg,
1578      CMSG_BARE_CONTENT_PARAM, signedWithCrlEmptyBareContent,
1579      sizeof(signedWithCrlEmptyBareContent));
1580     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1581     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1582     check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1583      signedWithCrlBareContent, sizeof(signedWithCrlBareContent));
1584
1585     CryptMsgClose(msg);
1586
1587     signInfo.cCertEncoded = 1;
1588     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1589      NULL, NULL);
1590     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1591
1592     check_param("signed with cert and crl empty bare content", msg,
1593      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlEmptyBareContent,
1594      sizeof(signedWithCertAndCrlEmptyBareContent));
1595     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1596     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1597     check_param("signed with cert and crl bare content", msg,
1598      CMSG_BARE_CONTENT_PARAM, signedWithCertAndCrlBareContent,
1599      sizeof(signedWithCertAndCrlBareContent));
1600
1601     CryptMsgClose(msg);
1602
1603     /* Test with a cert with a (bogus) public key */
1604     signInfo.cCrlEncoded = 0;
1605     encodedCert.cbData = sizeof(v1CertWithPubKey);
1606     encodedCert.pbData = v1CertWithPubKey;
1607     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1608      NULL, NULL);
1609     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1610     check_param("signedWithCertWithPubKeyBareContent", msg,
1611      CMSG_BARE_CONTENT_PARAM, signedWithCertWithPubKeyBareContent,
1612      sizeof(signedWithCertWithPubKeyBareContent));
1613     CryptMsgClose(msg);
1614
1615     CryptDestroyKey(key);
1616     CryptReleaseContext(signer.hCryptProv, 0);
1617     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL, PROV_RSA_FULL,
1618      CRYPT_DELETEKEYSET);
1619 }
1620
1621 static void test_signed_msg_get_param(void)
1622 {
1623     BOOL ret;
1624     HCRYPTMSG msg;
1625     DWORD size, value = 0;
1626     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1627     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1628     CERT_INFO certInfo = { 0 };
1629
1630     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1631      NULL, NULL);
1632     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1633
1634     /* Content and bare content are always gettable */
1635     size = 0;
1636     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
1637     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1638     size = 0;
1639     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
1640     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1641     /* For "signed" messages, so is the version. */
1642     size = 0;
1643     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, NULL, &size);
1644     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1645     size = sizeof(value);
1646     ret = CryptMsgGetParam(msg, CMSG_VERSION_PARAM, 0, (LPBYTE)&value, &size);
1647     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1648     ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1649     /* But for this message, with no signers, the hash and signer aren't
1650      * available.
1651      */
1652     size = 0;
1653     SetLastError(0xdeadbeef);
1654     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1655     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1656      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1657     SetLastError(0xdeadbeef);
1658     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1659     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1660      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1661     /* As usual, the type isn't available. */
1662     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1663     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1664      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1665
1666     CryptMsgClose(msg);
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     ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1677      PROV_RSA_FULL, CRYPT_NEWKEYSET);
1678     if (!ret && GetLastError() == NTE_EXISTS)
1679         ret = pCryptAcquireContextW(&signer.hCryptProv, cspNameW, NULL,
1680          PROV_RSA_FULL, 0);
1681     ok(ret, "CryptAcquireContextW failed: %x\n", GetLastError());
1682     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
1683      NULL, NULL);
1684     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1685
1686     /* This message, with one signer, has the hash and signer for index 0
1687      * available, but not for other indexes.
1688      */
1689     size = 0;
1690     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
1691     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1692     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
1693     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1694     size = 0;
1695     SetLastError(0xdeadbeef);
1696     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 1, NULL, &size);
1697     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1698      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1699     SetLastError(0xdeadbeef);
1700     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
1701     ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
1702      "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1703     /* As usual, the type isn't available. */
1704     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
1705     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1706      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1707
1708     CryptMsgClose(msg);
1709
1710     CryptReleaseContext(signer.hCryptProv, 0);
1711     pCryptAcquireContextW(&signer.hCryptProv, cspNameW, MS_DEF_PROV_W,
1712      PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1713 }
1714
1715 static void test_signed_msg(void)
1716 {
1717     test_signed_msg_open();
1718     test_signed_msg_update();
1719     test_signed_msg_encoding();
1720     test_signed_msg_get_param();
1721 }
1722
1723 static CRYPT_DATA_BLOB b4 = { 0, NULL };
1724 static const struct update_accum a4 = { 1, &b4 };
1725
1726 static const BYTE bogusOIDContent[] = {
1727 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
1728 0x04,0x00 };
1729 static const BYTE bogusHashContent[] = {
1730 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1731 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1732 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1733 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
1734 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1735
1736 static void test_decode_msg_update(void)
1737 {
1738     HCRYPTMSG msg;
1739     BOOL ret;
1740     CMSG_STREAM_INFO streamInfo = { 0 };
1741     DWORD i;
1742     struct update_accum accum = { 0, NULL };
1743
1744     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1745     /* Update with a full message in a final update */
1746     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1747     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1748     /* Can't update after a final update */
1749     SetLastError(0xdeadbeef);
1750     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1751     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1752      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1753     CryptMsgClose(msg);
1754
1755     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1756     /* Can't send a non-final update without streaming */
1757     SetLastError(0xdeadbeef);
1758     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1759      FALSE);
1760     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
1761      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1762     /* A subsequent final update succeeds */
1763     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent), TRUE);
1764     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1765     CryptMsgClose(msg);
1766
1767     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1768     /* Updating a message that has a NULL stream callback fails */
1769     SetLastError(0xdeadbeef);
1770     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1771      FALSE);
1772     todo_wine
1773     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1774      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1775     /* Changing the callback pointer after the fact yields the same error (so
1776      * the message must copy the stream info, not just store a pointer to it)
1777      */
1778     streamInfo.pfnStreamOutput = nop_stream_output;
1779     SetLastError(0xdeadbeef);
1780     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1781      FALSE);
1782     todo_wine
1783     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1784      "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
1785     CryptMsgClose(msg);
1786
1787     /* Empty non-final updates are allowed when streaming.. */
1788     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1789     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1790     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1791     /* but final updates aren't when not enough data has been received. */
1792     SetLastError(0xdeadbeef);
1793     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1794     todo_wine
1795     ok(!ret && GetLastError() == CRYPT_E_STREAM_INSUFFICIENT_DATA,
1796      "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
1797     CryptMsgClose(msg);
1798
1799     /* Updating the message byte by byte is legal */
1800     streamInfo.pfnStreamOutput = accumulating_stream_output;
1801     streamInfo.pvArg = &accum;
1802     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1803     for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
1804         ret = CryptMsgUpdate(msg, &dataEmptyContent[i], 1, FALSE);
1805     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1806     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1807     ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
1808     CryptMsgClose(msg);
1809     todo_wine
1810     check_updates("byte-by-byte empty content", &a4, &accum);
1811     free_updates(&accum);
1812
1813     /* Decoding bogus content fails in non-streaming mode.. */
1814     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1815     SetLastError(0xdeadbeef);
1816     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1817     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1818      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1819     CryptMsgClose(msg);
1820     /* and as the final update in streaming mode.. */
1821     streamInfo.pfnStreamOutput = nop_stream_output;
1822     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1823     SetLastError(0xdeadbeef);
1824     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1825     todo_wine
1826     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1827      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1828     CryptMsgClose(msg);
1829     /* and even as a non-final update in streaming mode. */
1830     streamInfo.pfnStreamOutput = nop_stream_output;
1831     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
1832     SetLastError(0xdeadbeef);
1833     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1834     todo_wine
1835     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1836      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1837     CryptMsgClose(msg);
1838
1839     /* An empty message can be opened with indetermined type.. */
1840     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1841     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1842      TRUE);
1843     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1844     /* but decoding it as an explicitly typed message fails. */
1845     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1846      NULL);
1847     SetLastError(0xdeadbeef);
1848     ret = CryptMsgUpdate(msg, dataEmptyContent, sizeof(dataEmptyContent),
1849      TRUE);
1850     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1851      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1852     CryptMsgClose(msg);
1853     /* On the other hand, decoding the bare content of an empty message fails
1854      * with unspecified type..
1855      */
1856     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1857     SetLastError(0xdeadbeef);
1858     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1859      sizeof(dataEmptyBareContent), TRUE);
1860     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1861      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1862     CryptMsgClose(msg);
1863     /* but succeeds with explicit type. */
1864     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
1865      NULL);
1866     ret = CryptMsgUpdate(msg, dataEmptyBareContent,
1867      sizeof(dataEmptyBareContent), TRUE);
1868     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1869     CryptMsgClose(msg);
1870
1871     /* Decoding valid content with an unsupported OID fails */
1872     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1873     SetLastError(0xdeadbeef);
1874     ret = CryptMsgUpdate(msg, bogusOIDContent, sizeof(bogusOIDContent), TRUE);
1875     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
1876      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1877     CryptMsgClose(msg);
1878
1879     /* Similarly, opening an empty hash with unspecified type succeeds.. */
1880     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1881     SetLastError(0xdeadbeef);
1882     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1883     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1884     CryptMsgClose(msg);
1885     /* while with specified type it fails. */
1886     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1887      NULL);
1888     SetLastError(0xdeadbeef);
1889     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
1890     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1891      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1892     CryptMsgClose(msg);
1893     /* On the other hand, decoding the bare content of an empty hash message
1894      * fails with unspecified type..
1895      */
1896     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1897     SetLastError(0xdeadbeef);
1898     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1899      sizeof(hashEmptyBareContent), TRUE);
1900     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1901      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1902     CryptMsgClose(msg);
1903     /* but succeeds with explicit type. */
1904     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1905      NULL);
1906     ret = CryptMsgUpdate(msg, hashEmptyBareContent,
1907      sizeof(hashEmptyBareContent), TRUE);
1908     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1909     CryptMsgClose(msg);
1910
1911     /* And again, opening a (non-empty) hash message with unspecified type
1912      * succeeds..
1913      */
1914     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1915     SetLastError(0xdeadbeef);
1916     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1917     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1918     CryptMsgClose(msg);
1919     /* while with specified type it fails.. */
1920     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1921      NULL);
1922     SetLastError(0xdeadbeef);
1923     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
1924     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1925      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1926     CryptMsgClose(msg);
1927     /* and decoding the bare content of a non-empty hash message fails with
1928      * unspecified type..
1929      */
1930     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1931     SetLastError(0xdeadbeef);
1932     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1933     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1934      "Expected CRYPT_E_ASN1_BADTAG, got %x\n", GetLastError());
1935     CryptMsgClose(msg);
1936     /* but succeeds with explicit type. */
1937     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
1938      NULL);
1939     ret = CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
1940     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1941     CryptMsgClose(msg);
1942
1943     /* Opening a (non-empty) hash message with unspecified type and a bogus
1944      * hash value succeeds..
1945      */
1946     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1947     SetLastError(0xdeadbeef);
1948     ret = CryptMsgUpdate(msg, bogusHashContent, sizeof(bogusHashContent), TRUE);
1949     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1950     CryptMsgClose(msg);
1951
1952     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1953     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
1954     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1955     CryptMsgClose(msg);
1956     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
1957     SetLastError(0xdeadbeef);
1958     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1959      sizeof(signedWithCertAndCrlBareContent), TRUE);
1960     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1961      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1962     CryptMsgClose(msg);
1963     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
1964      NULL);
1965     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
1966      sizeof(signedWithCertAndCrlBareContent), TRUE);
1967     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1968     CryptMsgClose(msg);
1969 }
1970
1971 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
1972  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1973
1974 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
1975  const CMSG_SIGNER_INFO *expected)
1976 {
1977     ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
1978      expected->dwVersion, got->dwVersion);
1979     ok(got->Issuer.cbData == expected->Issuer.cbData,
1980      "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
1981      got->Issuer.cbData);
1982     ok(!memcmp(got->Issuer.pbData, got->Issuer.pbData, got->Issuer.cbData),
1983      "Unexpected issuer\n");
1984     ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
1985      "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
1986      got->SerialNumber.cbData);
1987     ok(!memcmp(got->SerialNumber.pbData, got->SerialNumber.pbData,
1988      got->SerialNumber.cbData), "Unexpected serial number\n");
1989     /* FIXME: check more things */
1990 }
1991
1992 static void test_decode_msg_get_param(void)
1993 {
1994     HCRYPTMSG msg;
1995     BOOL ret;
1996     DWORD size = 0, value;
1997     LPBYTE buf;
1998
1999     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2000     SetLastError(0xdeadbeef);
2001     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
2002     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2003      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2004     ret = CryptMsgUpdate(msg, dataContent, sizeof(dataContent), TRUE);
2005     check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2006      sizeof(msgData));
2007     CryptMsgClose(msg);
2008
2009     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2010     ret = CryptMsgUpdate(msg, hashEmptyContent, sizeof(hashEmptyContent), TRUE);
2011     check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2012     check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2013     check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2014      emptyHashParam, sizeof(emptyHashParam));
2015     CryptMsgClose(msg);
2016     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2017     ret = CryptMsgUpdate(msg, hashContent, sizeof(hashContent), TRUE);
2018     check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2019      sizeof(msgData));
2020     check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2021      sizeof(hashParam));
2022     check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2023      hashParam, sizeof(hashParam));
2024     /* Curiously, getting the hash of index 1 succeeds, even though there's
2025      * only one hash.
2026      */
2027     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, NULL, &size);
2028     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2029     buf = CryptMemAlloc(size);
2030     if (buf)
2031     {
2032         ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 1, buf, &size);
2033         ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2034         ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2035         CryptMemFree(buf);
2036     }
2037     check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2038      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2039     value = CMSG_HASHED_DATA_V0;
2040     check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2041      sizeof(value));
2042     CryptMsgClose(msg);
2043
2044     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2045     ret = CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
2046     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2047     check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2048      sizeof(msgData));
2049     check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2050      (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2051     size = sizeof(value);
2052     value = 2112;
2053     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 0, &value, &size);
2054     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2055     ok(value == 1, "Expected 1 signer, got %d\n", value);
2056     size = 0;
2057     ret = CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &size);
2058     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2059     if (ret)
2060         buf = CryptMemAlloc(size);
2061     else
2062         buf = NULL;
2063     if (buf)
2064     {
2065         CMSG_SIGNER_INFO signer = { 0 };
2066
2067         signer.dwVersion = 1;
2068         signer.Issuer.cbData = sizeof(encodedCommonName);
2069         signer.Issuer.pbData = encodedCommonName;
2070         signer.SerialNumber.cbData = sizeof(serialNum);
2071         signer.SerialNumber.pbData = serialNum;
2072         signer.HashAlgorithm.pszObjId = oid_rsa_md5;
2073         CryptMsgGetParam(msg, CMSG_SIGNER_INFO_PARAM, 0, buf, &size);
2074         compare_signer_info((CMSG_SIGNER_INFO *)buf, &signer);
2075         CryptMemFree(buf);
2076     }
2077     /* index is ignored when getting signer count */
2078     size = sizeof(value);
2079     ret = CryptMsgGetParam(msg, CMSG_SIGNER_COUNT_PARAM, 1, &value, &size);
2080     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2081     ok(value == 1, "Expected 1 signer, got %d\n", value);
2082     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2083     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2084     ok(value == 0, "Expected 0 certs, got %d\n", value);
2085     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2086     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2087     ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2088     CryptMsgClose(msg);
2089     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2090      NULL);
2091     ret = CryptMsgUpdate(msg, signedWithCertAndCrlBareContent,
2092      sizeof(signedWithCertAndCrlBareContent), TRUE);
2093     ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2094     ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &value, &size);
2095     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2096     ok(value == 1, "Expected 1 cert, got %d\n", value);
2097     check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
2098     ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &value, &size);
2099     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2100     ok(value == 1, "Expected 1 CRL, got %d\n", value);
2101     check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
2102     CryptMsgClose(msg);
2103 }
2104
2105 static void test_decode_msg(void)
2106 {
2107     test_decode_msg_update();
2108     test_decode_msg_get_param();
2109 }
2110
2111 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
2112 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
2113 static BYTE encodedPubKey[] = {
2114 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
2115 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
2116 0x0d,0x0e,0x0f };
2117 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
2118 static BYTE mod_encoded[] = {
2119  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
2120  0x01,0x00,0x01 };
2121
2122 static void test_msg_control(void)
2123 {
2124     static char oid_rsa_rsa[] = szOID_RSA_RSA;
2125     BOOL ret;
2126     HCRYPTMSG msg;
2127     DWORD i;
2128     CERT_INFO certInfo = { 0 };
2129     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
2130     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
2131     CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2132
2133     /* Crashes
2134     ret = CryptMsgControl(NULL, 0, 0, NULL);
2135     */
2136
2137     /* Data encode messages don't allow any sort of control.. */
2138     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
2139      NULL);
2140     /* either with no prior update.. */
2141     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2142     {
2143         SetLastError(0xdeadbeef);
2144         ret = CryptMsgControl(msg, 0, i, NULL);
2145         ok(!ret && GetLastError() == E_INVALIDARG,
2146          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2147     }
2148     /* or after an update. */
2149     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2150     {
2151         SetLastError(0xdeadbeef);
2152         ret = CryptMsgControl(msg, 0, i, NULL);
2153         ok(!ret && GetLastError() == E_INVALIDARG,
2154          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2155     }
2156     CryptMsgClose(msg);
2157
2158     /* Hash encode messages don't allow any sort of control.. */
2159     hashInfo.cbSize = sizeof(hashInfo);
2160     hashInfo.HashAlgorithm.pszObjId = oid_rsa_md5;
2161     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, &hashInfo,
2162      NULL, NULL);
2163     /* either with no prior update.. */
2164     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2165     {
2166         SetLastError(0xdeadbeef);
2167         ret = CryptMsgControl(msg, 0, i, NULL);
2168         ok(!ret && GetLastError() == E_INVALIDARG,
2169          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2170     }
2171     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2172     /* or after an update. */
2173     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2174     {
2175         SetLastError(0xdeadbeef);
2176         ret = CryptMsgControl(msg, 0, i, NULL);
2177         ok(!ret && GetLastError() == E_INVALIDARG,
2178          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2179     }
2180     CryptMsgClose(msg);
2181
2182     /* Signed encode messages likewise don't allow any sort of control.. */
2183     signInfo.cbSize = sizeof(signInfo);
2184     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, &signInfo,
2185      NULL, NULL);
2186     /* either before an update.. */
2187     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2188     {
2189         SetLastError(0xdeadbeef);
2190         ret = CryptMsgControl(msg, 0, i, NULL);
2191         ok(!ret && GetLastError() == E_INVALIDARG,
2192          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2193     }
2194     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2195     /* or after an update. */
2196     for (i = 1; i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO; i++)
2197     {
2198         SetLastError(0xdeadbeef);
2199         ret = CryptMsgControl(msg, 0, i, NULL);
2200         ok(!ret && GetLastError() == E_INVALIDARG,
2201          "Expected E_INVALIDARG, got %08x\n", GetLastError());
2202     }
2203     CryptMsgClose(msg);
2204
2205     /* Decode messages behave a bit differently. */
2206     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
2207     /* Bad control type */
2208     SetLastError(0xdeadbeef);
2209     ret = CryptMsgControl(msg, 0, 0, NULL);
2210     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2211      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2212     SetLastError(0xdeadbeef);
2213     ret = CryptMsgControl(msg, 1, 0, NULL);
2214     ok(!ret && GetLastError() == CRYPT_E_CONTROL_TYPE,
2215      "Expected CRYPT_E_CONTROL_TYPE, got %08x\n", GetLastError());
2216     /* Can't verify the hash of an indeterminate-type message */
2217     SetLastError(0xdeadbeef);
2218     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2219     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2220      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2221     /* Crashes
2222     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, NULL);
2223      */
2224     /* Can't decrypt an indeterminate-type message */
2225     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2226     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2227      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2228     CryptMsgClose(msg);
2229
2230     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2231      NULL);
2232     /* Can't verify the hash of an empty message */
2233     SetLastError(0xdeadbeef);
2234     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2235     todo_wine
2236     ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2237      "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2238     /* Crashes
2239     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2240      */
2241     /* Can't verify the signature of a hash message */
2242     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2243     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2244      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2245     CryptMsgUpdate(msg, hashEmptyBareContent, sizeof(hashEmptyBareContent),
2246      TRUE);
2247     /* Oddly enough, this fails */
2248     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2249     todo_wine
2250     ok(!ret, "Expected failure\n");
2251     CryptMsgClose(msg);
2252     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
2253      NULL);
2254     CryptMsgUpdate(msg, hashBareContent, sizeof(hashBareContent), TRUE);
2255     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2256     ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
2257     /* Can't decrypt an indeterminate-type message */
2258     SetLastError(0xdeadbeef);
2259     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2260     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2261      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2262     CryptMsgClose(msg);
2263
2264     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2265      NULL);
2266     /* Can't verify the hash of a signed message */
2267     SetLastError(0xdeadbeef);
2268     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL);
2269     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2270      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2271     /* Can't decrypt a signed message */
2272     SetLastError(0xdeadbeef);
2273     ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
2274     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
2275      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2276     /* Crash
2277     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, NULL);
2278     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2279      */
2280     CryptMsgUpdate(msg, signedWithCertBareContent,
2281      sizeof(signedWithCertBareContent), TRUE);
2282     /* With an empty cert info, the signer can't be found in the message (and
2283      * the signature can't be verified.
2284      */
2285     SetLastError(0xdeadbeef);
2286     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2287     todo_wine
2288     ok(!ret && GetLastError() == CRYPT_E_SIGNER_NOT_FOUND,
2289      "Expected CRYPT_E_SIGNER_NOT_FOUND, got %08x\n", GetLastError());
2290     /* The cert info is expected to have an issuer, serial number, and public
2291      * key info set.
2292      */
2293     certInfo.SerialNumber.cbData = sizeof(serialNum);
2294     certInfo.SerialNumber.pbData = serialNum;
2295     certInfo.Issuer.cbData = sizeof(encodedCommonName);
2296     certInfo.Issuer.pbData = encodedCommonName;
2297     SetLastError(0xdeadbeef);
2298     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2299     todo_wine
2300     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2301      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2302     CryptMsgClose(msg);
2303     /* This cert has a public key, but it's not in a usable form */
2304     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
2305      NULL);
2306     CryptMsgUpdate(msg, signedWithCertWithPubKeyBareContent,
2307      sizeof(signedWithCertWithPubKeyBareContent), TRUE);
2308     /* Again, cert info needs to have a public key set */
2309     SetLastError(0xdeadbeef);
2310     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2311     todo_wine
2312     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2313      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2314     /* The public key is supposed to be in encoded form.. */
2315     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2316     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2317     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = aKey;
2318     SetLastError(0xdeadbeef);
2319     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2320     todo_wine
2321     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2322      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2323     /* but not as a X509_PUBLIC_KEY_INFO.. */
2324     certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2325     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(encodedPubKey);
2326     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = encodedPubKey;
2327     SetLastError(0xdeadbeef);
2328     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2329     todo_wine
2330     ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2331      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2332     /* This decodes successfully, but it doesn't match any key in the message */
2333     certInfo.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(mod_encoded);
2334     certInfo.SubjectPublicKeyInfo.PublicKey.pbData = mod_encoded;
2335     SetLastError(0xdeadbeef);
2336     ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo);
2337     todo_wine
2338     ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
2339      "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
2340     CryptMsgClose(msg);
2341     /* FIXME: need to test with a message with a valid signature and signer */
2342 }
2343
2344 START_TEST(msg)
2345 {
2346      init_function_pointers();
2347
2348     /* Basic parameter checking tests */
2349     test_msg_open_to_encode();
2350     test_msg_open_to_decode();
2351     test_msg_get_param();
2352     test_msg_close();
2353     test_msg_control();
2354
2355     /* Message-type specific tests */
2356     test_data_msg();
2357     test_hash_msg();
2358     test_signed_msg();
2359     test_decode_msg();
2360 }