ReactOS  0.4.14-dev-583-g2a1ba2c
msg.c
Go to the documentation of this file.
1 /*
2  * Unit test suite for crypt32.dll's CryptMsg functions
3  *
4  * Copyright 2007 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winerror.h>
26 #define CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
27 #define CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
28 #include <wincrypt.h>
29 
30 #include "wine/test.h"
31 
32 static BOOL have_nt = TRUE;
34 static char oid_rsa_md5[] = szOID_RSA_MD5;
35 
36 static BOOL (WINAPI * pCryptAcquireContextA)
38 static BOOL (WINAPI * pCryptAcquireContextW)
40 
41 static void init_function_pointers(void)
42 {
43  HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
44 
45 #define GET_PROC(dll, func) \
46  p ## func = (void *)GetProcAddress(dll, #func); \
47  if(!p ## func) \
48  trace("GetProcAddress(%s) failed\n", #func);
49 
50  GET_PROC(hAdvapi32, CryptAcquireContextA)
51  GET_PROC(hAdvapi32, CryptAcquireContextW)
52 
53 #undef GET_PROC
54 }
55 
56 static void test_msg_open_to_encode(void)
57 {
58  HCRYPTMSG msg;
59 
60  /* Crash
61  msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
62  NULL, NULL);
63  msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
64  NULL);
65  msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
66  NULL);
67  */
68 
69  /* Bad encodings */
70  SetLastError(0xdeadbeef);
71  msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
73  "Expected E_INVALIDARG, got %x\n", GetLastError());
74  SetLastError(0xdeadbeef);
77  "Expected E_INVALIDARG, got %x\n", GetLastError());
78 
79  /* Bad message types */
80  SetLastError(0xdeadbeef);
83  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
84  SetLastError(0xdeadbeef);
86  NULL, NULL, NULL);
88  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
89  SetLastError(0xdeadbeef);
93  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
94  SetLastError(0xdeadbeef);
96  NULL, NULL);
98  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
99 }
100 
101 static void test_msg_open_to_decode(void)
102 {
103  HCRYPTMSG msg;
104  CMSG_STREAM_INFO streamInfo = { 0 };
105 
106  SetLastError(0xdeadbeef);
107  msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
108  ok(!msg && GetLastError() == E_INVALIDARG,
109  "Expected E_INVALIDARG, got %x\n", GetLastError());
110 
111  /* Bad encodings */
112  SetLastError(0xdeadbeef);
114  ok(!msg && GetLastError() == E_INVALIDARG,
115  "Expected E_INVALIDARG, got %x\n", GetLastError());
116  SetLastError(0xdeadbeef);
118  ok(!msg && GetLastError() == E_INVALIDARG,
119  "Expected E_INVALIDARG, got %x\n", GetLastError());
120 
121  /* The message type can be explicit... */
123  NULL);
124  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
127  NULL);
128  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
131  NULL);
132  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
135  NULL);
136  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
140  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
142  /* or implicit.. */
144  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
146  /* or even invalid. */
148  NULL);
149  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
152  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
154 
155  /* And even though the stream info parameter "must be set to NULL" for
156  * CMSG_HASHED, it's still accepted.
157  */
159  &streamInfo);
160  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
162 }
163 
164 static void test_msg_get_param(void)
165 {
166  BOOL ret;
167  HCRYPTMSG msg;
168  DWORD size, i, value;
169 
170  /* Crash
171  ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
172  ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
173  ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
174  */
175 
176  /* Decoded messages */
178  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
179  /* For decoded messages, the type is always available */
180  size = 0;
182  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
183  size = sizeof(value);
185  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
186  /* For this (empty) message, the type isn't set */
187  ok(value == 0, "Expected type 0, got %d\n", value);
189 
191  NULL);
192  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
193  /* For explicitly typed messages, the type is known. */
194  size = sizeof(value);
196  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
197  ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
199  {
200  size = 0;
201  ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
202  ok(!ret, "Parameter %d: expected failure\n", i);
203  }
205 
207  NULL);
208  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
209  size = sizeof(value);
211  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
212  ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
214  {
215  size = 0;
216  ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
217  ok(!ret, "Parameter %d: expected failure\n", i);
218  }
220 
222  NULL);
223  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
224  size = sizeof(value);
226  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
227  ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
229  {
230  size = 0;
231  ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
232  ok(!ret, "Parameter %d: expected failure\n", i);
233  }
235 
237  NULL);
238  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
239  size = sizeof(value);
241  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
242  ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
244  {
245  size = 0;
246  ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
247  ok(!ret, "Parameter %d: expected failure\n", i);
248  }
250 
251  /* Explicitly typed messages get their types set, even if they're invalid */
253  NULL);
254  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
255  size = sizeof(value);
257  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
258  ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
260 
262  ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
263  size = sizeof(value);
265  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
266  ok(value == 1000, "Expected 1000, got %d\n", value);
268 }
269 
270 static void test_msg_close(void)
271 {
272  BOOL ret;
273  HCRYPTMSG msg;
274 
275  /* NULL succeeds.. */
277  ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
278  /* but an arbitrary pointer crashes. */
279  if (0)
282  NULL);
283  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
284  ret = CryptMsgClose(msg);
285  ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
286 }
287 
289  const BYTE *expected, DWORD expectedSize)
290 {
291  DWORD size;
292  LPBYTE buf;
293  BOOL ret;
294 
295  size = 0xdeadbeef;
297  ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */ ||
298  GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x, for some params */),
299  "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
300  if (!ret)
301  {
302  win_skip("parameter %d not supported, skipping tests\n", param);
303  return;
304  }
305  buf = HeapAlloc(GetProcessHeap(), 0, size);
306  ret = CryptMsgGetParam(msg, param, 0, buf, &size);
307  ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
308  ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
309  expectedSize, size);
310  if (size == expectedSize && size)
311  ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
312  HeapFree(GetProcessHeap(), 0, buf);
313 }
314 
315 static void test_data_msg_open(void)
316 {
317  HCRYPTMSG msg;
318  CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
319  CMSG_STREAM_INFO streamInfo = { 0 };
320  char oid[] = "1.2.3";
321 
322  /* The data message type takes no additional info */
323  SetLastError(0xdeadbeef);
325  NULL, NULL);
326  ok(!msg && GetLastError() == E_INVALIDARG,
327  "Expected E_INVALIDARG, got %x\n", GetLastError());
329  NULL);
330  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
332 
333  /* An empty stream info is allowed. */
335  &streamInfo);
336  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
338 
339  /* Passing a bogus inner OID succeeds for a non-streamed message.. */
341  NULL);
342  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
344  /* and still succeeds when CMSG_DETACHED_FLAG is passed.. */
346  CMSG_DATA, NULL, oid, NULL);
347  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
349  /* and when a stream info is given, even though you're not supposed to be
350  * able to use anything but szOID_RSA_data when streaming is being used.
351  */
353  CMSG_DATA, NULL, oid, &streamInfo);
354  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
356 }
357 
358 static const BYTE msgData[] = { 1, 2, 3, 4 };
359 
360 static BOOL WINAPI nop_stream_output(const void *pvArg, BYTE *pb, DWORD cb,
361  BOOL final)
362 {
363  return TRUE;
364 }
365 
366 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
367 
368 static void test_data_msg_update(void)
369 {
370  HCRYPTMSG msg;
371  BOOL ret;
372  CMSG_STREAM_INFO streamInfo = { 0 };
373 
375  NULL);
376  /* Can't update a message that wasn't opened detached with final = FALSE */
377  SetLastError(0xdeadbeef);
378  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
380  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
381  /* Updating it with final = TRUE succeeds */
382  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
383  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
384  /* Any subsequent update will fail, as the last was final */
385  SetLastError(0xdeadbeef);
386  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
388  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
390 
392  NULL);
393  /* Starting with Vista, can update a message with no data. */
394  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
395  ok(ret || broken(!ret), "CryptMsgUpdate failed: %08x\n", GetLastError());
396  if (ret)
397  {
398  DWORD size;
399 
401  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
402  if (ret)
403  {
405 
406  if (buf)
407  {
409  &size);
410  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
411  if (ret)
412  {
413  ok(size == sizeof(dataEmptyBareContent),
414  "unexpected size %d\n", size);
416  "unexpected value\n");
417  }
418  CryptMemFree(buf);
419  }
420  }
421  }
423 
425  CMSG_DATA, NULL, NULL, NULL);
426  if (have_nt)
427  {
428  /* Doesn't appear to be able to update CMSG-DATA with non-final updates.
429  * On Win9x, this sometimes succeeds, sometimes fails with
430  * GetLastError() == 0, so it's not worth checking there.
431  */
432  SetLastError(0xdeadbeef);
433  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
434  ok(!ret &&
435  (GetLastError() == E_INVALIDARG ||
436  broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
437  "Expected E_INVALIDARG, got %x\n", GetLastError());
438  SetLastError(0xdeadbeef);
439  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
440  ok(!ret &&
441  (GetLastError() == E_INVALIDARG ||
442  broken(GetLastError() == ERROR_SUCCESS)), /* Older NT4 */
443  "Expected E_INVALIDARG, got %x\n", GetLastError());
444  }
445  else
446  skip("not updating CMSG_DATA with a non-final update\n");
447  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
448  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
450 
451  if (!old_crypt32)
452  {
453  /* Calling update after opening with an empty stream info (with a bogus
454  * output function) yields an error:
455  */
456  /* Crashes on some Win9x */
458  &streamInfo);
459  SetLastError(0xdeadbeef);
460  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
462  GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
463  "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
464  GetLastError());
466  }
467  /* Calling update with a valid output function succeeds, even if the data
468  * exceeds the size specified in the stream info.
469  */
470  streamInfo.pfnStreamOutput = nop_stream_output;
472  &streamInfo);
473  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
474  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
475  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
476  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
478 }
479 
480 static void test_data_msg_get_param(void)
481 {
482  HCRYPTMSG msg;
483  DWORD size;
484  BOOL ret;
485  CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
486 
488  NULL);
489 
490  /* Content and bare content are always gettable when not streaming */
491  size = 0;
493  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
494  size = 0;
496  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
497  /* But for this type of message, the signer and hash aren't applicable,
498  * and the type isn't available.
499  */
500  size = 0;
501  SetLastError(0xdeadbeef);
504  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
505  SetLastError(0xdeadbeef);
508  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
511  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
513 
514  /* Can't get content or bare content when streaming */
516  NULL, &streamInfo);
517  SetLastError(0xdeadbeef);
519  ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
520  "Expected E_INVALIDARG, got %x\n", GetLastError());
521  SetLastError(0xdeadbeef);
523  ok((!ret && GetLastError() == E_INVALIDARG) || broken(ret /* Win9x */),
524  "Expected E_INVALIDARG, got %x\n", GetLastError());
526 }
527 
528 static const BYTE dataEmptyContent[] = {
529 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
530 0x04,0x00 };
531 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
532 static const BYTE dataContent[] = {
533 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
534 0x04,0x04,0x01,0x02,0x03,0x04 };
535 
537 {
540 };
541 
542 static BOOL WINAPI accumulating_stream_output(const void *pvArg, BYTE *pb,
543  DWORD cb, BOOL final)
544 {
545  struct update_accum *accum = (struct update_accum *)pvArg;
546  BOOL ret = FALSE;
547 
548  if (accum->cUpdates)
549  accum->updates = CryptMemRealloc(accum->updates,
550  (accum->cUpdates + 1) * sizeof(CRYPT_DATA_BLOB));
551  else
552  accum->updates = CryptMemAlloc(sizeof(CRYPT_DATA_BLOB));
553  if (accum->updates)
554  {
555  CRYPT_DATA_BLOB *blob = &accum->updates[accum->cUpdates];
556 
557  blob->pbData = CryptMemAlloc(cb);
558  if (blob->pbData)
559  {
560  memcpy(blob->pbData, pb, cb);
561  blob->cbData = cb;
562  ret = TRUE;
563  }
564  accum->cUpdates++;
565  }
566  return ret;
567 }
568 
569 /* The updates of a (bogus) definite-length encoded message */
570 static BYTE u1[] = { 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
571  0x07,0x01,0xa0,0x02,0x04,0x00 };
572 static BYTE u2[] = { 0x01,0x02,0x03,0x04 };
573 static CRYPT_DATA_BLOB b1[] = {
574  { sizeof(u1), u1 },
575  { sizeof(u2), u2 },
576  { sizeof(u2), u2 },
577 };
578 static const struct update_accum a1 = { ARRAY_SIZE(b1), b1 };
579 /* The updates of a definite-length encoded message */
580 static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
581  0x07,0x01,0xa0,0x06,0x04,0x04 };
582 static CRYPT_DATA_BLOB b2[] = {
583  { sizeof(u3), u3 },
584  { sizeof(u2), u2 },
585 };
586 static const struct update_accum a2 = { ARRAY_SIZE(b2), b2 };
587 /* The updates of an indefinite-length encoded message */
588 static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
589  0x07,0x01,0xa0,0x80,0x24,0x80 };
590 static BYTE u5[] = { 0x04,0x04 };
591 static BYTE u6[] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
592 static CRYPT_DATA_BLOB b3[] = {
593  { sizeof(u4), u4 },
594  { sizeof(u5), u5 },
595  { sizeof(u2), u2 },
596  { sizeof(u5), u5 },
597  { sizeof(u2), u2 },
598  { sizeof(u6), u6 },
599 };
600 static const struct update_accum a3 = { ARRAY_SIZE(b3), b3 };
601 
602 static void check_updates(LPCSTR header, const struct update_accum *expected,
603  const struct update_accum *got)
604 {
605  DWORD i;
606 
607  ok(expected->cUpdates == got->cUpdates,
608  "%s: expected %d updates, got %d\n", header, expected->cUpdates,
609  got->cUpdates);
610  if (expected->cUpdates == got->cUpdates)
611  for (i = 0; i < min(expected->cUpdates, got->cUpdates); i++)
612  {
613  ok(expected->updates[i].cbData == got->updates[i].cbData,
614  "%s, update %d: expected %d bytes, got %d\n", header, i,
615  expected->updates[i].cbData, got->updates[i].cbData);
616  if (expected->updates[i].cbData && expected->updates[i].cbData ==
617  got->updates[i].cbData)
618  ok(!memcmp(expected->updates[i].pbData, got->updates[i].pbData,
619  got->updates[i].cbData), "%s, update %d: unexpected value\n",
620  header, i);
621  }
622 }
623 
624 /* Frees the updates stored in accum */
625 static void free_updates(struct update_accum *accum)
626 {
627  DWORD i;
628 
629  for (i = 0; i < accum->cUpdates; i++)
630  CryptMemFree(accum->updates[i].pbData);
631  CryptMemFree(accum->updates);
632  accum->updates = NULL;
633  accum->cUpdates = 0;
634 }
635 
636 static void test_data_msg_encoding(void)
637 {
638  HCRYPTMSG msg;
639  BOOL ret;
640  static char oid[] = "1.2.3";
641  struct update_accum accum = { 0, NULL };
642  CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
643 
645  NULL);
646  check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
648  check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
649  sizeof(dataEmptyContent));
650  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
651  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
652  check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
654  check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
655  sizeof(dataContent));
657  /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
659  CMSG_DATA, NULL, NULL, NULL);
660  check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
662  check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
663  sizeof(dataEmptyContent));
664  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
665  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
666  check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
668  check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
669  sizeof(dataContent));
671  /* The inner OID is apparently ignored */
673  NULL);
674  check_param("data bogus oid bare content", msg, CMSG_BARE_CONTENT_PARAM,
676  check_param("data bogus oid content", msg, CMSG_CONTENT_PARAM,
678  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
679  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
680  check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
682  check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
683  sizeof(dataContent));
685  /* A streaming message is DER encoded if the length is not 0xffffffff, but
686  * curiously, updates aren't validated to make sure they don't exceed the
687  * stated length. (The resulting output will of course fail to decode.)
688  */
690  NULL, &streamInfo);
691  CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
692  CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
694  check_updates("bogus data message with definite length", &a1, &accum);
695  free_updates(&accum);
696  /* A valid definite-length encoding: */
697  streamInfo.cbContent = sizeof(msgData);
699  NULL, &streamInfo);
700  CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
702  check_updates("data message with definite length", &a2, &accum);
703  free_updates(&accum);
704  /* An indefinite-length encoding: */
705  streamInfo.cbContent = 0xffffffff;
707  NULL, &streamInfo);
708  CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
709  CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
711  check_updates("data message with indefinite length", &a3, &accum);
712  free_updates(&accum);
713 }
714 
715 static void test_data_msg(void)
716 {
721 }
722 
723 static void test_hash_msg_open(void)
724 {
725  HCRYPTMSG msg;
726  CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
727  CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
728 
729  SetLastError(0xdeadbeef);
731  NULL, NULL);
732  ok(!msg && GetLastError() == E_INVALIDARG,
733  "Expected E_INVALIDARG, got %x\n", GetLastError());
734  hashInfo.cbSize = sizeof(hashInfo);
735  SetLastError(0xdeadbeef);
737  NULL, NULL);
739  "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
742  NULL, NULL);
743  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
746  CMSG_HASHED, &hashInfo, NULL, NULL);
747  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
750  CMSG_HASHED, &hashInfo, NULL, &streamInfo);
751  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
753 }
754 
755 static void test_hash_msg_update(void)
756 {
757  HCRYPTMSG msg;
758  BOOL ret;
759  CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
760  { oid_rsa_md5, { 0, NULL } }, NULL };
761  CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
762 
764  CMSG_HASHED, &hashInfo, NULL, NULL);
765  /* Detached hashed messages opened in non-streaming mode allow non-final
766  * updates..
767  */
768  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
769  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
770  /* including non-final updates with no data.. */
771  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
772  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
773  /* and final updates with no data. */
774  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
775  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
776  /* But no updates are allowed after the final update. */
777  SetLastError(0xdeadbeef);
778  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
780  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
781  SetLastError(0xdeadbeef);
782  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
784  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
786  /* Non-detached messages, in contrast, don't allow non-final updates in
787  * non-streaming mode.
788  */
790  NULL, NULL);
791  SetLastError(0xdeadbeef);
792  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
794  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
795  /* Final updates (including empty ones) are allowed. */
796  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
797  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
799  /* And, of course, streaming mode allows non-final updates */
801  NULL, &streamInfo);
802  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
803  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
805  /* Setting pfnStreamOutput to NULL results in no error. (In what appears
806  * to be a bug, it isn't actually used - see encoding tests.)
807  */
808  streamInfo.pfnStreamOutput = NULL;
810  NULL, &streamInfo);
811  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
812  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
814 }
815 
816 static const BYTE emptyHashParam[] = {
817 0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,
818 0x7e };
819 
820 static void test_hash_msg_get_param(void)
821 {
822  HCRYPTMSG msg;
823  BOOL ret;
824  CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0,
825  { oid_rsa_md5, { 0, NULL } }, NULL };
826  DWORD size, value;
827  CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
828  BYTE buf[16];
829 
831  NULL, NULL);
832  /* Content and bare content are always gettable for non-streamed messages */
833  size = 0;
835  ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
836  "CryptMsgGetParam failed: %08x\n", GetLastError());
837  size = 0;
839  ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
840  "CryptMsgGetParam failed: %08x\n", GetLastError());
841  /* For an encoded hash message, the hash data aren't available */
842  SetLastError(0xdeadbeef);
845  GetLastError() == OSS_LIMITED /* Win9x */),
846  "Expected CRYPT_E_INVALID_MSG_TYPE or OSS_LIMITED, got %08x\n",
847  GetLastError());
848  /* The hash is also available. */
849  size = 0;
851  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
852  ok(size == sizeof(buf), "Unexpected size %d\n", size);
854  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
855  ok(size == sizeof(buf), "Unexpected size %d\n", size);
856  if (size == sizeof(buf))
857  ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
858  /* By getting the hash, further updates are not allowed */
859  SetLastError(0xdeadbeef);
860  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
861  ok(!ret &&
862  (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
863  GetLastError() == NTE_BAD_ALGID /* 9x */ ||
864  GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
865  broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
866  "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
867 
868  /* Even after a final update, the hash data aren't available */
869  SetLastError(0xdeadbeef);
872  "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
873  /* The version is also available, and should be zero for this message. */
874  size = 0;
876  ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
877  "CryptMsgGetParam failed: %08x\n", GetLastError());
878  size = sizeof(value);
880  ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
881  "CryptMsgGetParam failed: %08x\n", GetLastError());
882  if (ret)
883  ok(value == 0, "Expected version 0, got %d\n", value);
884  /* As usual, the type isn't available. */
886  ok(!ret, "Expected failure\n");
888 
890  NULL, &streamInfo);
891  /* Streamed messages don't allow you to get the content or bare content. */
892  SetLastError(0xdeadbeef);
894  ok(!ret && (GetLastError() == E_INVALIDARG ||
895  GetLastError() == OSS_LIMITED /* Win9x */),
896  "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
897  SetLastError(0xdeadbeef);
899  ok(!ret && (GetLastError() == E_INVALIDARG ||
900  GetLastError() == OSS_LIMITED /* Win9x */),
901  "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
902  /* The hash is still available. */
903  size = 0;
905  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
906  ok(size == sizeof(buf), "Unexpected size %d\n", size);
908  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
909  if (size == sizeof(buf))
910  ok(!memcmp(buf, emptyHashParam, size), "Unexpected value\n");
911  /* After updating the hash, further updates aren't allowed on streamed
912  * messages either.
913  */
914  SetLastError(0xdeadbeef);
915  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
916  ok(!ret &&
917  (GetLastError() == NTE_BAD_HASH_STATE /* NT */ ||
918  GetLastError() == NTE_BAD_ALGID /* 9x */ ||
919  GetLastError() == CRYPT_E_MSG_ERROR /* Vista */ ||
920  broken(GetLastError() == ERROR_SUCCESS) /* Some Win9x */),
921  "Expected NTE_BAD_HASH_STATE or NTE_BAD_ALGID or CRYPT_E_MSG_ERROR, got 0x%x\n", GetLastError());
922 
924 }
925 
926 static const BYTE hashEmptyBareContent[] = {
927 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
928 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
929 static const BYTE hashEmptyContent[] = {
930 0x30,0x26,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x19,
931 0x30,0x17,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
932 0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x04,0x00 };
933 static const BYTE hashBareContent[] = {
934 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
935 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
936 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
937 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
938 static const BYTE hashContent[] = {
939 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
940 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
941 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
942 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
943 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
944 
946 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
947 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
948 0x07,0x01,0x04,0x00 };
950 0x30,0x2f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x22,
951 0x30,0x20,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
952 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
953 0x07,0x01,0x04,0x00 };
954 static const BYTE detachedHashBareContent[] = {
955 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
956 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
957 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
958 0x9d,0x2a,0x8f,0x26,0x2f };
959 static const BYTE detachedHashContent[] = {
960 0x30,0x3f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x32,
961 0x30,0x30,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
962 0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
963 0x07,0x01,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,
964 0x9d,0x2a,0x8f,0x26,0x2f };
965 
966 static void test_hash_msg_encoding(void)
967 {
968  HCRYPTMSG msg;
969  CMSG_HASHED_ENCODE_INFO hashInfo = { sizeof(hashInfo), 0 };
970  BOOL ret;
971  struct update_accum accum = { 0, NULL }, empty_accum = { 0, NULL };
972  CMSG_STREAM_INFO streamInfo = { 0, accumulating_stream_output, &accum };
973 
976  NULL, NULL);
977  check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
979  check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
981  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
982  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
983  check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
985  check_param("hash content", msg, CMSG_CONTENT_PARAM,
986  hashContent, sizeof(hashContent));
988  /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
990  CMSG_HASHED, &hashInfo, NULL, NULL);
991  check_param("hash empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
993  check_param("hash empty content", msg, CMSG_CONTENT_PARAM,
995  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
996  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
997  check_param("hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
999  check_param("hash content", msg, CMSG_CONTENT_PARAM,
1000  hashContent, sizeof(hashContent));
1001  CryptMsgClose(msg);
1002  /* Same test, but with CMSG_DETACHED_FLAG set */
1004  CMSG_HASHED, &hashInfo, NULL, NULL);
1005  check_param("detached hash empty bare content", msg,
1007  sizeof(hashEmptyBareContent));
1008  check_param("detached hash empty content", msg, CMSG_CONTENT_PARAM,
1010  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1011  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1012  check_param("detached hash not final bare content", msg,
1015  check_param("detached hash not final content", msg, CMSG_CONTENT_PARAM,
1017  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1018  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1019  check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1021  check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1023  check_param("detached hash bare content", msg, CMSG_BARE_CONTENT_PARAM,
1025  check_param("detached hash content", msg, CMSG_CONTENT_PARAM,
1027  CryptMsgClose(msg);
1028  /* In what appears to be a bug, streamed updates to hash messages don't
1029  * call the output function.
1030  */
1032  NULL, &streamInfo);
1033  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1034  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1035  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1036  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1037  CryptMsgClose(msg);
1038  check_updates("empty hash message", &empty_accum, &accum);
1039  free_updates(&accum);
1040 
1041  streamInfo.cbContent = sizeof(msgData);
1043  NULL, &streamInfo);
1044  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1045  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1046  CryptMsgClose(msg);
1047  check_updates("hash message", &empty_accum, &accum);
1048  free_updates(&accum);
1049 
1050  streamInfo.cbContent = sizeof(msgData);
1052  CMSG_HASHED, &hashInfo, NULL, &streamInfo);
1053  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1054  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1055  CryptMsgClose(msg);
1056  check_updates("detached hash message", &empty_accum, &accum);
1057  free_updates(&accum);
1058 }
1059 
1060 static void test_hash_msg(void)
1061 {
1066 }
1067 
1068 static const CHAR cspNameA[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1069  'm','p',0 };
1070 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
1071  'm','p',0 };
1072 static BYTE serialNum[] = { 1 };
1073 static BYTE encodedCommonName[] = { 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1074  0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1075 
1076 static void test_signed_msg_open(void)
1077 {
1078  HCRYPTMSG msg;
1079  BOOL ret;
1080  CMSG_SIGNED_ENCODE_INFO signInfo = { 0 };
1081  CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1082  CERT_INFO certInfo = { 0 };
1083 
1084  SetLastError(0xdeadbeef);
1086  NULL, NULL);
1087  ok(!msg && GetLastError() == E_INVALIDARG,
1088  "Expected E_INVALIDARG, got %x\n", GetLastError());
1089  signInfo.cbSize = sizeof(signInfo);
1091  NULL, NULL);
1092  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1093  CryptMsgClose(msg);
1094 
1095  signInfo.cSigners = 1;
1096  signInfo.rgSigners = &signer;
1097  /* With signer.pCertInfo unset, attempting to open this message this
1098  * crashes.
1099  */
1100  signer.pCertInfo = &certInfo;
1101  /* The cert info must contain a serial number and an issuer. */
1102  SetLastError(0xdeadbeef);
1104  NULL, NULL);
1105  /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1106  ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1108  "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1109  GetLastError());
1110 
1111  certInfo.SerialNumber.cbData = sizeof(serialNum);
1112  certInfo.SerialNumber.pbData = serialNum;
1113  SetLastError(0xdeadbeef);
1115  NULL, NULL);
1116  /* NT: E_INVALIDARG, 9x: unchanged or CRYPT_E_UNKNOWN_ALGO */
1117  ok(!msg && (GetLastError() == E_INVALIDARG || GetLastError() == 0xdeadbeef
1119  "Expected E_INVALIDARG or 0xdeadbeef or CRYPT_E_UNKNOWN_ALGO, got 0x%x\n",
1120  GetLastError());
1121 
1122  certInfo.Issuer.cbData = sizeof(encodedCommonName);
1123  certInfo.Issuer.pbData = encodedCommonName;
1124  SetLastError(0xdeadbeef);
1126  NULL, NULL);
1127  ok(!msg && (GetLastError() == E_INVALIDARG ||
1129  "Expected E_INVALIDARG or CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1130 
1131  /* The signer's hCryptProv must be set to something. Whether it's usable
1132  * or not will be checked after the hash algorithm is checked (see next
1133  * test.)
1134  */
1135  signer.hCryptProv = 1;
1136  SetLastError(0xdeadbeef);
1138  NULL, NULL);
1140  "Expected CRYPT_E_UNKNOWN_ALGO, got %x\n", GetLastError());
1141  /* The signer's hash algorithm must also be set. */
1143  SetLastError(0xdeadbeef);
1144  /* Crashes in advapi32 in wine, don't do it */
1145  if (0) {
1147  &signInfo, NULL, NULL);
1149  "Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
1150  }
1151  /* The signer's hCryptProv must also be valid. */
1152  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1154  if (!ret && GetLastError() == NTE_EXISTS) {
1155  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1156  PROV_RSA_FULL, 0);
1157  }
1158  ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1159 
1160  if (ret) {
1162  NULL, NULL);
1163  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1164  CryptMsgClose(msg);
1165  }
1166 
1167  /* pCertInfo must still be set, but can be empty if the SignerId's issuer
1168  * and serial number are set.
1169  */
1170  certInfo.Issuer.cbData = 0;
1171  certInfo.SerialNumber.cbData = 0;
1172  signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1173  U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1174  sizeof(encodedCommonName);
1175  U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1176  U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1177  sizeof(serialNum);
1178  U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1180  NULL, NULL);
1181  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1182  CryptMsgClose(msg);
1183 
1184  CryptReleaseContext(signer.hCryptProv, 0);
1185  pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
1187 }
1188 
1189 static const BYTE privKey[] = {
1190  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
1191  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
1192  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
1193  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
1194  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
1195  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
1196  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
1197  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
1198  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
1199  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
1200  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
1201  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
1202  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
1203  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
1204  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
1205  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
1206  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
1207  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
1208  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
1209  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
1210  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
1211  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
1212  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
1213  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
1214 static BYTE pubKey[] = {
1215 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,
1216 0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,
1217 0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,
1218 0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,
1219 0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
1220 
1221 static void test_signed_msg_update(void)
1222 {
1223  HCRYPTMSG msg;
1224  BOOL ret;
1225  CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1226  CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1227  CERT_INFO certInfo = { 0 };
1228  HCRYPTKEY key;
1229 
1230  certInfo.SerialNumber.cbData = sizeof(serialNum);
1231  certInfo.SerialNumber.pbData = serialNum;
1232  certInfo.Issuer.cbData = sizeof(encodedCommonName);
1233  certInfo.Issuer.pbData = encodedCommonName;
1234  signer.pCertInfo = &certInfo;
1236  signInfo.cSigners = 1;
1237  signInfo.rgSigners = &signer;
1238 
1239  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1241  if (!ret && GetLastError() == NTE_EXISTS) {
1242  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1243  PROV_RSA_FULL, 0);
1244  }
1245  ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1246 
1247  if (!ret) {
1248  skip("No context for tests\n");
1249  return;
1250  }
1251 
1253  CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1254  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1255  /* Detached CMSG_SIGNED allows non-final updates. */
1256  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1257  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1258  /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1259  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1260  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1261  /* The final update requires a private key in the hCryptProv, in order to
1262  * generate the signature.
1263  */
1264  SetLastError(0xdeadbeef);
1265  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1266  ok(!ret &&
1267  (GetLastError() == NTE_BAD_KEYSET ||
1268  GetLastError() == NTE_NO_KEY ||
1269  broken(GetLastError() == ERROR_SUCCESS)), /* Some Win9x */
1270  "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %x\n", GetLastError());
1271  ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1272  0, 0, &key);
1273  ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1274  /* The final update should be able to succeed now that a key exists, but
1275  * the previous (invalid) final update prevents it.
1276  */
1277  SetLastError(0xdeadbeef);
1278  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1280  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1281  CryptMsgClose(msg);
1282 
1284  CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1285  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1286  /* Detached CMSG_SIGNED allows non-final updates. */
1287  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1288  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1289  /* Detached CMSG_SIGNED also allows non-final updates with no data. */
1290  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1291  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1292  /* Now that the private key exists, the final update can succeed (even
1293  * with no data.)
1294  */
1295  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1296  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1297  /* But no updates are allowed after the final update. */
1298  SetLastError(0xdeadbeef);
1299  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
1301  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1302  SetLastError(0xdeadbeef);
1303  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1305  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1306  CryptMsgClose(msg);
1307 
1309  NULL, NULL);
1310  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1311  /* Non-detached messages don't allow non-final updates.. */
1312  SetLastError(0xdeadbeef);
1313  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
1315  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
1316  /* but they do allow final ones. */
1317  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1318  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1319  CryptMsgClose(msg);
1321  NULL, NULL);
1322  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1323  /* They also allow final updates with no data. */
1324  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
1325  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1326  CryptMsgClose(msg);
1327 
1329  CryptReleaseContext(signer.hCryptProv, 0);
1330  pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1332 }
1333 
1334 static const BYTE signedEmptyBareContent[] = {
1335 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1336 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1337 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1338 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1339 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1340 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1341 static const BYTE signedEmptyContent[] = {
1342 0x30,0x5f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x52,
1343 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1344 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
1345 0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1346 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,
1347 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,
1348 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1350 0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1351 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
1352 0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1353 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1354 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1355 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1356 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1357 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1358 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1359 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1360 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1361 static const BYTE detachedSignedContent[] = {
1362 0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1363 0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1364 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,
1365 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,
1366 0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1367 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,
1368 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,
1369 0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,
1370 0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,
1371 0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,
1372 0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,
1373 0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1374 static const BYTE signedBareContent[] = {
1375 0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1376 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1377 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,0x77,
1378 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1379 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1380 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1381 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1382 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1383 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1384 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1385 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1386 static const BYTE signedContent[] = {
1387 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1388 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1389 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1390 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1391 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1392 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1393 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1394 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1395 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1396 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1397 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1398 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1399 0x0d };
1400 static const BYTE signedHash[] = {
1401 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
1402 0x2f };
1403 static const BYTE signedKeyIdEmptyContent[] = {
1404 0x30,0x46,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x39,
1405 0x30,0x37,0x02,0x01,0x03,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1406 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x1e,0x30,0x1c,0x02,
1407 0x01,0x03,0x80,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1408 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1409 static const BYTE signedEncodedSigner[] = {
1410 0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1411 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1412 0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,
1413 0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,
1414 0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,
1415 0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,
1416 0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,
1417 0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1419 0x30,0x82,0x01,0x00,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1420 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1421 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x31,
1422 0x81,0xd5,0x30,0x81,0xd2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1423 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1424 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1425 0x0d,0x02,0x05,0x05,0x00,0xa0,0x5b,0x30,0x18,0x06,0x09,0x2a,0x86,0x48,0x86,
1426 0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1427 0x01,0x07,0x01,0x30,0x1e,0x06,0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,
1428 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1429 0x4c,0x61,0x6e,0x67,0x00,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1430 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,
1431 0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1432 0x40,0xbf,0x65,0xde,0x7a,0x3e,0xa2,0x19,0x59,0xc3,0xc7,0x02,0x53,0xc9,0x72,
1433 0xcd,0x74,0x96,0x70,0x0b,0x3b,0xcf,0x8b,0xd9,0x17,0x5c,0xc5,0xd1,0x83,0x41,
1434 0x32,0x93,0xa6,0xf3,0x52,0x83,0x94,0xa9,0x6b,0x0a,0x92,0xcf,0xaf,0x12,0xfa,
1435 0x40,0x53,0x12,0x84,0x03,0xab,0x10,0xa2,0x3d,0xe6,0x9f,0x5a,0xbf,0xc5,0xb8,
1436 0xff,0xc6,0x33,0x63,0x34 };
1437 static BYTE cert[] = {
1438 0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1439 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1440 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1441 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1442 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1443 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1444 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,
1445 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1446 0xff,0x02,0x01,0x01 };
1448 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1449 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1450 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1451 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1452 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1453 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1454 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1455 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1456 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1457 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1458 0x01,0x01 };
1460 0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1461 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1462 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1463 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1464 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1465 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1466 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1467 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1468 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1469 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1470 0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,
1471 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,
1472 0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
1473 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1475 0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1476 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1477 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1478 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1479 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1480 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1481 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1482 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1483 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1484 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1485 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1486 0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,
1487 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1488 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1489 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1490 0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,
1491 0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,
1492 0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,
1493 0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,
1494 0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1495 static BYTE crl[] = { 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1496 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1497 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1498 0x30,0x30,0x30,0x30,0x5a };
1500 0x30,0x81,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1501 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa1,0x2e,0x30,0x2c,
1502 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1503 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
1504 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,
1505 0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1506 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1507 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
1508 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1509 static const BYTE signedWithCrlBareContent[] = {
1510 0x30,0x81,0xd1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1511 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,
1512 0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa1,0x2e,
1513 0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1514 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,
1515 0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,
1516 0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1517 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1518 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1519 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,
1520 0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,
1521 0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,
1522 0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,
1523 0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,
1524 0xa8,0x0d };
1526 0x30,0x81,0xfe,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1527 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x7c,0x30,0x7a,
1528 0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,
1529 0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,
1530 0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1531 0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1532 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
1533 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
1534 0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
1535 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
1536 0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1537 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1538 0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
1539 0x30,0x30,0x30,0x30,0x5a,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,
1540 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1541 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,
1542 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,
1543 0x04,0x00 };
1545 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1546 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1547 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1548 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1549 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1550 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1551 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1552 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1553 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1554 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1555 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1556 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1557 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1558 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1559 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1560 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1561 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1562 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1563 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1564 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1565 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1566 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1567 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1569 0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1570 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0xa0,0x81,0x98,0x30,
1571 0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1572 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1573 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
1574 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1575 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
1576 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
1577 0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1578 0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
1579 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
1580 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
1581 0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,
1582 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1583 0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1584 0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
1586 0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1587 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1588 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1589 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1590 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1591 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1592 0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1593 0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,
1594 0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,
1595 0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,
1596 0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,
1597 0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,
1598 0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
1599 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1601 0x30,0x82,0x01,0x38,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1602 0xa0,0x82,0x01,0x29,0x30,0x82,0x01,0x25,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1603 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,
1604 0x00,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1605 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1606 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1607 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1608 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1609 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1610 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1611 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,
1612 0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,
1613 0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,
1614 0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,
1615 0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
1616 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
1617 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
1618 0xff,0x02,0x01,0x01,0x31,0x37,0x30,0x35,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,
1619 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1620 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,
1621 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1622 0x00 };
1624 0x30,0x82,0x01,0x89,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1625 0xa0,0x82,0x01,0x7a,0x30,0x82,0x01,0x76,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,
1626 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,
1627 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,
1628 0x02,0x03,0x04,0xa0,0x81,0xd2,0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,
1629 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
1630 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1631 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
1632 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
1633 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1634 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,
1635 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,
1636 0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,
1637 0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
1638 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,
1639 0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,
1640 0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,
1641 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
1642 0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
1643 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
1644 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
1645 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
1646 0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,
1647 0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,
1648 0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,
1649 0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,
1650 0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1651 
1652 static void test_signed_msg_encoding(void)
1653 {
1654  HCRYPTMSG msg;
1655  CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1656  CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1657  CERT_INFO certInfo = { 0 };
1658  CERT_BLOB encodedCert = { sizeof(cert), cert };
1659  CRL_BLOB encodedCrl = { sizeof(crl), crl };
1660  char oid_common_name[] = szOID_COMMON_NAME;
1663  CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
1664  BOOL ret;
1665  HCRYPTKEY key;
1666  DWORD size;
1667 
1668  certInfo.SerialNumber.cbData = sizeof(serialNum);
1669  certInfo.SerialNumber.pbData = serialNum;
1670  certInfo.Issuer.cbData = sizeof(encodedCommonName);
1671  certInfo.Issuer.pbData = encodedCommonName;
1672  signer.pCertInfo = &certInfo;
1674  signInfo.cSigners = 1;
1675  signInfo.rgSigners = &signer;
1676 
1677  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1679  if (!ret && GetLastError() == NTE_EXISTS) {
1680  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1681  PROV_RSA_FULL, 0);
1682  }
1683  ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1684 
1685  if (!ret) {
1686  skip("No context for tests\n");
1687  return;
1688  }
1689 
1690  ret = CryptImportKey(signer.hCryptProv, privKey, sizeof(privKey),
1691  0, 0, &key);
1692  ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
1693 
1695  CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
1696  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1697 
1698  check_param("detached signed empty bare content", msg,
1700  sizeof(signedEmptyBareContent));
1701  check_param("detached signed empty content", msg, CMSG_CONTENT_PARAM,
1703  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1704  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1705  check_param("detached signed hash", msg, CMSG_COMPUTED_HASH_PARAM,
1706  signedHash, sizeof(signedHash));
1707  check_param("detached signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1709  check_param("detached signed content", msg, CMSG_CONTENT_PARAM,
1711  SetLastError(0xdeadbeef);
1714  broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */)),
1715  "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1716  check_param("detached signed encoded signer", msg, CMSG_ENCODED_SIGNER,
1718 
1719  CryptMsgClose(msg);
1720 
1721  certInfo.SerialNumber.cbData = 0;
1722  certInfo.Issuer.cbData = 0;
1723  signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
1724  U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
1725  U(signer.SignerId).KeyId.pbData = serialNum;
1727  NULL, NULL);
1728  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1729  check_param("signed key id empty content", msg, CMSG_CONTENT_PARAM,
1731  CryptMsgClose(msg);
1732 
1733  certInfo.SerialNumber.cbData = sizeof(serialNum);
1734  certInfo.SerialNumber.pbData = serialNum;
1735  certInfo.Issuer.cbData = sizeof(encodedCommonName);
1736  certInfo.Issuer.pbData = encodedCommonName;
1737  signer.SignerId.dwIdChoice = 0;
1739  NULL, NULL);
1740  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1741 
1742  check_param("signed empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
1744  check_param("signed empty content", msg, CMSG_CONTENT_PARAM,
1746  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1747  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1748  check_param("signed bare content", msg, CMSG_BARE_CONTENT_PARAM,
1750  check_param("signed content", msg, CMSG_CONTENT_PARAM,
1751  signedContent, sizeof(signedContent));
1752 
1753  CryptMsgClose(msg);
1754 
1755  signer.cAuthAttr = 1;
1756  signer.rgAuthAttr = &attr;
1758  NULL, NULL);
1759  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1760 
1761  CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1762  check_param("signed with auth attrs bare content", msg,
1765 
1766  CryptMsgClose(msg);
1767 
1768  signer.cAuthAttr = 0;
1769  signInfo.rgCertEncoded = &encodedCert;
1770  signInfo.cCertEncoded = 1;
1772  NULL, NULL);
1773  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1774 
1775  check_param("signed with cert empty bare content", msg,
1778  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1779  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1780  check_param("signed with cert bare content", msg, CMSG_BARE_CONTENT_PARAM,
1782 
1783  CryptMsgClose(msg);
1784 
1785  signInfo.cCertEncoded = 0;
1786  signInfo.rgCrlEncoded = &encodedCrl;
1787  signInfo.cCrlEncoded = 1;
1789  NULL, NULL);
1790  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1791 
1792  check_param("signed with crl empty bare content", msg,
1795  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1796  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1797  check_param("signed with crl bare content", msg, CMSG_BARE_CONTENT_PARAM,
1799 
1800  CryptMsgClose(msg);
1801 
1802  signInfo.cCertEncoded = 1;
1804  NULL, NULL);
1805  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1806 
1807  check_param("signed with cert and crl empty bare content", msg,
1810  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1811  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
1812  check_param("signed with cert and crl bare content", msg,
1815 
1816  CryptMsgClose(msg);
1817 
1818  /* Test with a cert with a (bogus) public key */
1819  signInfo.cCrlEncoded = 0;
1820  encodedCert.cbData = sizeof(v1CertWithPubKey);
1821  encodedCert.pbData = v1CertWithPubKey;
1823  NULL, NULL);
1824  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1825  check_param("signedWithCertWithPubKeyBareContent", msg,
1828  CryptMsgClose(msg);
1829 
1830  encodedCert.cbData = sizeof(v1CertWithValidPubKey);
1831  encodedCert.pbData = v1CertWithValidPubKey;
1833  NULL, NULL);
1834  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1835  check_param("signedWithCertWithValidPubKeyEmptyContent", msg,
1838  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
1839  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
1840  check_param("signedWithCertWithValidPubKeyContent", msg,
1843  CryptMsgClose(msg);
1844 
1846  CryptReleaseContext(signer.hCryptProv, 0);
1847  pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL, PROV_RSA_FULL,
1849 }
1850 
1851 static void test_signed_msg_get_param(void)
1852 {
1853  BOOL ret;
1854  HCRYPTMSG msg;
1855  DWORD size, value = 0;
1856  CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
1857  CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
1858  CERT_INFO certInfo = { 0 };
1859 
1861  NULL, NULL);
1862  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1863 
1864  /* Content and bare content are always gettable */
1865  size = 0;
1867  ok(ret || broken(!ret /* Win9x */), "CryptMsgGetParam failed: %08x\n",
1868  GetLastError());
1869  if (!ret)
1870  {
1871  skip("message parameters are broken, skipping tests\n");
1872  return;
1873  }
1874  size = 0;
1876  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1877  /* For "signed" messages, so is the version. */
1878  size = 0;
1880  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1881  size = sizeof(value);
1883  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1884  ok(value == CMSG_SIGNED_DATA_V1, "Expected version 1, got %d\n", value);
1885  /* But for this message, with no signers, the hash and signer aren't
1886  * available.
1887  */
1888  size = 0;
1889  SetLastError(0xdeadbeef);
1892  "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1893  SetLastError(0xdeadbeef);
1896  "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1897  /* As usual, the type isn't available. */
1900  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1901 
1902  CryptMsgClose(msg);
1903 
1904  certInfo.SerialNumber.cbData = sizeof(serialNum);
1905  certInfo.SerialNumber.pbData = serialNum;
1906  certInfo.Issuer.cbData = sizeof(encodedCommonName);
1907  certInfo.Issuer.pbData = encodedCommonName;
1908  signer.pCertInfo = &certInfo;
1910  signInfo.cSigners = 1;
1911  signInfo.rgSigners = &signer;
1912 
1913  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1915  if (!ret && GetLastError() == NTE_EXISTS) {
1916  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1917  PROV_RSA_FULL, 0);
1918  }
1919  ok(ret, "CryptAcquireContext failed: 0x%x\n", GetLastError());
1920 
1921  if (!ret) {
1922  skip("No context for tests\n");
1923  return;
1924  }
1925 
1927  NULL, NULL);
1928  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1929 
1930  /* This message, with one signer, has the hash and signer for index 0
1931  * available, but not for other indexes.
1932  */
1933  size = 0;
1935  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1937  ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
1938  size = 0;
1939  SetLastError(0xdeadbeef);
1942  "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1943  SetLastError(0xdeadbeef);
1946  "Expected CRYPT_E_INVALID_INDEX, got %x\n", GetLastError());
1947  /* As usual, the type isn't available. */
1950  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
1951 
1952  CryptMsgClose(msg);
1953 
1954  /* Opening the message using the CMS fields.. */
1955  certInfo.SerialNumber.cbData = 0;
1956  certInfo.Issuer.cbData = 0;
1957  signer.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
1958  U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
1959  sizeof(encodedCommonName);
1960  U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
1961  U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
1962  sizeof(serialNum);
1963  U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
1964  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1966  if (!ret && GetLastError() == NTE_EXISTS)
1967  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
1968  PROV_RSA_FULL, 0);
1969  ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
1972  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
1973  /* still results in the version being 1 when the issuer and serial number
1974  * are used and no additional CMS fields are used.
1975  */
1976  size = sizeof(value);
1979  "CryptMsgGetParam failed: %08x\n", GetLastError());
1980  if (ret)
1981  ok(value == CMSG_SIGNED_DATA_V1, "expected version 1, got %d\n", value);
1982  /* Apparently the encoded signer can be retrieved.. */
1984  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1985  /* but the signer info, CMS signer info, and cert ID can't be. */
1986  SetLastError(0xdeadbeef);
1989  "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1990  SetLastError(0xdeadbeef);
1993  "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1994  SetLastError(0xdeadbeef);
1997  "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1998  CryptMsgClose(msg);
1999 
2000  /* Using the KeyId field of the SignerId results in the version becoming
2001  * the CMS version.
2002  */
2003  signer.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
2004  U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
2005  U(signer.SignerId).KeyId.pbData = serialNum;
2006  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2008  if (!ret && GetLastError() == NTE_EXISTS)
2009  ret = pCryptAcquireContextA(&signer.hCryptProv, cspNameA, NULL,
2010  PROV_RSA_FULL, 0);
2011  ok(ret, "CryptAcquireContextA failed: %x\n", GetLastError());
2014  ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
2015  size = sizeof(value);
2017  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2018  if (ret)
2019  ok(value == CMSG_SIGNED_DATA_V3, "expected version 3, got %d\n", value);
2020  /* Even for a CMS message, the signer can be retrieved.. */
2022  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2023  /* but the signer info, CMS signer info, and cert ID can't be. */
2024  SetLastError(0xdeadbeef);
2027  "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2028  SetLastError(0xdeadbeef);
2031  "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2032  SetLastError(0xdeadbeef);
2035  "expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
2036  CryptMsgClose(msg);
2037 
2038  CryptReleaseContext(signer.hCryptProv, 0);
2039  pCryptAcquireContextA(&signer.hCryptProv, cspNameA, MS_DEF_PROV_A,
2041 }
2042 
2043 static void test_signed_msg(void)
2044 {
2049 }
2050 
2051 static char oid_rsa_rc4[] = szOID_RSA_RC4;
2052 
2053 static void test_enveloped_msg_open(void)
2054 {
2055  HCRYPTMSG msg;
2056  BOOL ret;
2057  CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { 0 };
2059 
2060  SetLastError(0xdeadbeef);
2062  &envelopedInfo, NULL, NULL);
2063  ok(!msg && GetLastError() == E_INVALIDARG,
2064  "expected E_INVALIDARG, got %08x\n", GetLastError());
2065 
2066  envelopedInfo.cbSize = sizeof(envelopedInfo);
2067  SetLastError(0xdeadbeef);
2069  &envelopedInfo, NULL, NULL);
2070  ok(!msg &&
2072  GetLastError() == E_INVALIDARG), /* Win9x */
2073  "expected CRYPT_E_UNKNOWN_ALGO or E_INVALIDARG, got %08x\n", GetLastError());
2074 
2076  SetLastError(0xdeadbeef);
2078  &envelopedInfo, NULL, NULL);
2079  ok(msg != NULL ||
2080  broken(!msg), /* Win9x */
2081  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2082  CryptMsgClose(msg);
2083 
2084  envelopedInfo.cRecipients = 1;
2085  if (!old_crypt32)
2086  {
2087  SetLastError(0xdeadbeef);
2089  &envelopedInfo, NULL, NULL);
2090  ok(!msg && GetLastError() == E_INVALIDARG,
2091  "expected E_INVALIDARG, got %08x\n", GetLastError());
2092  }
2093 
2096  if (context)
2097  {
2098  envelopedInfo.rgpRecipientCert = (PCERT_INFO *)&context->pCertInfo;
2099  SetLastError(0xdeadbeef);
2101  &envelopedInfo, NULL, NULL);
2102  ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2103  CryptMsgClose(msg);
2104  SetLastError(0xdeadbeef);
2105  ret = pCryptAcquireContextA(&envelopedInfo.hCryptProv, NULL, NULL,
2107  ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError());
2108  SetLastError(0xdeadbeef);
2110  &envelopedInfo, NULL, NULL);
2111  ok(msg != NULL, "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2112  CryptMsgClose(msg);
2113  CryptReleaseContext(envelopedInfo.hCryptProv, 0);
2115  }
2116  else
2117  win_skip("failed to create certificate context, skipping tests\n");
2118 }
2119 
2120 static void test_enveloped_msg_update(void)
2121 {
2122  HCRYPTMSG msg;
2123  BOOL ret;
2124  CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2125  { oid_rsa_rc4, { 0, NULL } }, NULL };
2126  CMSG_STREAM_INFO streamInfo = { 0, nop_stream_output, NULL };
2127 
2128  SetLastError(0xdeadbeef);
2130  &envelopedInfo, NULL, NULL);
2131  ok(msg != NULL ||
2132  broken(!msg), /* Win9x */
2133  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2134  if (msg)
2135  {
2136  SetLastError(0xdeadbeef);
2137  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2139  "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2140  SetLastError(0xdeadbeef);
2141  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2142  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2143  SetLastError(0xdeadbeef);
2144  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2146  "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2147  CryptMsgClose(msg);
2148  }
2149  SetLastError(0xdeadbeef);
2151  &envelopedInfo, NULL, NULL);
2152  ok(msg != NULL ||
2153  broken(!msg), /* Win9x */
2154  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2155  if (msg)
2156  {
2157  SetLastError(0xdeadbeef);
2158  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2160  "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2161  SetLastError(0xdeadbeef);
2162  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2163  ok(ret ||
2164  broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2165  "CryptMsgUpdate failed: %08x\n", GetLastError());
2166  SetLastError(0xdeadbeef);
2167  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2169  "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2170  CryptMsgClose(msg);
2171  }
2172  SetLastError(0xdeadbeef);
2174  CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2175  ok(msg != NULL ||
2176  broken(!msg), /* Win9x */
2177  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2178  if (msg)
2179  {
2180  SetLastError(0xdeadbeef);
2181  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2182  ok(!ret && GetLastError() == E_INVALIDARG,
2183  "expected E_INVALIDARG, got %08x\n", GetLastError());
2184  SetLastError(0xdeadbeef);
2185  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2186  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2187  CryptMsgClose(msg);
2188  }
2189  SetLastError(0xdeadbeef);
2191  CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
2192  ok(msg != NULL ||
2193  broken(!msg), /* Win9x */
2194  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2195  if (msg)
2196  {
2197  SetLastError(0xdeadbeef);
2198  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2199  ok(!ret && GetLastError() == E_INVALIDARG,
2200  "expected E_INVALIDARG, got %08x\n", GetLastError());
2201  SetLastError(0xdeadbeef);
2202  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2203  ok(ret ||
2204  broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2205  "CryptMsgUpdate failed: %08x\n", GetLastError());
2206  CryptMsgClose(msg);
2207  }
2208  SetLastError(0xdeadbeef);
2210  &envelopedInfo, NULL, &streamInfo);
2211  ok(msg != NULL ||
2212  broken(!msg), /* Win9x */
2213  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2214  if (msg)
2215  {
2216  SetLastError(0xdeadbeef);
2217  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2218  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2219  SetLastError(0xdeadbeef);
2220  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2221  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2222  CryptMsgClose(msg);
2223  }
2224  SetLastError(0xdeadbeef);
2226  &envelopedInfo, NULL, &streamInfo);
2227  ok(msg != NULL ||
2228  broken(!msg), /* Win9x */
2229  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2230  if (msg)
2231  {
2232  SetLastError(0xdeadbeef);
2233  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2234  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2235  SetLastError(0xdeadbeef);
2236  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2237  ok(ret ||
2238  broken(!ret && GetLastError() == NTE_PERM), /* some NT4 */
2239  "CryptMsgUpdate failed: %08x\n", GetLastError());
2240  CryptMsgClose(msg);
2241  }
2242 }
2243 
2245 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2246 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2247 0x03,0x04,0x05,0x00,0x80,0x00 };
2248 static const BYTE envelopedEmptyContent[] = {
2249 0x30,0x31,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,0x24,
2250 0x30,0x22,0x02,0x01,0x00,0x31,0x00,0x30,0x1b,0x06,0x09,0x2a,0x86,0x48,0x86,
2251 0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2252 0x03,0x04,0x05,0x00,0x80,0x00 };
2253 
2255 {
2256  HCRYPTMSG msg;
2257  CMSG_ENVELOPED_ENCODE_INFO envelopedInfo = { sizeof(envelopedInfo), 0,
2258  { oid_rsa_rc4, { 0, NULL } }, NULL };
2259 
2260  SetLastError(0xdeadbeef);
2262  &envelopedInfo, NULL, NULL);
2263  ok(msg != NULL ||
2264  broken(!msg), /* Win9x */
2265  "CryptMsgOpenToEncode failed: %08x\n", GetLastError());
2266  if (msg)
2267  {
2268  check_param("enveloped empty bare content", msg,
2270  sizeof(envelopedEmptyBareContent));
2271  check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM,
2273  CryptMsgClose(msg);
2274  }
2275 }
2276 
2277 static void test_enveloped_msg(void)
2278 {
2282 }
2283 
2284 static CRYPT_DATA_BLOB b4 = { 0, NULL };
2285 static const struct update_accum a4 = { 1, &b4 };
2286 
2287 static const BYTE bogusOIDContent[] = {
2288 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x07,0xa0,0x02,
2289 0x04,0x00 };
2290 static const BYTE bogusHashContent[] = {
2291 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
2292 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
2293 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2294 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x00,0xd6,0xc0,
2295 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2297 0x30,0x81,0xdb,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2298 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2299 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2300 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2301 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x87,0x46,0x26,0x56,0xe3,0xf3,0xa5,0x5b,
2302 0xd4,0x2c,0x03,0xcc,0x52,0x7e,0xf7,0x55,0xf1,0x34,0x9f,0x63,0xf6,0x04,0x9f,
2303 0xc5,0x13,0xf1,0xc9,0x57,0x0a,0xbc,0xa9,0x33,0xd2,0xf2,0x93,0xb6,0x5c,0x94,
2304 0xc3,0x49,0xd6,0xd6,0x6d,0xc4,0x91,0x38,0x80,0xdd,0x0d,0x82,0xef,0xe5,0x72,
2305 0x55,0x40,0x0a,0xdd,0x35,0xfe,0xdc,0x87,0x47,0x92,0xb1,0xbd,0x05,0xc9,0x18,
2306 0x0e,0xde,0x4b,0x00,0x70,0x40,0x31,0x1f,0x5d,0x6c,0x8f,0x3a,0xfb,0x9a,0xc3,
2307 0xb3,0x06,0xe7,0x68,0x3f,0x20,0x14,0x1c,0xf9,0x28,0x4b,0x0f,0x01,0x01,0xb6,
2308 0xfe,0x07,0xe5,0xd8,0xf0,0x7c,0x17,0xbc,0xec,0xfb,0xd7,0x73,0x8a,0x71,0x49,
2309 0x79,0x62,0xe4,0xbf,0xb5,0xe3,0x56,0xa6,0xb4,0x49,0x1e,0xdc,0xaf,0xd7,0x0e,
2310 0x30,0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2311 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00 };
2312 
2313 static void test_decode_msg_update(void)
2314 {
2315  HCRYPTMSG msg;
2316  BOOL ret;
2317  CMSG_STREAM_INFO streamInfo = { 0 };
2318  DWORD i;
2319  struct update_accum accum = { 0, NULL };
2320 
2322  /* Update with a full message in a final update */
2324  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2325  /* Can't update after a final update */
2326  SetLastError(0xdeadbeef);
2329  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2330  CryptMsgClose(msg);
2331 
2333  /* Can't send a non-final update without streaming */
2334  SetLastError(0xdeadbeef);
2336  FALSE);
2338  "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
2339  /* A subsequent final update succeeds */
2341  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2342  CryptMsgClose(msg);
2343 
2344  if (!old_crypt32)
2345  {
2346  msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2347  /* Updating a message that has a NULL stream callback fails */
2348  SetLastError(0xdeadbeef);
2349  /* Crashes on some Win9x */
2351  FALSE);
2352  todo_wine
2354  GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2355  "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2356  GetLastError());
2357  /* Changing the callback pointer after the fact yields the same error (so
2358  * the message must copy the stream info, not just store a pointer to it)
2359  */
2360  streamInfo.pfnStreamOutput = nop_stream_output;
2361  SetLastError(0xdeadbeef);
2363  FALSE);
2364  todo_wine
2366  GetLastError() == STATUS_ILLEGAL_INSTRUCTION /* WinME */),
2367  "Expected STATUS_ACCESS_VIOLATION or STATUS_ILLEGAL_INSTRUCTION, got %x\n",
2368  GetLastError());
2369  CryptMsgClose(msg);
2370  }
2371 
2372  /* Empty non-final updates are allowed when streaming.. */
2373  msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2374  ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
2375  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2376  /* but final updates aren't when not enough data has been received. */
2377  SetLastError(0xdeadbeef);
2378  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2379  todo_wine
2381  "Expected CRYPT_E_STREAM_INSUFFICIENT_DATA, got %x\n", GetLastError());
2382  CryptMsgClose(msg);
2383 
2384  /* Updating the message byte by byte is legal */
2386  streamInfo.pvArg = &accum;
2387  msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2388  for (i = 0, ret = TRUE; ret && i < sizeof(dataEmptyContent); i++)
2390  ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2391  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2392  ok(ret, "CryptMsgUpdate failed on byte %d: %x\n", i, GetLastError());
2393  CryptMsgClose(msg);
2394  todo_wine
2395  check_updates("byte-by-byte empty content", &a4, &accum);
2396  free_updates(&accum);
2397 
2398  /* Decoding bogus content fails in non-streaming mode.. */
2400  SetLastError(0xdeadbeef);
2401  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2402  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2403  GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2404  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2405  GetLastError());
2406  CryptMsgClose(msg);
2407  /* and as the final update in streaming mode.. */
2408  streamInfo.pfnStreamOutput = nop_stream_output;
2409  msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2410  SetLastError(0xdeadbeef);
2411  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
2412  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2413  GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2414  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2415  GetLastError());
2416  CryptMsgClose(msg);
2417  /* and even as a non-final update in streaming mode. */
2418  streamInfo.pfnStreamOutput = nop_stream_output;
2419  msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, &streamInfo);
2420  SetLastError(0xdeadbeef);
2421  ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
2422  todo_wine
2423  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2424  GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2425  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2426  GetLastError());
2427  CryptMsgClose(msg);
2428 
2429  /* An empty message can be opened with undetermined type.. */
2432  TRUE);
2433  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2434  CryptMsgClose(msg);
2435  /* but decoding it as an explicitly typed message fails. */
2437  NULL);
2438  SetLastError(0xdeadbeef);
2440  TRUE);
2441  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2442  GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2443  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2444  GetLastError());
2445  CryptMsgClose(msg);
2446  /* On the other hand, decoding the bare content of an empty message fails
2447  * with unspecified type..
2448  */
2450  SetLastError(0xdeadbeef);
2452  sizeof(dataEmptyBareContent), TRUE);
2453  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2454  GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
2455  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %x\n",
2456  GetLastError());
2457  CryptMsgClose(msg);
2458  /* but succeeds with explicit type. */
2460  NULL);
2462  sizeof(dataEmptyBareContent), TRUE);
2463  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2464  CryptMsgClose(msg);
2465 
2466  /* Decoding valid content with an unsupported OID fails */
2468  SetLastError(0xdeadbeef);
2471  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2472  CryptMsgClose(msg);
2473 
2474  /* Similarly, opening an empty hash with unspecified type succeeds.. */
2476  SetLastError(0xdeadbeef);
2478  ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2479  "CryptMsgUpdate failed: %08x\n", GetLastError());
2480  CryptMsgClose(msg);
2481  /* while with specified type it fails. */
2483  NULL);
2484  SetLastError(0xdeadbeef);
2486  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2487  GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2488  GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2489  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2490  GetLastError());
2491  CryptMsgClose(msg);
2492  /* On the other hand, decoding the bare content of an empty hash message
2493  * fails with unspecified type..
2494  */
2496  SetLastError(0xdeadbeef);
2498  sizeof(hashEmptyBareContent), TRUE);
2499  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2500  GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2501  GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2502  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2503  GetLastError());
2504  CryptMsgClose(msg);
2505  /* but succeeds with explicit type. */
2507  NULL);
2509  sizeof(hashEmptyBareContent), TRUE);
2510  ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win9x */),
2511  "CryptMsgUpdate failed: %x\n", GetLastError());
2512  CryptMsgClose(msg);
2513 
2514  /* And again, opening a (non-empty) hash message with unspecified type
2515  * succeeds..
2516  */
2518  SetLastError(0xdeadbeef);
2520  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2521  CryptMsgClose(msg);
2522  /* while with specified type it fails.. */
2524  NULL);
2525  SetLastError(0xdeadbeef);
2527  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2528  GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2529  GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2530  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2531  GetLastError());
2532  CryptMsgClose(msg);
2533  /* and decoding the bare content of a non-empty hash message fails with
2534  * unspecified type..
2535  */
2537  SetLastError(0xdeadbeef);
2539  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2540  GetLastError() == OSS_PDU_MISMATCH /* some Win9x */ ||
2541  GetLastError() == OSS_DATA_ERROR /* some Win9x */),
2542  "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH or OSS_DATA_ERROR, got %x\n",
2543  GetLastError());
2544  CryptMsgClose(msg);
2545  /* but succeeds with explicit type. */
2547  NULL);
2549  ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
2550  CryptMsgClose(msg);
2551 
2552  /* Opening a (non-empty) hash message with unspecified type and a bogus
2553  * hash value succeeds..
2554  */
2556  SetLastError(0xdeadbeef);
2558  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2559  CryptMsgClose(msg);
2560 
2563  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2564  CryptMsgClose(msg);
2566  SetLastError(0xdeadbeef);
2569  ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2570  GetLastError() == OSS_DATA_ERROR /* Win9x */),
2571  "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
2572  GetLastError());
2573  CryptMsgClose(msg);
2575  NULL);
2578  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2579  CryptMsgClose(msg);
2580 
2582  NULL, NULL);
2583  /* The first update succeeds.. */
2585  sizeof(detachedSignedContent), TRUE);
2586  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2587  /* as does a second (probably to update the detached portion).. */
2589  sizeof(detachedSignedContent), TRUE);
2590  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2591  /* while a third fails. */
2593  sizeof(detachedSignedContent), TRUE);
2595  "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2596  CryptMsgClose(msg);
2597 
2600  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2601  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2602  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2604  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2605  ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
2606  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2607 
2610  "expected CRYPT_E_MSG_ERROR, got %08x\n", GetLastError());
2611  CryptMsgClose(msg);
2612 
2614  NULL);
2615  SetLastError(0xdeadbeef);
2617  sizeof(envelopedEmptyBareContent), TRUE);
2618  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2619  CryptMsgClose(msg);
2620 
2622  NULL);
2623  SetLastError(0xdeadbeef);
2625  sizeof(envelopedEmptyContent), TRUE);
2626  ok(!ret &&
2628  GetLastError() == OSS_DATA_ERROR), /* Win9x */
2629  "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2630  CryptMsgClose(msg);
2631 
2633  SetLastError(0xdeadbeef);
2635  sizeof(envelopedEmptyBareContent), TRUE);
2636  ok(!ret &&
2638  GetLastError() == OSS_DATA_ERROR), /* Win9x */
2639  "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2640  CryptMsgClose(msg);
2641 
2643  SetLastError(0xdeadbeef);
2645  sizeof(envelopedEmptyContent), TRUE);
2646  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2647  CryptMsgClose(msg);
2648 
2650  NULL);
2651  SetLastError(0xdeadbeef);
2654  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2655  CryptMsgClose(msg);
2656 }
2657 
2658 static const BYTE hashParam[] = { 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,
2659  0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
2660 
2661 static void compare_signer_info(const CMSG_SIGNER_INFO *got,
2662  const CMSG_SIGNER_INFO *expected)
2663 {
2664  ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2665  expected->dwVersion, got->dwVersion);
2666  ok(got->Issuer.cbData == expected->Issuer.cbData,
2667  "Expected issuer size %d, got %d\n", expected->Issuer.cbData,
2668  got->Issuer.cbData);
2669  ok(!memcmp(got->Issuer.pbData, expected->Issuer.pbData, got->Issuer.cbData),
2670  "Unexpected issuer\n");
2671  ok(got->SerialNumber.cbData == expected->SerialNumber.cbData,
2672  "Expected serial number size %d, got %d\n", expected->SerialNumber.cbData,
2673  got->SerialNumber.cbData);
2674  ok(!memcmp(got->SerialNumber.pbData, expected->SerialNumber.pbData,
2675  got->SerialNumber.cbData), "Unexpected serial number\n");
2676  /* FIXME: check more things */
2677 }
2678 
2681 {
2682  ok(got->dwVersion == expected->dwVersion, "Expected version %d, got %d\n",
2683  expected->dwVersion, got->dwVersion);
2684  ok(got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice,
2685  "Expected id choice %d, got %d\n", expected->SignerId.dwIdChoice,
2686  got->SignerId.dwIdChoice);
2687  if (got->SignerId.dwIdChoice == expected->SignerId.dwIdChoice)
2688  {
2690  {
2691  ok(U(got->SignerId).IssuerSerialNumber.Issuer.cbData ==
2692  U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2693  "Expected issuer size %d, got %d\n",
2694  U(expected->SignerId).IssuerSerialNumber.Issuer.cbData,
2695  U(got->SignerId).IssuerSerialNumber.Issuer.cbData);
2696  ok(!memcmp(U(got->SignerId).IssuerSerialNumber.Issuer.pbData,
2697  U(expected->SignerId).IssuerSerialNumber.Issuer.pbData,
2698  U(got->SignerId).IssuerSerialNumber.Issuer.cbData),
2699  "Unexpected issuer\n");
2700  ok(U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
2701  U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2702  "Expected serial number size %d, got %d\n",
2703  U(expected->SignerId).IssuerSerialNumber.SerialNumber.cbData,
2704  U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData);
2705  ok(!memcmp(U(got->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2706  U(expected->SignerId).IssuerSerialNumber.SerialNumber.pbData,
2707  U(got->SignerId).IssuerSerialNumber.SerialNumber.cbData),
2708  "Unexpected serial number\n");
2709  }
2710  else
2711  {
2712  ok(U(got->SignerId).KeyId.cbData == U(expected->SignerId).KeyId.cbData,
2713  "expected key id size %d, got %d\n",
2714  U(expected->SignerId).KeyId.cbData, U(got->SignerId).KeyId.cbData);
2715  ok(!memcmp(U(expected->SignerId).KeyId.pbData,
2716  U(got->SignerId).KeyId.pbData, U(got->SignerId).KeyId.cbData),
2717  "unexpected key id\n");
2718  }
2719  }
2720  /* FIXME: check more things */
2721 }
2722 
2724 0x08,0xd6,0xc0,0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,
2725 0x2f };
2726 static BYTE keyIdIssuer[] = {
2727 0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,
2728 0x0a,0x07,0x01,0x04,0x01,0x01 };
2729 static const BYTE publicPrivateKeyPair[] = {
2730 0x07,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x32,0x00,0x04,0x00,
2731 0x00,0x01,0x00,0x01,0x00,0x21,0x65,0x5d,0x97,0x19,0x3f,0xd0,0xd0,0x76,0x5b,
2732 0xb1,0x10,0x4e,0xcc,0x14,0xb5,0x92,0x0f,0x60,0xad,0xb6,0x74,0x8d,0x94,0x50,
2733 0xfd,0x14,0x5e,0xbc,0xf1,0x93,0xbf,0x24,0x21,0x64,0x9d,0xc7,0x77,0x04,0x54,
2734 0xd1,0xbd,0x3e,0xd8,0x3b,0x2a,0x8b,0x95,0x70,0xdf,0x19,0x20,0xed,0x76,0x39,
2735 0xfa,0x64,0x04,0xc6,0xf7,0x33,0x7b,0xaa,0x94,0x67,0x74,0xbc,0x6b,0xd5,0xa7,
2736 0x69,0x99,0x99,0x47,0x88,0xc0,0x7e,0x36,0xf1,0xc5,0x7d,0xa8,0xd8,0x07,0x48,
2737 0xe6,0x05,0x4f,0xf4,0x1f,0x37,0xd7,0xc7,0xa7,0x00,0x20,0xb3,0xe5,0x40,0x17,
2738 0x86,0x43,0x77,0xe0,0x32,0x39,0x11,0x9c,0xd9,0xd8,0x53,0x9b,0x45,0x42,0x54,
2739 0x65,0xca,0x15,0xbe,0xb2,0x44,0xf1,0xd0,0xf3,0xb6,0x4a,0x19,0xc8,0x3d,0x33,
2740 0x63,0x93,0x4f,0x7c,0x67,0xc6,0x58,0x6d,0xf6,0xb7,0x20,0xd8,0x30,0xcc,0x52,
2741 0xaa,0x68,0x66,0xf6,0x86,0xf8,0xe0,0x3a,0x73,0x0e,0x9d,0xc5,0x03,0x60,0x9e,
2742 0x08,0xe9,0x5e,0xd4,0x5e,0xcc,0xbb,0xc1,0x48,0xad,0x9d,0xbb,0xfb,0x26,0x61,
2743 0xa8,0x0e,0x9c,0xba,0xf1,0xd0,0x0b,0x5f,0x87,0xd4,0xb5,0xd2,0xdf,0x41,0xcb,
2744 0x7a,0xec,0xb5,0x87,0x59,0x6a,0x9d,0xb3,0x6c,0x06,0xee,0x1f,0xc5,0xae,0x02,
2745 0xa8,0x7f,0x33,0x6e,0x30,0x50,0x6d,0x65,0xd0,0x1f,0x00,0x47,0x43,0x25,0x90,
2746 0x4a,0xa8,0x74,0x8c,0x23,0x8b,0x15,0x8a,0x74,0xd2,0x03,0xa6,0x1c,0xc1,0x7e,
2747 0xbb,0xb1,0xa6,0x80,0x05,0x2b,0x62,0xfb,0x89,0xe5,0xba,0xc6,0xcc,0x12,0xce,
2748 0xa8,0xe9,0xc4,0xb5,0x9d,0xd8,0x11,0xdd,0x95,0x90,0x71,0xb0,0xfe,0xaa,0x14,
2749 0xce,0xd5,0xd0,0x5a,0x88,0x47,0xda,0x31,0xda,0x26,0x11,0x66,0xd1,0xd5,0xc5,
2750 0x1b,0x08,0xbe,0xc6,0xf3,0x15,0xbf,0x80,0x78,0xcf,0x55,0xe0,0x61,0xee,0xf5,
2751 0x71,0x1e,0x2f,0x0e,0xb3,0x67,0xf7,0xa1,0x86,0x04,0xcf,0x4b,0xc1,0x2f,0x94,
2752 0x73,0xd1,0x5d,0x0c,0xee,0x10,0x58,0xbb,0x74,0x0c,0x61,0x02,0x15,0x69,0x68,
2753 0xe0,0x21,0x3e,0xa6,0x27,0x22,0x8c,0xc8,0x61,0xbc,0xba,0xa9,0x4b,0x2e,0x71,
2754 0x77,0x74,0xdc,0x63,0x05,0x32,0x7a,0x93,0x4f,0xbf,0xc7,0xa5,0x3a,0xe3,0x25,
2755 0x4d,0x67,0xcf,0x78,0x1b,0x85,0x22,0x6c,0xfe,0x5c,0x34,0x0e,0x27,0x12,0xbc,
2756 0xd5,0x33,0x1a,0x75,0x8a,0x9c,0x40,0x39,0xe8,0xa0,0xc9,0xae,0xf8,0xaf,0x9a,
2757 0xc6,0x62,0x47,0xf3,0x5b,0xdf,0x5e,0xcd,0xc6,0xc0,0x5c,0xd7,0x0e,0x04,0x64,
2758 0x3d,0xdd,0x57,0xef,0xf6,0xcd,0xdf,0xd2,0x7e,0x17,0x6c,0x0a,0x47,0x5e,0x77,
2759 0x4b,0x02,0x49,0x78,0xc0,0xf7,0x09,0x6e,0xdf,0x96,0x04,0x51,0x74,0x3d,0x68,
2760 0x99,0x43,0x8e,0x03,0x16,0x46,0xa4,0x04,0x84,0x01,0x6e,0xd4,0xca,0x5c,0xab,
2761 0xb0,0xd3,0x82,0xf1,0xb9,0xba,0x51,0x99,0x03,0xe9,0x7f,0xdf,0x30,0x3b,0xf9,
2762 0x18,0xbb,0x80,0x7f,0xf0,0x89,0xbb,0x6d,0x98,0x95,0xb7,0xfd,0xd8,0xdf,0xed,
2763 0xf3,0x16,0x6f,0x96,0x4f,0xfd,0x54,0x66,0x6d,0x90,0xba,0xf5,0xcc,0xce,0x01,
2764 0x34,0x34,0x51,0x07,0x66,0x20,0xfb,0x4a,0x3c,0x7e,0x19,0xf8,0x8e,0x35,0x0e,
2765 0x07,0x48,0x74,0x38,0xd2,0x18,0xaa,0x2e,0x90,0x5e,0x0e,0xcc,0x50,0x6e,0x71,
2766 0x6f,0x54,0xdb,0xbf,0x7b,0xb4,0xf4,0x79,0x6a,0x21,0xa3,0x6d,0xdf,0x61,0xc0,
2767 0x8f,0xb3,0xb6,0xe1,0x8a,0x65,0x21,0x6e,0xf6,0x5b,0x80,0xf0,0xfb,0x28,0x87,
2768 0x13,0x06,0xd6,0xbc,0x28,0x5c,0xda,0xc5,0x13,0x13,0x44,0x8d,0xf4,0xa8,0x7b,
2769 0x5c,0x2a,0x7f,0x11,0x16,0x4e,0x52,0x41,0xe9,0xe7,0x8e };
2770 static const BYTE envelopedMessage[] = {
2771 0x30,0x81,0xf2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,0xa0,
2772 0x81,0xe4,0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,
2773 0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,
2774 0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,
2775 0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
2776 0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xc2,0x0d,0x59,0x87,0xb3,0x65,
2777 0xd2,0x64,0xcd,0xba,0xe3,0xaf,0x1e,0xa1,0xd3,0xdd,0xb3,0x53,0xfc,0x2f,0xae,
2778 0xdc,0x6d,0x2a,0x81,0x84,0x38,0x6f,0xdf,0x81,0xb1,0x65,0xba,0xac,0x59,0xb1,
2779 0x19,0x12,0x3f,0xde,0x12,0xce,0x77,0x42,0x71,0x67,0xa9,0x78,0x38,0x95,0x51,
2780 0xbb,0x66,0x78,0xbf,0xaf,0x0a,0x98,0x4b,0xba,0xa5,0xf0,0x8b,0x9f,0xef,0xcf,
2781 0x40,0x05,0xa1,0xd6,0x10,0xae,0xbf,0xb9,0xbd,0x4d,0x22,0x39,0x33,0x63,0x2b,
2782 0x0b,0xd3,0x0c,0xb5,0x4b,0xe8,0xfe,0x15,0xa8,0xa5,0x2c,0x86,0x33,0x80,0x6e,
2783 0x4c,0x7a,0x99,0x3c,0x6b,0x4b,0x60,0xfd,0x8e,0xb2,0xf3,0x82,0x2f,0x3e,0x1e,
2784 0xba,0xb9,0x78,0x24,0x32,0xab,0xa4,0x10,0x1a,0x38,0x94,0x10,0x8d,0xf8,0x70,
2785 0x3e,0x4e,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,
2786 0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,
2787 0x04,0x5f,0x80,0xf2,0x17 };
2788 static const BYTE envelopedBareMessage[] = {
2789 0x30,0x81,0xe1,0x02,0x01,0x00,0x31,0x81,0xba,0x30,0x81,0xb7,0x02,0x01,0x00,
2790 0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,
2791 0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,0xa9,0xba,0x41,0xa5,0xcc,0x01,
2792 0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2793 0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x69,0x79,0x12,0x6b,0xa1,0x2f,0xe9,0x0d,
2794 0x34,0x79,0x77,0xe9,0x15,0xf2,0xff,0x0c,0x9a,0xf2,0x87,0xbd,0x12,0xc4,0x2d,
2795 0x9e,0x81,0xc7,0x3c,0x74,0x05,0xdc,0x13,0xaf,0xe9,0xa2,0xba,0x72,0xe9,0xa5,
2796 0x2b,0x81,0x39,0xd3,0x62,0xaa,0x78,0xc3,0x90,0x4f,0x06,0xf0,0xdb,0x18,0x5e,
2797 0xe1,0x2e,0x19,0xa3,0xc2,0xac,0x1e,0xf1,0xbf,0xe6,0x03,0x00,0x96,0xfa,0xd2,
2798 0x66,0x73,0xd0,0x45,0x55,0x57,0x71,0xff,0x3a,0x0c,0xad,0xce,0xde,0x68,0xd4,
2799 0x45,0x20,0xc8,0x44,0x4d,0x5d,0xa2,0x98,0x79,0xb1,0x81,0x0f,0x8a,0xfc,0x70,
2800 0xa5,0x18,0xd2,0x30,0x65,0x22,0x84,0x02,0x24,0x48,0xf7,0xa4,0xe0,0xa5,0x6c,
2801 0xa8,0xa4,0xd0,0x86,0x4b,0x6e,0x9b,0x18,0xab,0x78,0xfa,0x76,0x12,0xce,0x55,
2802 0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x30,0x0c,
2803 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,0x80,0x04,0x2c,
2804 0x2d,0xa3,0x6e };
2806 0x30,0x82,0x02,0x69,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x03,
2807 0xa0,0x82,0x02,0x5a,0x30,0x82,0x02,0x56,0x02,0x01,0x00,0x31,0x82,0x02,0x2e,
2808 0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,
2809 0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,0x63,0x75,0x75,0x7a,0x53,0x36,
2810 0xa9,0xba,0x41,0xa5,0xcc,0x01,0x7f,0x76,0x4c,0xd9,0x30,0x0d,0x06,0x09,0x2a,
2811 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0xa4,0x2e,
2812 0xe5,0x56,0x60,0xc5,0x64,0x07,0x29,0xaf,0x5c,0x38,0x3d,0x4b,0xec,0xbd,0xba,
2813 0x97,0x60,0x17,0xed,0xd7,0x21,0x7b,0x19,0x94,0x95,0xf1,0xb2,0x84,0x06,0x1f,
2814 0xc5,0x83,0xb3,0x5d,0xc8,0x2c,0x1c,0x0f,0xf7,0xfd,0x58,0x8b,0x0f,0x25,0xb5,
2815 0x9f,0x7f,0x43,0x8f,0x5f,0x81,0x16,0x4a,0x62,0xfb,0x47,0xb5,0x36,0x72,0x21,
2816 0x29,0xd4,0x9e,0x27,0x35,0xf4,0xd0,0xd4,0xc0,0xa3,0x7a,0x47,0xbe,0xc9,0xae,
2817 0x08,0x17,0x6a,0xb5,0x63,0x38,0xa1,0xdc,0xf5,0xc1,0x8d,0x97,0x56,0xb4,0xc0,
2818 0x2d,0x2b,0xec,0x3d,0xbd,0xce,0xd1,0x52,0x3e,0x29,0x34,0xe2,0x9a,0x00,0x96,
2819 0x4c,0x85,0xaf,0x0f,0xfb,0x10,0x1d,0xf8,0x08,0x27,0x10,0x04,0x04,0xbf,0xae,
2820 0x36,0xd0,0x6a,0x49,0xe7,0x43,0x30,0x81,0xb7,0x02,0x01,0x00,0x30,0x20,0x30,
2821 0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x4e,0x02,0x10,
2822 0xc2,0x8f,0xc4,0x5e,0x8d,0x3b,0x01,0x8c,0x4b,0x23,0xcb,0x93,0x77,0xab,0xb6,
2823 0xe1,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
2824 0x00,0x04,0x81,0x80,0x4b,0x22,0x8a,0xfa,0xa6,0xb6,0x01,0xe9,0xb5,0x54,0xcf,
2825 0xa7,0x81,0x54,0xf9,0x08,0x42,0x8a,0x75,0x19,0x9c,0xc9,0x27,0x68,0x08,0xf9,
2826 0x53,0xa7,0x60,0xf8,0xdd,0xba,0xfb,0x4f,0x63,0x8a,0x15,0x6a,0x5b,0xf6,0xe3,
2827 0x4e,0x29,0xa9,0xc8,0x1d,0x63,0x92,0x8f,0x95,0x91,0x95,0x71,0xb5,0x5d,0x02,
2828 0xe5,0xa0,0x07,0x67,0x36,0xe5,0x2d,0x7b,0xcd,0xe1,0xf2,0xa4,0xc6,0x24,0x70,
2829 0xac,0xd7,0xaf,0x63,0xb2,0x04,0x02,0x8d,0xae,0x2f,0xdc,0x7e,0x6c,0x84,0xd3,
2830 0xe3,0x66,0x54,0x3b,0x05,0xd8,0x77,0x40,0xe4,0x6b,0xbd,0xa9,0x8d,0x4d,0x74,
2831 0x15,0xfd,0x74,0xf7,0xd3,0xc0,0xc9,0xf1,0x20,0x0e,0x08,0x13,0xcc,0xb0,0x94,
2832 0x53,0x01,0xd4,0x5f,0x95,0x32,0xeb,0xe8,0x73,0x9f,0x6a,0xd1,0x30,0x81,0xb7,
2833 0x02,0x01,0x00,0x30,0x20,0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,
2834 0x03,0x13,0x01,0x58,0x02,0x10,0x1c,0xf2,0x1f,0xec,0x6b,0xdc,0x36,0xbf,0x4a,
2835 0xd7,0xe1,0x6c,0x84,0x85,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
2836 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x04,0x81,0x80,0x47,0x21,0xf9,0xe7,0x98,
2837 0x7f,0xe7,0x49,0x3f,0x16,0xb8,0x4c,0x8b,0x7d,0x5d,0x56,0xa7,0x31,0xfd,0xa5,
2838 0xcd,0x43,0x70,0x58,0xf1,0x33,0xfb,0xe6,0xc8,0xbb,0x6f,0x0a,0x89,0xa4,0xb9,
2839 0x3e,0x3a,0xc5,0x85,0x46,0x54,0x73,0x37,0xa3,0xbd,0x36,0xc3,0xce,0x40,0xf3,
2840 0xd7,0x92,0x54,0x8e,0x60,0x1f,0xa2,0xa7,0x03,0xc2,0x49,0xa9,0x02,0x28,0xc8,
2841 0xa5,0xa7,0x42,0xcd,0x29,0x85,0x34,0xa7,0xa9,0xe8,0x8c,0x3d,0xb3,0xd0,0xac,
2842 0x7d,0x31,0x5d,0xb4,0xcb,0x7e,0xad,0x62,0xfd,0x04,0x7b,0xa1,0x93,0xb5,0xbc,
2843 0x08,0x4f,0x36,0xd7,0x5a,0x95,0xbc,0xff,0x47,0x0f,0x84,0x21,0x24,0xdf,0xc5,
2844 0xfe,0xc8,0xe5,0x0b,0xc4,0xc4,0x5c,0x1a,0x50,0x31,0x91,0xce,0xf6,0x11,0xf1,
2845 0x0e,0x28,0xce,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,
2846 0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x04,0x05,0x00,
2847 0x80,0x04,0x4e,0x99,0x9d,0x4c };
2848 static const BYTE serialNumber[] = {
2849 0x2e,0xcd,0x85,0x84,0x6c,0xe1,0xd7,0x4a,0xbf,0x36,0xdc,0x6b,0xec,0x1f,0xf2,
2850 0x1c };
2851 static const BYTE issuer[] = {
2852 0x30,0x0c,0x31,0x0a,0x30,0x08,0x06,0x03,0x55,0x04,0x03,0x13,0x01,0x58 };
2853 
2854 static void test_decode_msg_get_param(void)
2855 {
2856  HCRYPTMSG msg;
2857  HCRYPTPROV hCryptProv;
2858  HCRYPTKEY key = 0;
2859  BOOL ret;
2860  DWORD size = 0, value, req_size;
2861  LPBYTE buf;
2862  CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
2863 
2865  SetLastError(0xdeadbeef);
2868  "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
2870  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2871  check_param("data content", msg, CMSG_CONTENT_PARAM, msgData,
2872  sizeof(msgData));
2873  CryptMsgClose(msg);
2874 
2877  if (ret)
2878  {
2879  /* Crashes on some Win9x */
2880  check_param("empty hash content", msg, CMSG_CONTENT_PARAM, NULL, 0);
2881  check_param("empty hash hash data", msg, CMSG_HASH_DATA_PARAM, NULL, 0);
2882  check_param("empty hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2883  emptyHashParam, sizeof(emptyHashParam));
2884  }
2885  CryptMsgClose(msg);
2888  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2889  check_param("hash content", msg, CMSG_CONTENT_PARAM, msgData,
2890  sizeof(msgData));
2891  check_param("hash hash data", msg, CMSG_HASH_DATA_PARAM, hashParam,
2892  sizeof(hashParam));
2893  check_param("hash computed hash", msg, CMSG_COMPUTED_HASH_PARAM,
2894  hashParam, sizeof(hashParam));
2895  /* Curiously, on NT-like systems, getting the hash of index 1 succeeds,
2896  * even though there's only one hash.
2897  */
2899  ok(ret || GetLastError() == OSS_DATA_ERROR /* Win9x */,
2900  "CryptMsgGetParam failed: %08x\n", GetLastError());
2901  if (ret)
2902  buf = CryptMemAlloc(size);
2903  else
2904  buf = NULL;
2905  if (buf)
2906  {
2908  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2909  ok(size == sizeof(hashParam), "Unexpected size %d\n", size);
2910  ok(!memcmp(buf, hashParam, size), "Unexpected value\n");
2911  CryptMemFree(buf);
2912  }
2913  check_param("hash inner OID", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2914  (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2916  check_param("hash version", msg, CMSG_VERSION_PARAM, (const BYTE *)&value,
2917  sizeof(value));
2918  CryptMsgClose(msg);
2919 
2922  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
2923  check_param("signed content", msg, CMSG_CONTENT_PARAM, msgData,
2924  sizeof(msgData));
2925  check_param("inner content", msg, CMSG_INNER_CONTENT_TYPE_PARAM,
2926  (const BYTE *)szOID_RSA_data, strlen(szOID_RSA_data) + 1);
2927  size = sizeof(value);
2928  value = 2112;
2930  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2931  ok(value == 1, "Expected 1 signer, got %d\n", value);
2932  size = 0;
2934  ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
2935  "CryptMsgGetParam failed: %08x\n", GetLastError());
2936  if (ret)
2937  buf = CryptMemAlloc(size);
2938  else
2939  buf = NULL;
2940  if (buf)
2941  {
2942  CMSG_SIGNER_INFO signer = { 0 };
2943 
2944  signer.dwVersion = 1;
2945  signer.Issuer.cbData = sizeof(encodedCommonName);
2946  signer.Issuer.pbData = encodedCommonName;
2947  signer.SerialNumber.cbData = sizeof(serialNum);
2948  signer.SerialNumber.pbData = serialNum;
2950  req_size = size;
2951  size += 10;
2953  ok(size == req_size, "size = %u, expected %u\n", size, req_size);
2955  CryptMemFree(buf);
2956  }
2957  /* Getting the CMS signer info of a PKCS7 message is possible. */
2958  size = 0;
2960  ok(ret || broken(GetLastError() == CRYPT_E_INVALID_MSG_TYPE /* Win9x */),
2961  "CryptMsgGetParam failed: %08x\n", GetLastError());
2962  if (ret)
2963  buf = CryptMemAlloc(size);
2964  else
2965  buf = NULL;
2966  if (buf)
2967  {
2968  CMSG_CMS_SIGNER_INFO signer = { 0 };
2969 
2970  signer.dwVersion = 1;
2972  U(signer.SignerId).IssuerSerialNumber.Issuer.cbData =
2973  sizeof(encodedCommonName);
2974  U(signer.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonName;
2975  U(signer.SignerId).IssuerSerialNumber.SerialNumber.cbData =
2976  sizeof(serialNum);
2977  U(signer.SignerId).IssuerSerialNumber.SerialNumber.pbData = serialNum;
2981  CryptMemFree(buf);
2982  }
2983  /* index is ignored when getting signer count */
2984  size = sizeof(value);
2986  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2987  ok(value == 1, "Expected 1 signer, got %d\n", value);
2989  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2990  ok(value == 0, "Expected 0 certs, got %d\n", value);
2992  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
2993  ok(value == 0, "Expected 0 CRLs, got %d\n", value);
2994  CryptMsgClose(msg);
2996  NULL);
2999  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3001  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3002  ok(value == 1, "Expected 1 cert, got %d\n", value);
3003  check_param("cert", msg, CMSG_CERT_PARAM, cert, sizeof(cert));
3005  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3006  ok(value == 1, "Expected 1 CRL, got %d\n", value);
3007  check_param("crl", msg, CMSG_CRL_PARAM, crl, sizeof(crl));
3008  check_param("signed with cert and CRL computed hash", msg,
3011  CryptMsgClose(msg);
3012 
3015  sizeof(signedKeyIdEmptyContent), TRUE);
3016  if (!ret && GetLastError() == OSS_DATA_ERROR)
3017  {
3018  CryptMsgClose(msg);
3019  win_skip("Subsequent tests crash on some Win9x\n");
3020  return;
3021  }
3022  ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
3023  size = sizeof(value);
3025  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3026  ok(value == 1, "Expected 1 signer, got %d\n", value);
3027  /* Getting the regular (non-CMS) signer info from a CMS message is also
3028  * possible..
3029  */
3030  size = 0;
3032  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3033  if (ret)
3034  buf = CryptMemAlloc(size);
3035  else
3036  buf = NULL;
3037  if (buf)
3038  {
3039  CMSG_SIGNER_INFO signer;
3040  BYTE zero = 0;
3041 
3042  /* and here's the little oddity: for a CMS message using the key id
3043  * variant of a SignerId, retrieving the CMSG_SIGNER_INFO param yields
3044  * a signer with a zero (not empty) serial number, and whose issuer is
3045  * an RDN with OID szOID_KEYID_RDN, value type CERT_RDN_OCTET_STRING,
3046  * and value of the key id.
3047  */
3048  signer.dwVersion = CMSG_SIGNED_DATA_V3;
3049  signer.Issuer.cbData = sizeof(keyIdIssuer);
3050  signer.Issuer.pbData = keyIdIssuer;
3051  signer.SerialNumber.cbData = 1;
3052  signer.SerialNumber.pbData = &zero;
3055  CryptMemFree(buf);
3056  }
3057  size = 0;
3059  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3060  if (ret)
3061  buf = CryptMemAlloc(size);
3062  else
3063  buf = NULL;
3064  if (buf)
3065  {
3066  CMSG_CMS_SIGNER_INFO signer = { 0 };
3067 
3068  signer.dwVersion = CMSG_SIGNED_DATA_V3;
3070  U(signer.SignerId).KeyId.cbData = sizeof(serialNum);
3071  U(signer.SignerId).KeyId.pbData = serialNum;
3075  CryptMemFree(buf);
3076  }
3077  CryptMsgClose(msg);
3078 
3080  NULL);
3082  sizeof(envelopedEmptyBareContent), TRUE);
3083  check_param("enveloped empty bare content", msg, CMSG_CONTENT_PARAM, NULL,
3084  0);
3085  CryptMsgClose(msg);
3086 
3089  TRUE);
3090  check_param("enveloped empty content", msg, CMSG_CONTENT_PARAM, NULL, 0);
3091  CryptMsgClose(msg);
3092 
3093  pCryptAcquireContextA(&hCryptProv, NULL, MS_ENHANCED_PROV_A, PROV_RSA_FULL,
3095  SetLastError(0xdeadbeef);
3096  ret = CryptImportKey(hCryptProv, publicPrivateKeyPair,
3097  sizeof(publicPrivateKeyPair), 0, 0, &key);
3098  ok(ret ||
3099  broken(!ret && GetLastError() == NTE_PERM), /* WinME and some NT4 */
3100  "CryptImportKey failed: %08x\n", GetLastError());
3101 
3104  check_param("enveloped message before decrypting", msg, CMSG_CONTENT_PARAM,
3105  envelopedMessage + sizeof(envelopedMessage) - 4, 4);
3106  if (key)
3107  {
3108  decryptPara.hCryptProv = hCryptProv;
3109  SetLastError(0xdeadbeef);
3110  ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3111  ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3112  decryptPara.hCryptProv = 0;
3113  SetLastError(0xdeadbeef);
3114  ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3116  "expected CRYPT_E_ALREADY_DECRYPTED, got %08x\n", GetLastError());
3117  check_param("enveloped message", msg, CMSG_CONTENT_PARAM, msgData,
3118  sizeof(msgData));
3119  }
3120  else
3121  win_skip("failed to import a key, skipping tests\n");
3122  CryptMsgClose(msg);
3123 
3125  NULL);
3127  TRUE);
3128  check_param("enveloped bare message before decrypting", msg,
3130  sizeof(envelopedBareMessage) - 4, 4);
3131  if (key)
3132  {
3133  decryptPara.hCryptProv = hCryptProv;
3134  SetLastError(0xdeadbeef);
3135  ret = CryptMsgControl(msg, 0, CMSG_CTRL_DECRYPT, &decryptPara);
3136  ok(ret, "CryptMsgControl failed: %08x\n", GetLastError());
3137  check_param("enveloped bare message", msg, CMSG_CONTENT_PARAM, msgData,
3138  sizeof(msgData));
3139  }
3140  else
3141  win_skip("failed to import a key, skipping tests\n");
3142  CryptMsgClose(msg);
3143 
3144  if (key)
3146  CryptReleaseContext(hCryptProv, 0);
3147 
3150  sizeof(envelopedMessageWith3Recps), TRUE);
3151  value = 3;
3152  check_param("recipient count", msg, CMSG_RECIPIENT_COUNT_PARAM,
3153  (const BYTE *)&value, sizeof(value));
3154  size = 0;
3155  SetLastError(0xdeadbeef);
3158  "expected CRYPT_E_INVALID_INDEX, got %08x\n", GetLastError());
3159  size = 0;
3160  SetLastError(0xdeadbeef);
3162  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3163  ok(size >= 142, "unexpected size: %u\n", size);
3164  if (ret)
3165  buf = CryptMemAlloc(size);
3166  else
3167  buf = NULL;
3168  if (buf)
3169  {
3170  CERT_INFO *certInfo = (CERT_INFO *)buf;
3171 
3172  SetLastError(0xdeadbeef);
3174  ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
3175  ok(certInfo->SerialNumber.cbData == sizeof(serialNumber),
3176  "unexpected serial number size: %u\n", certInfo->SerialNumber.cbData);
3178  sizeof(serialNumber)), "unexpected serial number\n");
3179  ok(certInfo->Issuer.cbData == sizeof(issuer),
3180  "unexpected issuer size: %u\n", certInfo->Issuer.cbData);
3181  ok(!memcmp(certInfo->Issuer.pbData, issuer, sizeof(issuer)),
3182  "unexpected issuer\n");
3183  CryptMemFree(buf);
3184  }
3185  CryptMsgClose(msg);
3186 }
3187 
3188 static void test_decode_msg(void)
3189 {
3192 }
3193 
3194 static BYTE aKey[] = { 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf };
3195 /* aKey encoded as a X509_PUBLIC_KEY_INFO */
3196 static BYTE encodedPubKey[] = {
3197 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,
3198 0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
3199 0x0d,0x0e,0x0f };
3200 /* a weird modulus encoded as RSA_CSP_PUBLICKEYBLOB */
3201 static BYTE mod_encoded[] = {
3202  0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,
3203  0x01,0x00,0x01 };
3204 
3205 static void test_msg_control(void)
3206 {
3207  static char oid_rsa_rsa[] = szOID_RSA_RSA;
3208  BOOL ret;
3209  HCRYPTMSG msg;
3210  DWORD i;
3211  CERT_INFO certInfo = { 0 };
3212  CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
3213  CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
3214  CMSG_CTRL_DECRYPT_PARA decryptPara = { sizeof(decryptPara), 0 };
3215 
3216  /* Crashes
3217  ret = CryptMsgControl(NULL, 0, 0, NULL);
3218  */
3219 
3220  /* Data encode messages don't allow any sort of control.. */
3222  NULL);
3223  /* either with no prior update.. */
3224  for (i = 1; !old_crypt32 && (i <= CMSG_CTRL_ADD_CMS_SIGNER_INFO); i++)
3225  {
3226  SetLastError(0xdeadbeef);
3227  ret</