ReactOS  0.4.12-dev-918-g6c6e7b8
decode.c
Go to the documentation of this file.
1 /*
2  * Copyright 2005-2009 Juan Lang
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  * This file implements ASN.1 DER decoding of a limited set of types.
19  * It isn't a full ASN.1 implementation. Microsoft implements BER
20  * encoding of many of the basic types in msasn1.dll, but that interface isn't
21  * implemented, so I implement them here.
22  *
23  * References:
24  * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25  * (available online, look for a PDF copy as the HTML versions tend to have
26  * translation errors.)
27  *
28  * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
29  *
30  * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
31  */
32 
33 #include "config.h"
34 #include "wine/port.h"
35 
36 #include <assert.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 
41 #define NONAMELESSUNION
42 
43 #include "windef.h"
44 #include "winbase.h"
45 #include "wincrypt.h"
46 #include "winnls.h"
47 #include "snmp.h"
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
51 
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
54 
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
57 
60 
62  DWORD, DWORD, void *, DWORD *);
64  DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
65 
66 /* Internal decoders don't do memory allocation or exception handling, and
67  * they report how many bytes they decoded.
68  */
69 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
70  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
71 
73  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
74  DWORD *pcbDecoded);
76  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
77  DWORD *pcbDecoded);
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
79  */
80 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
81  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
84  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
85 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
86  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
89  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
90  DWORD *pcbDecoded);
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
93  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
94 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
95  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97  * member has been initialized, doesn't do exception handling, and doesn't do
98  * memory allocation. Also doesn't check tag, assumes the caller has checked
99  * it.
100  */
102  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
103  DWORD *pcbDecoded);
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
106  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
107  DWORD *pcbDecoded);
109  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110  DWORD *pcbDecoded);
111 
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
114 
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116  * where pbEncoded[0] is the tag. If the data are too short to contain a
117  * length or if the length is too large for cbEncoded, sets an appropriate
118  * error code and returns FALSE. If the encoded length is unknown due to
119  * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
120  */
122  DWORD *len)
123 {
124  BOOL ret;
125 
126  if (cbEncoded <= 1)
127  {
129  ret = FALSE;
130  }
131  else if (pbEncoded[1] <= 0x7f)
132  {
133  if (pbEncoded[1] + 1 > cbEncoded)
134  {
136  ret = FALSE;
137  }
138  else
139  {
140  *len = pbEncoded[1];
141  ret = TRUE;
142  }
143  }
144  else if (pbEncoded[1] == 0x80)
145  {
147  ret = TRUE;
148  }
149  else
150  {
151  BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
152 
153  if (lenLen > sizeof(DWORD) + 1)
154  {
156  ret = FALSE;
157  }
158  else if (lenLen + 2 > cbEncoded)
159  {
161  ret = FALSE;
162  }
163  else
164  {
165  DWORD out = 0;
166 
167  pbEncoded += 2;
168  while (--lenLen)
169  {
170  out <<= 8;
171  out |= *pbEncoded++;
172  }
173  if (out + lenLen + 1 > cbEncoded)
174  {
176  ret = FALSE;
177  }
178  else
179  {
180  *len = out;
181  ret = TRUE;
182  }
183  }
184  }
185  return ret;
186 }
187 
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
190 {
191  BOOL ret;
192 
193  if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
195  {
197  ret = FALSE;
198  }
199  return ret;
200 }
201 
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203  * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204  * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205  * pointer to the newly allocated memory.
206  */
208  const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
209  DWORD bytesNeeded)
210 {
211  BOOL ret = TRUE;
212 
214  {
215  if (pDecodePara && pDecodePara->pfnAlloc)
216  *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
217  else
218  *(BYTE **)pvStructInfo = LocalAlloc(LPTR, bytesNeeded);
219  if (!*(BYTE **)pvStructInfo)
220  ret = FALSE;
221  else
222  *pcbStructInfo = bytesNeeded;
223  }
224  else if (*pcbStructInfo < bytesNeeded)
225  {
226  *pcbStructInfo = bytesNeeded;
228  ret = FALSE;
229  }
230  else
231  *pcbStructInfo = bytesNeeded;
232  return ret;
233 }
234 
235 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA *pDecodePara, LPVOID pv)
236 {
237  if (pDecodePara && pDecodePara->pfnFree)
238  pDecodePara->pfnFree(pv);
239  else
240  LocalFree(pv);
241 }
242 
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244  * Assumes pvStructInfo is not NULL.
245  */
246 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
247 {
248  BOOL ret;
249 
250  if (*pcbStructInfo < bytesNeeded)
251  {
252  *pcbStructInfo = bytesNeeded;
254  ret = FALSE;
255  }
256  else
257  {
258  *pcbStructInfo = bytesNeeded;
259  ret = TRUE;
260  }
261  return ret;
262 }
263 
264 /* tag:
265  * The expected tag of the item. If tag is 0, decodeFunc is called
266  * regardless of the tag value seen.
267  * offset:
268  * A sequence is decoded into a struct. The offset member is the
269  * offset of this item within that struct.
270  * decodeFunc:
271  * The decoder function to use. If this is NULL, then the member isn't
272  * decoded, but minSize space is reserved for it.
273  * minSize:
274  * The minimum amount of space occupied after decoding. You must set this.
275  * optional:
276  * If true, and the tag doesn't match the expected tag for this item,
277  * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278  * filled with 0 for this member.
279  * hasPointer, pointerOffset:
280  * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281  * the offset within the struct of the data pointer (or to the
282  * first data pointer, if more than one exist).
283  * size:
284  * Used by CRYPT_AsnDecodeSequence, not for your use.
285  */
287 {
296 };
297 
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300  (offsetof(s, nextmember) - offsetof(s, member))
301 
302 /* Decodes the items in a sequence, where the items are described in items,
303  * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304  * pvStructInfo. nextData is a pointer to the memory location at which the
305  * first decoded item with a dynamic pointer should point.
306  * Upon decoding, *cbDecoded is the total number of bytes decoded.
307  * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
308  */
310  DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
311  void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
312 {
313  BOOL ret;
314  DWORD i, decoded = 0;
315  const BYTE *ptr = pbEncoded;
316 
317  TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
318  cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
319 
320  for (i = 0, ret = TRUE; ret && i < cItem; i++)
321  {
322  if (cbEncoded - (ptr - pbEncoded) != 0)
323  {
324  DWORD itemLen;
325 
327  cbEncoded - (ptr - pbEncoded), &itemLen)))
328  {
329  BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
330 
331  if (ptr[0] == items[i].tag || !items[i].tag)
332  {
333  DWORD itemEncodedLen;
334 
335  if (itemLen == CMSG_INDEFINITE_LENGTH)
336  itemEncodedLen = cbEncoded - (ptr - pbEncoded);
337  else
338  itemEncodedLen = 1 + itemLenBytes + itemLen;
339  if (nextData && pvStructInfo && items[i].hasPointer)
340  {
341  TRACE("Setting next pointer to %p\n",
342  nextData);
343  *(BYTE **)((BYTE *)pvStructInfo +
344  items[i].pointerOffset) = nextData;
345  }
346  if (items[i].decodeFunc)
347  {
348  DWORD itemDecoded;
349 
350  if (pvStructInfo)
351  TRACE("decoding item %d\n", i);
352  else
353  TRACE("sizing item %d\n", i);
354  ret = items[i].decodeFunc(ptr, itemEncodedLen,
356  pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
357  : NULL, &items[i].size, &itemDecoded);
358  if (ret)
359  {
360  if (items[i].size < items[i].minSize)
361  items[i].size = items[i].minSize;
362  else if (items[i].size > items[i].minSize)
363  {
364  /* Account for alignment padding */
365  items[i].size = ALIGN_DWORD_PTR(items[i].size);
366  }
367  TRACE("item %d size: %d\n", i, items[i].size);
368  if (nextData && items[i].hasPointer &&
369  items[i].size > items[i].minSize)
370  nextData += items[i].size - items[i].minSize;
371  if (itemDecoded > itemEncodedLen)
372  {
373  WARN("decoded length %d exceeds encoded %d\n",
374  itemDecoded, itemEncodedLen);
376  ret = FALSE;
377  }
378  else
379  {
380  ptr += itemDecoded;
381  decoded += itemDecoded;
382  TRACE("item %d: decoded %d bytes\n", i,
383  itemDecoded);
384  }
385  }
386  else if (items[i].optional &&
388  {
389  TRACE("skipping optional item %d\n", i);
390  items[i].size = items[i].minSize;
392  ret = TRUE;
393  }
394  else
395  TRACE("item %d failed: %08x\n", i,
396  GetLastError());
397  }
398  else if (itemLen == CMSG_INDEFINITE_LENGTH)
399  {
400  ERR("can't use indefinite length encoding without a decoder\n");
402  ret = FALSE;
403  }
404  else
405  {
406  TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
407  ptr += itemEncodedLen;
408  decoded += itemEncodedLen;
409  items[i].size = items[i].minSize;
410  }
411  }
412  else if (items[i].optional)
413  {
414  TRACE("skipping optional item %d\n", i);
415  items[i].size = items[i].minSize;
416  }
417  else
418  {
419  TRACE("item %d: tag %02x doesn't match expected %02x\n",
420  i, ptr[0], items[i].tag);
422  ret = FALSE;
423  }
424  }
425  }
426  else if (items[i].optional)
427  {
428  TRACE("missing optional item %d, skipping\n", i);
429  items[i].size = items[i].minSize;
430  }
431  else
432  {
433  TRACE("not enough bytes for item %d, failing\n", i);
435  ret = FALSE;
436  }
437  }
438  if (cbDecoded)
439  *cbDecoded = decoded;
440  TRACE("returning %d\n", ret);
441  return ret;
442 }
443 
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445  * (basically, a struct.) Each element being decoded is described by a struct
446  * AsnDecodeSequenceItem, see above.
447  * startingPointer is an optional pointer to the first place where dynamic
448  * data will be stored. If you know the starting offset, you may pass it
449  * here. Otherwise, pass NULL, and one will be inferred from the items.
450  */
452  DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
453  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
454  DWORD *pcbDecoded, void *startingPointer)
455 {
456  BOOL ret;
457 
458  TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
459  cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
460  startingPointer);
461 
462  if (!cbEncoded)
463  {
465  return FALSE;
466  }
467  if (pbEncoded[0] == ASN_SEQUENCE)
468  {
469  DWORD dataLen;
470 
471  if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
472  {
473  DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
474  const BYTE *ptr = pbEncoded + 1 + lenBytes;
475  BOOL indefinite = FALSE;
476 
477  cbEncoded -= 1 + lenBytes;
478  if (dataLen == CMSG_INDEFINITE_LENGTH)
479  {
480  dataLen = cbEncoded;
481  indefinite = TRUE;
482  lenBytes += 2;
483  }
484  else if (cbEncoded < dataLen)
485  {
486  TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
487  cbEncoded);
489  ret = FALSE;
490  }
491  if (ret)
492  {
494  ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
495  if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
496  {
497  if (cbDecoded > cbEncoded - 2)
498  {
499  /* Not enough space for 0 TLV */
501  ret = FALSE;
502  }
503  else if (*(ptr + cbDecoded) != 0 ||
504  *(ptr + cbDecoded + 1) != 0)
505  {
506  TRACE("expected 0 TLV\n");
508  ret = FALSE;
509  }
510  else
511  cbDecoded += 2;
512  }
513  }
514  if (ret && !indefinite && cbDecoded != dataLen)
515  {
516  TRACE("expected %d decoded, got %d, failing\n", dataLen,
517  cbDecoded);
519  ret = FALSE;
520  }
521  if (ret)
522  {
523  DWORD i, bytesNeeded = 0, structSize = 0;
524 
525  for (i = 0; i < cItem; i++)
526  {
527  if (items[i].size > items[i].minSize)
528  bytesNeeded += items[i].size - items[i].minSize;
529  structSize = max( structSize, items[i].offset + items[i].minSize );
530  }
531  bytesNeeded += structSize;
532  if (pcbDecoded)
533  *pcbDecoded = 1 + lenBytes + cbDecoded;
534  if (!pvStructInfo)
535  *pcbStructInfo = bytesNeeded;
536  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
537  pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
538  {
539  BYTE *nextData;
540 
542  pvStructInfo = *(BYTE **)pvStructInfo;
543  if (startingPointer)
544  nextData = startingPointer;
545  else
546  nextData = (BYTE *)pvStructInfo + structSize;
547  memset(pvStructInfo, 0, structSize);
549  ptr, dataLen, dwFlags, pvStructInfo, nextData,
550  &cbDecoded);
551  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
552  CRYPT_FreeSpace(pDecodePara, pvStructInfo);
553  }
554  }
555  }
556  }
557  else
558  {
560  ret = FALSE;
561  }
562  TRACE("returning %d (%08x)\n", ret, GetLastError());
563  return ret;
564 }
565 
566 /* tag:
567  * The expected tag of the entire encoded array (usually a variant
568  * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
569  * regardless of the tag seen.
570  * countOffset:
571  * The offset within the outer structure at which the count exists.
572  * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
573  * while CRYPT_ATTRIBUTE has countOffset ==
574  * offsetof(CRYPT_ATTRIBUTE, cValue).
575  * arrayOffset:
576  * The offset within the outer structure at which the array pointer exists.
577  * For example, CRYPT_ATTRIBUTES has arrayOffset ==
578  * offsetof(CRYPT_ATTRIBUTES, rgAttr).
579  * minArraySize:
580  * The minimum size of the decoded array. On WIN32, this is always 8:
581  * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
582  * alignment.
583  * decodeFunc:
584  * used to decode each item in the array
585  * itemSize:
586  * is the minimum size of each decoded item
587  * hasPointer:
588  * indicates whether each item has a dynamic pointer
589  * pointerOffset:
590  * indicates the offset within itemSize at which the pointer exists
591  */
593 {
602 };
603 
605 {
608 };
609 
610 /* Decodes an array of like types into a structure described by a struct
611  * AsnArrayDescriptor.
612  */
613 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
614  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
615  const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
616  DWORD *pcbDecoded)
617 {
618  BOOL ret = TRUE;
619 
620  TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
621  cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
622 
623  if (!cbEncoded)
624  {
626  ret = FALSE;
627  }
628  else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
629  {
630  DWORD dataLen;
631 
632  if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
633  {
634  DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
635  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
636  /* There can be arbitrarily many items, but there is often only one.
637  */
638  struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
639 
640  decoded = 1 + lenBytes;
641  if (dataLen)
642  {
643  const BYTE *ptr;
644  BOOL doneDecoding = FALSE;
645 
646  for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
647  {
648  if (dataLen == CMSG_INDEFINITE_LENGTH)
649  {
650  if (ptr[0] == 0)
651  {
652  doneDecoding = TRUE;
653  if (ptr[1] != 0)
654  {
656  ret = FALSE;
657  }
658  else
659  decoded += 2;
660  }
661  }
662  else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
663  doneDecoding = TRUE;
664  if (!doneDecoding)
665  {
666  DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
667 
668  /* Each item decoded may not tolerate extraneous bytes,
669  * so get the length of the next element if known.
670  */
672  cbEncoded - (ptr - pbEncoded), &itemDataLen)))
673  {
674  if (itemDataLen == CMSG_INDEFINITE_LENGTH)
675  itemEncoded = cbEncoded - (ptr - pbEncoded);
676  else
677  itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
678  itemDataLen;
679  }
680  if (ret)
681  ret = arrayDesc->decodeFunc(ptr, itemEncoded,
683  &itemDecoded);
684  if (ret)
685  {
686  cItems++;
687  if (itemSizes != &itemSize)
688  itemSizes = CryptMemRealloc(itemSizes,
689  cItems * sizeof(struct AsnArrayItemSize));
690  else if (cItems > 1)
691  {
692  itemSizes =
694  cItems * sizeof(struct AsnArrayItemSize));
695  if (itemSizes)
696  *itemSizes = itemSize;
697  }
698  if (itemSizes)
699  {
700  decoded += itemDecoded;
701  itemSizes[cItems - 1].encodedLen = itemEncoded;
702  itemSizes[cItems - 1].size = size;
703  bytesNeeded += size;
704  ptr += itemEncoded;
705  }
706  else
707  ret = FALSE;
708  }
709  }
710  }
711  }
712  if (ret)
713  {
714  if (pcbDecoded)
715  *pcbDecoded = decoded;
716  if (!pvStructInfo)
717  *pcbStructInfo = bytesNeeded;
718  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
719  pvStructInfo, pcbStructInfo, bytesNeeded)))
720  {
721  DWORD i, *pcItems;
722  BYTE *nextData;
723  const BYTE *ptr;
724  void *rgItems;
725 
727  pvStructInfo = *(void **)pvStructInfo;
728  pcItems = pvStructInfo;
729  *pcItems = cItems;
731  {
732  rgItems = (BYTE *)pvStructInfo +
733  arrayDesc->minArraySize;
734  *(void **)((BYTE *)pcItems -
735  arrayDesc->countOffset + arrayDesc->arrayOffset) =
736  rgItems;
737  }
738  else
739  rgItems = *(void **)((BYTE *)pcItems -
740  arrayDesc->countOffset + arrayDesc->arrayOffset);
741  nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
742  for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
743  i < cItems && ptr - pbEncoded - 1 - lenBytes <
744  dataLen; i++)
745  {
746  DWORD itemDecoded;
747 
748  if (arrayDesc->hasPointer)
749  *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
750  + arrayDesc->pointerOffset) = nextData;
751  ret = arrayDesc->decodeFunc(ptr,
752  itemSizes[i].encodedLen,
754  (BYTE *)rgItems + i * arrayDesc->itemSize,
755  &itemSizes[i].size, &itemDecoded);
756  if (ret)
757  {
758  nextData += itemSizes[i].size - arrayDesc->itemSize;
759  ptr += itemDecoded;
760  }
761  }
762  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
763  CRYPT_FreeSpace(pDecodePara, pvStructInfo);
764  }
765  }
766  if (itemSizes != &itemSize)
767  CryptMemFree(itemSizes);
768  }
769  }
770  else
771  {
773  ret = FALSE;
774  }
775  return ret;
776 }
777 
778 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
779  * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
780  * to CRYPT_E_ASN1_CORRUPT.
781  * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
782  * set!
783  */
784 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
785  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
786 {
787  BOOL ret;
788  DWORD dataLen;
789 
790  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
791  {
792  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
793  DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
794 
796  bytesNeeded += 1 + lenBytes + dataLen;
797 
798  if (pcbDecoded)
799  *pcbDecoded = 1 + lenBytes + dataLen;
800  if (!pvStructInfo)
801  *pcbStructInfo = bytesNeeded;
802  else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
803  {
805 
807  pvStructInfo = *(BYTE **)pvStructInfo;
808  blob = pvStructInfo;
809  blob->cbData = 1 + lenBytes + dataLen;
810  if (blob->cbData)
811  {
813  blob->pbData = (BYTE *)pbEncoded;
814  else
815  {
816  assert(blob->pbData);
817  memcpy(blob->pbData, pbEncoded, blob->cbData);
818  }
819  }
820  else
821  {
823  ret = FALSE;
824  }
825  }
826  }
827  return ret;
828 }
829 
830 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
832  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
833  DWORD *pcbDecoded)
834 {
835  BOOL ret;
836 
837  TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
838  pvStructInfo, *pcbStructInfo, pcbDecoded);
839 
840  /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
841  * place.
842  */
844  dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
845  pcbDecoded);
846  if (ret && pvStructInfo)
847  {
848  CRYPT_BIT_BLOB *blob = pvStructInfo;
849 
850  if (blob->cbData)
851  {
852  DWORD i;
853  BYTE temp;
854 
855  for (i = 0; i < blob->cbData / 2; i++)
856  {
857  temp = blob->pbData[i];
858  blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
859  blob->pbData[blob->cbData - i - 1] = temp;
860  }
861  }
862  }
863  TRACE("returning %d (%08x)\n", ret, GetLastError());
864  return ret;
865 }
866 
868  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
869  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
870 {
871  BOOL ret = TRUE;
872 
873  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
874  pDecodePara, pvStructInfo, *pcbStructInfo);
875 
876  __TRY
877  {
878  struct AsnDecodeSequenceItem items[] = {
879  { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
881  offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
883  SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
885  offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
889  };
890 
892  items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
894  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
895  pcbStructInfo, NULL, NULL);
896  }
898  {
900  ret = FALSE;
901  }
902  __ENDTRY
903 
904  TRACE("Returning %d (%08x)\n", ret, GetLastError());
905  return ret;
906 }
907 
909  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
910 {
911  BOOL ret;
912  DWORD dataLen;
913 
914  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
915  {
916  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
917 
918  ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
919  dwFlags, pvStructInfo, pcbStructInfo, NULL);
920  if (pcbDecoded)
921  *pcbDecoded = 1 + lenBytes + dataLen;
922  }
923  return ret;
924 }
925 
927  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
928 {
929  BOOL ret;
930 
931  struct AsnDecodeSequenceItem items[] = {
932  { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
934  { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
936  };
937 
939  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
940  pcbDecoded, NULL);
941  return ret;
942 }
943 
945  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
946  DWORD *pcbDecoded)
947 {
948  BOOL ret = TRUE;
949  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
950  offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
951  FINALMEMBERSIZE(CERT_INFO, cExtension),
953  offsetof(CERT_EXTENSION, pszObjId) };
954 
955  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
956  pvStructInfo, *pcbStructInfo, pcbDecoded);
957 
958  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
959  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
960  return ret;
961 }
962 
964  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
965  DWORD *pcbDecoded)
966 {
967  BOOL ret;
968  DWORD dataLen;
969 
970  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
971  {
972  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
973 
975  dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
976  if (ret && pcbDecoded)
977  *pcbDecoded = 1 + lenBytes + dataLen;
978  }
979  return ret;
980 }
981 
983  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
984  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
985 {
986  BOOL ret = TRUE;
987  struct AsnDecodeSequenceItem items[] = {
989  CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
992  TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
993  { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
995  FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
998  Issuer.pbData) },
999  { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
1001  FALSE, 0 },
1002  { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1004  Subject.pbData) },
1005  { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1008  SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1009  { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
1011  offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1012  { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId),
1014  offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1015  { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1017  TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1018  };
1019 
1020  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1021  pDecodePara, pvStructInfo, *pcbStructInfo);
1022 
1024  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1025  NULL, NULL);
1026  if (ret && pvStructInfo)
1027  {
1028  CERT_INFO *info;
1029 
1031  info = *(CERT_INFO **)pvStructInfo;
1032  else
1033  info = pvStructInfo;
1034  if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1035  !info->Subject.cbData)
1036  {
1038  /* Don't need to deallocate, because it should have failed on the
1039  * first pass (and no memory was allocated.)
1040  */
1041  ret = FALSE;
1042  }
1043  }
1044 
1045  TRACE("Returning %d (%08x)\n", ret, GetLastError());
1046  return ret;
1047 }
1048 
1050  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1051  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1052 {
1053  BOOL ret = FALSE;
1054 
1055  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1056  pDecodePara, pvStructInfo, *pcbStructInfo);
1057 
1058  __TRY
1059  {
1060  DWORD size = 0;
1061 
1062  /* Unless told not to, first try to decode it as a signed cert. */
1064  {
1065  PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1066 
1069  &signedCert, &size);
1070  if (ret)
1071  {
1072  size = 0;
1075  signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1076  pvStructInfo, pcbStructInfo);
1077  LocalFree(signedCert);
1078  }
1079  }
1080  /* Failing that, try it as an unsigned cert */
1081  if (!ret)
1082  {
1083  size = 0;
1086  pDecodePara, pvStructInfo, pcbStructInfo);
1087  }
1088  }
1090  {
1092  }
1093  __ENDTRY
1094 
1095  TRACE("Returning %d (%08x)\n", ret, GetLastError());
1096  return ret;
1097 }
1098 
1100  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1101  DWORD *pcbDecoded)
1102 {
1103  BOOL ret = TRUE;
1104  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1105  offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1106  FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1108  offsetof(CERT_EXTENSION, pszObjId) };
1109 
1110  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1111  pvStructInfo, *pcbStructInfo, pcbDecoded);
1112 
1113  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1114  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1115  return ret;
1116 }
1117 
1119  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1120 {
1121  BOOL ret;
1122  struct AsnDecodeSequenceItem items[] = {
1125  offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1126  { 0, offsetof(CRL_ENTRY, RevocationDate),
1128  { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1130  FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1131  offsetof(CRL_ENTRY, rgExtension), 0 },
1132  };
1133  PCRL_ENTRY entry = pvStructInfo;
1134 
1135  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1136  *pcbStructInfo);
1137 
1139  pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1140  entry ? entry->SerialNumber.pbData : NULL);
1141  if (ret && entry && !entry->SerialNumber.cbData)
1142  {
1143  WARN("empty CRL entry serial number\n");
1145  ret = FALSE;
1146  }
1147  return ret;
1148 }
1149 
1150 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1151  * whose rgCRLEntry member has been set prior to calling.
1152  */
1154  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1155 {
1156  BOOL ret;
1157  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1158  offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1159  MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1161  offsetof(CRL_ENTRY, SerialNumber.pbData) };
1162 
1163  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1164  pvStructInfo, *pcbStructInfo, pcbDecoded);
1165 
1166  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1167  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1168  TRACE("Returning %d (%08x)\n", ret, GetLastError());
1169  return ret;
1170 }
1171 
1173  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1174  DWORD *pcbDecoded)
1175 {
1176  BOOL ret = TRUE;
1177  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1178  offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1179  FINALMEMBERSIZE(CRL_INFO, cExtension),
1181  offsetof(CERT_EXTENSION, pszObjId) };
1182 
1183  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1184  pvStructInfo, *pcbStructInfo, pcbDecoded);
1185 
1186  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1187  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1188  return ret;
1189 }
1190 
1192  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1193  DWORD *pcbDecoded)
1194 {
1195  BOOL ret;
1196  DWORD dataLen;
1197 
1198  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1199  {
1200  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1201 
1203  dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1204  if (ret && pcbDecoded)
1205  *pcbDecoded = 1 + lenBytes + dataLen;
1206  }
1207  return ret;
1208 }
1209 
1211  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1212  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1213 {
1214  struct AsnDecodeSequenceItem items[] = {
1215  { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1216  CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1217  { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1219  FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1220  { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1222  Issuer.pbData) },
1224  sizeof(FILETIME), FALSE, FALSE, 0 },
1226  sizeof(FILETIME), TRUE, FALSE, 0 },
1227  { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1228  CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1229  TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1230  { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1232  TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1233  };
1234  BOOL ret = TRUE;
1235 
1236  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1237  pDecodePara, pvStructInfo, *pcbStructInfo);
1238 
1240  pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1241 
1242  TRACE("Returning %d (%08x)\n", ret, GetLastError());
1243  return ret;
1244 }
1245 
1247  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1248  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1249 {
1250  BOOL ret = FALSE;
1251 
1252  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1253  pDecodePara, pvStructInfo, *pcbStructInfo);
1254 
1255  __TRY
1256  {
1257  DWORD size = 0;
1258 
1259  /* Unless told not to, first try to decode it as a signed crl. */
1261  {
1262  PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1263 
1266  &signedCrl, &size);
1267  if (ret)
1268  {
1269  size = 0;
1272  signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1273  pvStructInfo, pcbStructInfo);
1274  LocalFree(signedCrl);
1275  }
1276  }
1277  /* Failing that, try it as an unsigned crl */
1278  if (!ret)
1279  {
1280  size = 0;
1283  dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1284  }
1285  }
1287  {
1289  }
1290  __ENDTRY
1291 
1292  TRACE("Returning %d (%08x)\n", ret, GetLastError());
1293  return ret;
1294 }
1295 
1297  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1298 {
1299  BOOL ret = TRUE;
1300  DWORD dataLen;
1301 
1302  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1303  pvStructInfo, *pcbStructInfo);
1304 
1305  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1306  {
1307  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1308  DWORD bytesNeeded = sizeof(LPSTR);
1309 
1310  if (dataLen)
1311  {
1312  const BYTE *ptr;
1313  char str[32];
1314 
1315  snprintf(str, sizeof(str), "%d.%d",
1316  pbEncoded[1 + lenBytes] / 40,
1317  pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1318  * 40);
1319  bytesNeeded += strlen(str) + 1;
1320  for (ptr = pbEncoded + 2 + lenBytes; ret &&
1321  ptr - pbEncoded - 1 - lenBytes < dataLen; )
1322  {
1323  int val = 0;
1324 
1325  while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1326  (*ptr & 0x80))
1327  {
1328  val <<= 7;
1329  val |= *ptr & 0x7f;
1330  ptr++;
1331  }
1332  if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1333  (*ptr & 0x80))
1334  {
1336  ret = FALSE;
1337  }
1338  else
1339  {
1340  val <<= 7;
1341  val |= *ptr++;
1342  snprintf(str, sizeof(str), ".%d", val);
1343  bytesNeeded += strlen(str);
1344  }
1345  }
1346  }
1347  if (pcbDecoded)
1348  *pcbDecoded = 1 + lenBytes + dataLen;
1349  if (!pvStructInfo)
1350  *pcbStructInfo = bytesNeeded;
1351  else if (*pcbStructInfo < bytesNeeded)
1352  {
1353  *pcbStructInfo = bytesNeeded;
1355  ret = FALSE;
1356  }
1357  else
1358  {
1359  if (dataLen)
1360  {
1361  const BYTE *ptr;
1362  LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1363 
1364  *pszObjId = 0;
1365  sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1366  pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1367  40) * 40);
1368  pszObjId += strlen(pszObjId);
1369  for (ptr = pbEncoded + 2 + lenBytes; ret &&
1370  ptr - pbEncoded - 1 - lenBytes < dataLen; )
1371  {
1372  int val = 0;
1373 
1374  while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1375  (*ptr & 0x80))
1376  {
1377  val <<= 7;
1378  val |= *ptr & 0x7f;
1379  ptr++;
1380  }
1381  val <<= 7;
1382  val |= *ptr++;
1383  sprintf(pszObjId, ".%d", val);
1384  pszObjId += strlen(pszObjId);
1385  }
1386  }
1387  else
1388  *(LPSTR *)pvStructInfo = NULL;
1389  *pcbStructInfo = bytesNeeded;
1390  }
1391  }
1392  return ret;
1393 }
1394 
1396  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1397 {
1398  BOOL ret;
1399 
1400  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1401  pvStructInfo, *pcbStructInfo);
1402 
1403  if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1405  pvStructInfo, pcbStructInfo, pcbDecoded);
1406  else
1407  {
1409  ret = FALSE;
1410  }
1411  return ret;
1412 }
1413 
1415  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1416 {
1417  struct AsnDecodeSequenceItem items[] = {
1420  offsetof(CERT_EXTENSION, pszObjId), 0 },
1422  sizeof(BOOL), TRUE, FALSE, 0, 0 },
1425  offsetof(CERT_EXTENSION, Value.pbData) },
1426  };
1427  BOOL ret = TRUE;
1428  PCERT_EXTENSION ext = pvStructInfo;
1429 
1430  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1431  *pcbStructInfo);
1432 
1433  if (ext)
1434  TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1436  pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1437  pcbDecoded, ext ? ext->pszObjId : NULL);
1438  if (ext)
1439  TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1440  debugstr_a(ext->pszObjId));
1441  TRACE("returning %d (%08x)\n", ret, GetLastError());
1442  return ret;
1443 }
1444 
1446  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1447  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1448 {
1449  BOOL ret = TRUE;
1450 
1451  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1452  pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1453 
1454  __TRY
1455  {
1456  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1457  offsetof(CERT_EXTENSIONS, cExtension),
1458  offsetof(CERT_EXTENSIONS, rgExtension),
1459  sizeof(CERT_EXTENSIONS),
1461  offsetof(CERT_EXTENSION, pszObjId) };
1462  CERT_EXTENSIONS *exts = pvStructInfo;
1463 
1464  if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1465  exts->rgExtension = (CERT_EXTENSION *)(exts + 1);
1466  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1467  dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1468  }
1470  {
1472  ret = FALSE;
1473  }
1474  __ENDTRY
1475  return ret;
1476 }
1477 
1478 /* Warning: this assumes the address of value->Value.pbData is already set, in
1479  * order to avoid overwriting memory. (In some cases, it may change it, if it
1480  * doesn't copy anything to memory.) Be sure to set it correctly!
1481  */
1483  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1484  DWORD *pcbDecoded)
1485 {
1486  BOOL ret = TRUE;
1487  DWORD dataLen;
1488  CERT_NAME_VALUE *value = pvStructInfo;
1489 
1490  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1491  {
1492  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1493  DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1494 
1495  switch (pbEncoded[0])
1496  {
1497  case ASN_OCTETSTRING:
1498  valueType = CERT_RDN_OCTET_STRING;
1500  bytesNeeded += dataLen;
1501  break;
1502  case ASN_NUMERICSTRING:
1503  valueType = CERT_RDN_NUMERIC_STRING;
1505  bytesNeeded += dataLen;
1506  break;
1507  case ASN_PRINTABLESTRING:
1508  valueType = CERT_RDN_PRINTABLE_STRING;
1510  bytesNeeded += dataLen;
1511  break;
1512  case ASN_IA5STRING:
1513  valueType = CERT_RDN_IA5_STRING;
1515  bytesNeeded += dataLen;
1516  break;
1517  case ASN_T61STRING:
1518  valueType = CERT_RDN_T61_STRING;
1520  bytesNeeded += dataLen;
1521  break;
1522  case ASN_VIDEOTEXSTRING:
1523  valueType = CERT_RDN_VIDEOTEX_STRING;
1525  bytesNeeded += dataLen;
1526  break;
1527  case ASN_GRAPHICSTRING:
1528  valueType = CERT_RDN_GRAPHIC_STRING;
1530  bytesNeeded += dataLen;
1531  break;
1532  case ASN_VISIBLESTRING:
1533  valueType = CERT_RDN_VISIBLE_STRING;
1535  bytesNeeded += dataLen;
1536  break;
1537  case ASN_GENERALSTRING:
1538  valueType = CERT_RDN_GENERAL_STRING;
1540  bytesNeeded += dataLen;
1541  break;
1542  case ASN_UNIVERSALSTRING:
1543  FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545  return FALSE;
1546  case ASN_BMPSTRING:
1547  valueType = CERT_RDN_BMP_STRING;
1548  bytesNeeded += dataLen;
1549  break;
1550  case ASN_UTF8STRING:
1551  valueType = CERT_RDN_UTF8_STRING;
1552  bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1553  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * sizeof(WCHAR);
1554  break;
1555  default:
1557  return FALSE;
1558  }
1559 
1560  if (pcbDecoded)
1561  *pcbDecoded = 1 + lenBytes + dataLen;
1562  if (!value)
1563  *pcbStructInfo = bytesNeeded;
1564  else if (*pcbStructInfo < bytesNeeded)
1565  {
1566  *pcbStructInfo = bytesNeeded;
1568  ret = FALSE;
1569  }
1570  else
1571  {
1572  *pcbStructInfo = bytesNeeded;
1573  value->dwValueType = valueType;
1574  if (dataLen)
1575  {
1576  DWORD i;
1577 
1578  assert(value->Value.pbData);
1579  switch (pbEncoded[0])
1580  {
1581  case ASN_OCTETSTRING:
1582  case ASN_NUMERICSTRING:
1583  case ASN_PRINTABLESTRING:
1584  case ASN_IA5STRING:
1585  case ASN_T61STRING:
1586  case ASN_VIDEOTEXSTRING:
1587  case ASN_GRAPHICSTRING:
1588  case ASN_VISIBLESTRING:
1589  case ASN_GENERALSTRING:
1590  value->Value.cbData = dataLen;
1591  if (dataLen)
1592  {
1594  memcpy(value->Value.pbData,
1595  pbEncoded + 1 + lenBytes, dataLen);
1596  else
1597  value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1598  lenBytes;
1599  }
1600  break;
1601  case ASN_BMPSTRING:
1602  {
1603  LPWSTR str = (LPWSTR)value->Value.pbData;
1604 
1605  value->Value.cbData = dataLen;
1606  for (i = 0; i < dataLen / 2; i++)
1607  str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1608  pbEncoded[1 + lenBytes + 2 * i + 1];
1609  break;
1610  }
1611  case ASN_UTF8STRING:
1612  {
1613  LPWSTR str = (LPWSTR)value->Value.pbData;
1614 
1615  value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1616  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1617  str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1618  break;
1619  }
1620  }
1621  }
1622  else
1623  {
1624  value->Value.cbData = 0;
1625  value->Value.pbData = NULL;
1626  }
1627  }
1628  }
1629  return ret;
1630 }
1631 
1633  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1634  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1635 {
1636  BOOL ret = TRUE;
1637 
1638  __TRY
1639  {
1641  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1642  if (ret && pvStructInfo)
1643  {
1644  ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1645  pcbStructInfo, *pcbStructInfo);
1646  if (ret)
1647  {
1649 
1651  pvStructInfo = *(BYTE **)pvStructInfo;
1652  value = pvStructInfo;
1653  value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1655  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1656  pcbStructInfo, NULL);
1657  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1658  CRYPT_FreeSpace(pDecodePara, value);
1659  }
1660  }
1661  }
1663  {
1665  ret = FALSE;
1666  }
1667  __ENDTRY
1668  return ret;
1669 }
1670 
1672  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1673  DWORD *pcbDecoded)
1674 {
1675  BOOL ret = TRUE;
1676  DWORD dataLen;
1677  CERT_NAME_VALUE *value = pvStructInfo;
1678 
1679  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1680  {
1681  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1682  DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1683 
1684  switch (pbEncoded[0])
1685  {
1686  case ASN_NUMERICSTRING:
1687  valueType = CERT_RDN_NUMERIC_STRING;
1688  if (dataLen)
1689  bytesNeeded += (dataLen + 1) * 2;
1690  break;
1691  case ASN_PRINTABLESTRING:
1692  valueType = CERT_RDN_PRINTABLE_STRING;
1693  if (dataLen)
1694  bytesNeeded += (dataLen + 1) * 2;
1695  break;
1696  case ASN_IA5STRING:
1697  valueType = CERT_RDN_IA5_STRING;
1698  if (dataLen)
1699  bytesNeeded += (dataLen + 1) * 2;
1700  break;
1701  case ASN_T61STRING:
1702  valueType = CERT_RDN_T61_STRING;
1703  if (dataLen)
1704  bytesNeeded += (dataLen + 1) * 2;
1705  break;
1706  case ASN_VIDEOTEXSTRING:
1707  valueType = CERT_RDN_VIDEOTEX_STRING;
1708  if (dataLen)
1709  bytesNeeded += (dataLen + 1) * 2;
1710  break;
1711  case ASN_GRAPHICSTRING:
1712  valueType = CERT_RDN_GRAPHIC_STRING;
1713  if (dataLen)
1714  bytesNeeded += (dataLen + 1) * 2;
1715  break;
1716  case ASN_VISIBLESTRING:
1717  valueType = CERT_RDN_VISIBLE_STRING;
1718  if (dataLen)
1719  bytesNeeded += (dataLen + 1) * 2;
1720  break;
1721  case ASN_GENERALSTRING:
1722  valueType = CERT_RDN_GENERAL_STRING;
1723  if (dataLen)
1724  bytesNeeded += (dataLen + 1) * 2;
1725  break;
1726  case ASN_UNIVERSALSTRING:
1727  valueType = CERT_RDN_UNIVERSAL_STRING;
1728  if (dataLen)
1729  bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1730  break;
1731  case ASN_BMPSTRING:
1732  valueType = CERT_RDN_BMP_STRING;
1733  if (dataLen)
1734  bytesNeeded += dataLen + sizeof(WCHAR);
1735  break;
1736  case ASN_UTF8STRING:
1737  valueType = CERT_RDN_UTF8_STRING;
1738  if (dataLen)
1739  bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1740  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1741  break;
1742  default:
1744  return FALSE;
1745  }
1746 
1747  if (pcbDecoded)
1748  *pcbDecoded = 1 + lenBytes + dataLen;
1749  if (!value)
1750  *pcbStructInfo = bytesNeeded;
1751  else if (*pcbStructInfo < bytesNeeded)
1752  {
1753  *pcbStructInfo = bytesNeeded;
1755  ret = FALSE;
1756  }
1757  else
1758  {
1759  *pcbStructInfo = bytesNeeded;
1760  value->dwValueType = valueType;
1761  if (dataLen)
1762  {
1763  DWORD i;
1764  LPWSTR str = (LPWSTR)value->Value.pbData;
1765 
1766  assert(value->Value.pbData);
1767  switch (pbEncoded[0])
1768  {
1769  case ASN_NUMERICSTRING:
1770  case ASN_PRINTABLESTRING:
1771  case ASN_IA5STRING:
1772  case ASN_T61STRING:
1773  case ASN_VIDEOTEXSTRING:
1774  case ASN_GRAPHICSTRING:
1775  case ASN_VISIBLESTRING:
1776  case ASN_GENERALSTRING:
1777  value->Value.cbData = dataLen * 2;
1778  for (i = 0; i < dataLen; i++)
1779  str[i] = pbEncoded[1 + lenBytes + i];
1780  str[i] = 0;
1781  break;
1782  case ASN_UNIVERSALSTRING:
1783  value->Value.cbData = dataLen / 2;
1784  for (i = 0; i < dataLen / 4; i++)
1785  str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1786  | pbEncoded[1 + lenBytes + 2 * i + 3];
1787  str[i] = 0;
1788  break;
1789  case ASN_BMPSTRING:
1790  value->Value.cbData = dataLen;
1791  for (i = 0; i < dataLen / 2; i++)
1792  str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1793  pbEncoded[1 + lenBytes + 2 * i + 1];
1794  str[i] = 0;
1795  break;
1796  case ASN_UTF8STRING:
1797  value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1798  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1799  str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1800  *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1801  value->Value.cbData += sizeof(WCHAR);
1802  break;
1803  }
1804  }
1805  else
1806  {
1807  value->Value.cbData = 0;
1808  value->Value.pbData = NULL;
1809  }
1810  }
1811  }
1812  return ret;
1813 }
1814 
1816  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1817  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1818 {
1819  BOOL ret = TRUE;
1820 
1821  __TRY
1822  {
1824  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1825  if (ret && pvStructInfo)
1826  {
1827  ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1828  pcbStructInfo, *pcbStructInfo);
1829  if (ret)
1830  {
1832 
1834  pvStructInfo = *(BYTE **)pvStructInfo;
1835  value = pvStructInfo;
1836  value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1838  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1839  pcbStructInfo, NULL);
1840  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1841  CRYPT_FreeSpace(pDecodePara, value);
1842  }
1843  }
1844  }
1846  {
1848  ret = FALSE;
1849  }
1850  __ENDTRY
1851  return ret;
1852 }
1853 
1855  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1856 {
1857  BOOL ret;
1858  struct AsnDecodeSequenceItem items[] = {
1861  offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1862  { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1864  FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1865  };
1866  CERT_RDN_ATTR *attr = pvStructInfo;
1867 
1868  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1869  pvStructInfo, *pcbStructInfo);
1870 
1871  if (attr)
1872  TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1874  pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1875  attr ? attr->pszObjId : NULL);
1876  if (attr)
1877  {
1878  TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1879  debugstr_a(attr->pszObjId));
1880  TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1881  }
1882  TRACE("returning %d (%08x)\n", ret, GetLastError());
1883  return ret;
1884 }
1885 
1886 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1887  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1888 {
1889  BOOL ret = TRUE;
1890  struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1891  offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1892  sizeof(CERT_RDN),
1894  offsetof(CERT_RDN_ATTR, pszObjId) };
1895 
1896  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1897  NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1898  return ret;
1899 }
1900 
1902  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1903  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1904 {
1905  BOOL ret = TRUE;
1906 
1907  __TRY
1908  {
1909  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1911  sizeof(CERT_NAME_INFO),
1912  CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1913  offsetof(CERT_RDN, rgRDNAttr) };
1914  DWORD bytesNeeded = 0;
1915 
1916  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1917  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1918  NULL);
1919  if (ret)
1920  {
1921  if (!pvStructInfo)
1922  *pcbStructInfo = bytesNeeded;
1923  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1924  pvStructInfo, pcbStructInfo, bytesNeeded)))
1925  {
1927 
1929  pvStructInfo = *(BYTE **)pvStructInfo;
1930  info = pvStructInfo;
1931  info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1932  sizeof(CERT_NAME_INFO));
1933  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1934  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1935  &bytesNeeded, NULL);
1936  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1937  CRYPT_FreeSpace(pDecodePara, info);
1938  }
1939  }
1940  }
1942  {
1944  ret = FALSE;
1945  }
1946  __ENDTRY
1947  return ret;
1948 }
1949 
1951  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1952  DWORD *pcbDecoded)
1953 {
1954  BOOL ret;
1955  struct AsnDecodeSequenceItem items[] = {
1958  offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1959  { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1961  FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1962  };
1963  CERT_RDN_ATTR *attr = pvStructInfo;
1964 
1965  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1966  pvStructInfo, *pcbStructInfo);
1967 
1968  if (attr)
1969  TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1971  pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1972  attr ? attr->pszObjId : NULL);
1973  if (attr)
1974  {
1975  TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1976  debugstr_a(attr->pszObjId));
1977  TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1978  }
1979  TRACE("returning %d (%08x)\n", ret, GetLastError());
1980  return ret;
1981 }
1982 
1984  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1985 {
1986  BOOL ret = TRUE;
1987  struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1988  offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1989  sizeof(CERT_RDN),
1991  offsetof(CERT_RDN_ATTR, pszObjId) };
1992 
1993  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1994  NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1995  return ret;
1996 }
1997 
1999  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2000  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2001 {
2002  BOOL ret = TRUE;
2003 
2004  __TRY
2005  {
2006  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2008  sizeof(CERT_NAME_INFO),
2010  offsetof(CERT_RDN, rgRDNAttr) };
2011  DWORD bytesNeeded = 0;
2012 
2013  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2014  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2015  NULL);
2016  if (ret)
2017  {
2018  if (!pvStructInfo)
2019  *pcbStructInfo = bytesNeeded;
2020  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2021  pvStructInfo, pcbStructInfo, bytesNeeded)))
2022  {
2024 
2026  pvStructInfo = *(BYTE **)pvStructInfo;
2027  info = pvStructInfo;
2028  info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2029  sizeof(CERT_NAME_INFO));
2030  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2031  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2032  &bytesNeeded, NULL);
2033  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2034  CRYPT_FreeSpace(pDecodePara, info);
2035  }
2036  }
2037  }
2039  {
2041  ret = FALSE;
2042  }
2043  __ENDTRY
2044  return ret;
2045 }
2046 
2047 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2048  DWORD *pcbDecoded)
2049 {
2050  BOOL ret = TRUE, done = FALSE;
2051  DWORD indefiniteNestingLevels = 0, decoded = 0;
2052 
2053  TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2054 
2055  do {
2056  DWORD dataLen;
2057 
2058  if (!cbEncoded)
2059  done = TRUE;
2060  else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2061  &dataLen)))
2062  {
2063  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2064 
2065  if (dataLen == CMSG_INDEFINITE_LENGTH)
2066  {
2067  indefiniteNestingLevels++;
2068  pbEncoded += 1 + lenBytes;
2069  cbEncoded -= 1 + lenBytes;
2070  decoded += 1 + lenBytes;
2071  TRACE("indefiniteNestingLevels = %d\n",
2072  indefiniteNestingLevels);
2073  }
2074  else
2075  {
2076  if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2077  indefiniteNestingLevels)
2078  {
2079  indefiniteNestingLevels--;
2080  TRACE("indefiniteNestingLevels = %d\n",
2081  indefiniteNestingLevels);
2082  }
2083  pbEncoded += 1 + lenBytes + dataLen;
2084  cbEncoded -= 1 + lenBytes + dataLen;
2085  decoded += 1 + lenBytes + dataLen;
2086  if (!indefiniteNestingLevels)
2087  done = TRUE;
2088  }
2089  }
2090  } while (ret && !done);
2091  /* If we haven't found all 0 TLVs, we haven't found the end */
2092  if (ret && indefiniteNestingLevels)
2093  {
2095  ret = FALSE;
2096  }
2097  if (ret)
2098  *pcbDecoded = decoded;
2099  TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2100  return ret;
2101 }
2102 
2104  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2105  DWORD *pcbDecoded)
2106 {
2107  BOOL ret = TRUE;
2108  DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2109 
2110  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2111  pvStructInfo, *pcbStructInfo);
2112 
2113  if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2114  {
2116  bytesNeeded += encodedLen;
2117  if (!pvStructInfo)
2118  *pcbStructInfo = bytesNeeded;
2119  else if (*pcbStructInfo < bytesNeeded)
2120  {
2122  *pcbStructInfo = bytesNeeded;
2123  ret = FALSE;
2124  }
2125  else
2126  {
2127  PCRYPT_OBJID_BLOB blob = pvStructInfo;
2128 
2129  *pcbStructInfo = bytesNeeded;
2130  blob->cbData = encodedLen;
2131  if (encodedLen)
2132  {
2134  blob->pbData = (LPBYTE)pbEncoded;
2135  else
2136  {
2137  assert(blob->pbData);
2138  memcpy(blob->pbData, pbEncoded, blob->cbData);
2139  }
2140  }
2141  else
2142  blob->pbData = NULL;
2143  }
2144  if (pcbDecoded)
2145  *pcbDecoded = encodedLen;
2146  }
2147  return ret;
2148 }
2149 
2151  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2152 {
2153  BOOL ret;
2154  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2155  offsetof(CTL_USAGE, cUsageIdentifier),
2156  offsetof(CTL_USAGE, rgpszUsageIdentifier),
2157  sizeof(CTL_USAGE),
2158  CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2159 
2160  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2161  NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2162  return ret;
2163 }
2164 
2166  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2167  DWORD *pcbDecoded)
2168 {
2169  struct AsnArrayDescriptor arrayDesc = { 0,
2170  offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2171  FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2173  offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2174  BOOL ret;
2175 
2176  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2177  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2178  return ret;
2179 }
2180 
2182  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2183 {
2184  struct AsnDecodeSequenceItem items[] = {
2185  { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2187  offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2188  { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2190  FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2191  offsetof(CTL_ENTRY, rgAttribute), 0 },
2192  };
2193  BOOL ret = TRUE;
2194  CTL_ENTRY *entry = pvStructInfo;
2195 
2196  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2197  *pcbStructInfo);
2198 
2200  pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2201  pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2202  return ret;
2203 }
2204 
2206  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2207 {
2208  BOOL ret;
2209  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2210  offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2211  FINALMEMBERSIZE(CTL_INFO, cExtension),
2213  offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2214 
2215  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2216  pvStructInfo, *pcbStructInfo, pcbDecoded);
2217 
2218  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2219  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2220  return ret;
2221 }
2222 
2224  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2225  DWORD *pcbDecoded)
2226 {
2227  BOOL ret = TRUE;
2228  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2229  offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2230  FINALMEMBERSIZE(CTL_INFO, cExtension),
2232  offsetof(CERT_EXTENSION, pszObjId) };
2233 
2234  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2235  pvStructInfo, *pcbStructInfo, pcbDecoded);
2236 
2237  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2238  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2239  return ret;
2240 }
2241 
2243  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2244  DWORD *pcbDecoded)
2245 {
2246  BOOL ret;
2247  DWORD dataLen;
2248 
2249  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2250  {
2251  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2252 
2254  dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2255  if (ret && pcbDecoded)
2256  *pcbDecoded = 1 + lenBytes + dataLen;
2257  }
2258  return ret;
2259 }
2260 
2262  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2263  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2264 {
2265  BOOL ret = FALSE;
2266 
2267  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2268  pDecodePara, pvStructInfo, *pcbStructInfo);
2269 
2270  __TRY
2271  {
2272  struct AsnDecodeSequenceItem items[] = {
2273  { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2274  CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2275  { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2277  offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2278  { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2280  TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2281  { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2283  TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2284  { 0, offsetof(CTL_INFO, ThisUpdate),
2286  0 },
2287  { 0, offsetof(CTL_INFO, NextUpdate),
2289  0 },
2290  { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2292  FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2293  { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2295  MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2296  TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2297  { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2299  TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2300  };
2301 
2303  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2304  pcbStructInfo, NULL, NULL);
2305  }
2307  {
2309  }
2310  __ENDTRY
2311  return ret;
2312 }
2313 
2315  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2316  DWORD *pcbDecoded)
2317 {
2318  BOOL ret;
2319  struct AsnDecodeSequenceItem items[] = {
2322  offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2326  };
2327  PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2328 
2329  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2330  pvStructInfo, *pcbStructInfo);
2331 
2333  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2334  pcbDecoded, capability ? capability->pszObjId : NULL);
2335  TRACE("returning %d\n", ret);
2336  return ret;
2337 }
2338 
2340  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2341  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2342 {
2343  BOOL ret = FALSE;
2344 
2345  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2346  pDecodePara, pvStructInfo, *pcbStructInfo);
2347 
2348  __TRY
2349  {
2350  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2351  offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2352  offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2353  sizeof(CRYPT_SMIME_CAPABILITIES),
2355  offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2356  CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo;
2357 
2358  if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2359  capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1);
2360  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2361  dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2362  }
2364  {
2366  }
2367  __ENDTRY
2368  TRACE("returning %d\n", ret);
2369  return ret;
2370 }
2371 
2373  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2374  DWORD *pcbDecoded)
2375 {
2376  BOOL ret = TRUE;
2377  DWORD dataLen;
2378  LPSTR *pStr = pvStructInfo;
2379 
2380  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2381  {
2382  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2383  DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2384 
2385  if (pbEncoded[0] != ASN_IA5STRING)
2386  {
2388  ret = FALSE;
2389  }
2390  else
2391  {
2392  bytesNeeded += dataLen;
2393  if (pcbDecoded)
2394  *pcbDecoded = 1 + lenBytes + dataLen;
2395  if (!pvStructInfo)
2396  *pcbStructInfo = bytesNeeded;
2397  else if (*pcbStructInfo < bytesNeeded)
2398  {
2399  *pcbStructInfo = bytesNeeded;
2401  ret = FALSE;
2402  }
2403  else
2404  {
2405  *pcbStructInfo = bytesNeeded;
2406  if (dataLen)
2407  {
2408  LPSTR str = *pStr;
2409 
2410  assert(str);
2411  memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2412  str[dataLen] = 0;
2413  }
2414  else
2415  *pStr = NULL;
2416  }
2417  }
2418  }
2419  return ret;
2420 }
2421 
2423  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2424  DWORD *pcbDecoded)
2425 {
2426  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2430  CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2431  BOOL ret;
2432 
2433  TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2434  pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2435 
2436  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2437  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2438  TRACE("returning %d\n", ret);
2439  return ret;
2440 }
2441 
2443  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2444  DWORD *pcbDecoded)
2445 {
2446  BOOL ret;
2447  struct AsnDecodeSequenceItem items[] = {
2449  pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2450  offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2452  cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2455  rgNoticeNumbers), 0 },
2456  };
2457  DWORD bytesNeeded = 0;
2458 
2459  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2460  pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2461 
2463  pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2464  NULL);
2465  if (ret)
2466  {
2467  /* The caller is expecting a pointer to a
2468  * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2469  * CRYPT_AsnDecodeSequence is decoding a
2470  * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2471  * needed, and decode again if the requisite space is available.
2472  */
2473  bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2474  if (!pvStructInfo)
2475  *pcbStructInfo = bytesNeeded;
2476  else if (*pcbStructInfo < bytesNeeded)
2477  {
2478  *pcbStructInfo = bytesNeeded;
2480  ret = FALSE;
2481  }
2482  else
2483  {
2485 
2486  *pcbStructInfo = bytesNeeded;
2487  /* The pointer (pvStructInfo) passed in points to the first dynamic
2488  * pointer, so use it as the pointer to the
2489  * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2490  * appropriate offset for the first dynamic pointer within the
2491  * notice reference by pointing to the first memory location past
2492  * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2493  */
2494  noticeRef =
2495  *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2496  noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2499  NULL, noticeRef, &bytesNeeded, pcbDecoded, noticeRef->pszOrganization);
2500  }
2501  }
2502  TRACE("returning %d\n", ret);
2503  return ret;
2504 }
2505 
2507  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2508  DWORD *pcbDecoded)
2509 {
2510  BOOL ret = TRUE;
2511  DWORD dataLen;
2512 
2513  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2514  {
2515  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2516  DWORD bytesNeeded = sizeof(LPWSTR);
2517 
2518  switch (pbEncoded[0])
2519  {
2520  case ASN_NUMERICSTRING:
2521  if (dataLen)
2522  bytesNeeded += (dataLen + 1) * 2;
2523  break;
2524  case ASN_PRINTABLESTRING:
2525  if (dataLen)
2526  bytesNeeded += (dataLen + 1) * 2;
2527  break;
2528  case ASN_IA5STRING:
2529  if (dataLen)
2530  bytesNeeded += (dataLen + 1) * 2;
2531  break;
2532  case ASN_T61STRING:
2533  if (dataLen)
2534  bytesNeeded += (dataLen + 1) * 2;
2535  break;
2536  case ASN_VIDEOTEXSTRING:
2537  if (dataLen)
2538  bytesNeeded += (dataLen + 1) * 2;
2539  break;
2540  case ASN_GRAPHICSTRING:
2541  if (dataLen)
2542  bytesNeeded += (dataLen + 1) * 2;
2543  break;
2544  case ASN_VISIBLESTRING:
2545  if (dataLen)
2546  bytesNeeded += (dataLen + 1) * 2;
2547  break;
2548  case ASN_GENERALSTRING:
2549  if (dataLen)
2550  bytesNeeded += (dataLen + 1) * 2;
2551  break;
2552  case ASN_UNIVERSALSTRING:
2553  if (dataLen)
2554  bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2555  break;
2556  case ASN_BMPSTRING:
2557  if (dataLen)
2558  bytesNeeded += dataLen + sizeof(WCHAR);
2559  break;
2560  case ASN_UTF8STRING:
2561  if (dataLen)
2562  bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2563  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2564  break;
2565  default:
2567  return FALSE;
2568  }
2569 
2570  if (pcbDecoded)
2571  *pcbDecoded = 1 + lenBytes + dataLen;
2572  if (!pvStructInfo)
2573  *pcbStructInfo = bytesNeeded;
2574  else if (*pcbStructInfo < bytesNeeded)
2575  {
2576  *pcbStructInfo = bytesNeeded;
2578  ret = FALSE;
2579  }
2580  else
2581  {
2582  LPWSTR *pStr = pvStructInfo;
2583 
2584  *pcbStructInfo = bytesNeeded;
2585  if (dataLen)
2586  {
2587  DWORD i;
2588  LPWSTR str = *(LPWSTR *)pStr;
2589 
2590  assert(str);
2591  switch (pbEncoded[0])
2592  {
2593  case ASN_NUMERICSTRING:
2594  case ASN_PRINTABLESTRING:
2595  case ASN_IA5STRING:
2596  case ASN_T61STRING:
2597  case ASN_VIDEOTEXSTRING:
2598  case ASN_GRAPHICSTRING:
2599  case ASN_VISIBLESTRING:
2600  case ASN_GENERALSTRING:
2601  for (i = 0; i < dataLen; i++)
2602  str[i] = pbEncoded[1 + lenBytes + i];
2603  str[i] = 0;
2604  break;
2605  case ASN_UNIVERSALSTRING:
2606  for (i = 0; i < dataLen / 4; i++)
2607  str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2608  | pbEncoded[1 + lenBytes + 2 * i + 3];
2609  str[i] = 0;
2610  break;
2611  case ASN_BMPSTRING:
2612  for (i = 0; i < dataLen / 2; i++)
2613  str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2614  pbEncoded[1 + lenBytes + 2 * i + 1];
2615  str[i] = 0;
2616  break;
2617  case ASN_UTF8STRING:
2618  {
2619  int len = MultiByteToWideChar(CP_UTF8, 0,
2620  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2621  str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2622  str[len] = 0;
2623  break;
2624  }
2625  }
2626  }
2627  else
2628  *pStr = NULL;
2629  }
2630  }
2631  return ret;
2632 }
2633 
2635  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2636  DWORD *pcbStructInfo, DWORD *pcbDecoded)
2637 {
2638  BOOL ret;
2639  struct AsnDecodeSequenceItem items[] = {
2641  pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2643  offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2644  { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2646  offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2647  };
2649 
2650  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2651  pvStructInfo, *pcbStructInfo);
2652 
2654  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2655  pcbDecoded, notice ? notice->pNoticeReference : NULL);
2656  TRACE("returning %d\n", ret);
2657  return ret;
2658 }
2659 
2661  DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2662  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2663  void *pvStructInfo, DWORD *pcbStructInfo)
2664 {
2665  BOOL ret = FALSE;
2666 
2667  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2668  pDecodePara, pvStructInfo, *pcbStructInfo);
2669 
2670  __TRY
2671  {
2672  DWORD bytesNeeded = 0;
2673 
2675  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2676  NULL);
2677  if (ret)
2678  {
2679  if (!pvStructInfo)
2680  *pcbStructInfo = bytesNeeded;
2681  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2682  pvStructInfo, pcbStructInfo, bytesNeeded)))
2683  {
2685 
2687  pvStructInfo = *(BYTE **)pvStructInfo;
2688  notice = pvStructInfo;
2689  notice->pNoticeReference =
2691  ((BYTE *)pvStructInfo +
2694  pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2695  pvStructInfo, &bytesNeeded, NULL);
2696  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2697  CRYPT_FreeSpace(pDecodePara, notice);
2698  }
2699  }
2700  }
2702  {
2704  }
2705  __ENDTRY
2706  TRACE("returning %d\n", ret);
2707  return ret;
2708 }
2709 
2711  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2712  DWORD *pcbDecoded)
2713 {
2714  BOOL ret;
2715  struct AsnArrayDescriptor arrayDesc = { 0,
2716  offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2720 
2721  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2722  pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2723 
2724  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2725  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2726  return ret;
2727 }
2728 
2730  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2731  DWORD *pcbDecoded)
2732 {
2733  BOOL ret;
2734  struct AsnDecodeSequenceItem items[] = {
2737  offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2741  TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2742  };
2743  PCRYPT_ATTRIBUTE attr = pvStructInfo;
2744 
2745  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2746  pvStructInfo, *pcbStructInfo);
2747 
2749  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2750  pcbDecoded, attr ? attr->pszObjId : NULL);
2751  TRACE("returning %d\n", ret);
2752  return ret;
2753 }
2754 
2756  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2757  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2758 {
2759  BOOL ret = FALSE;
2760 
2761  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2762  pDecodePara, pvStructInfo, *pcbStructInfo);
2763 
2764  __TRY
2765  {
2766  DWORD bytesNeeded = 0;
2767 
2769  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2770  if (ret)
2771  {
2772  if (!pvStructInfo)
2773  *pcbStructInfo = bytesNeeded;
2774  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2775  pvStructInfo, pcbStructInfo, bytesNeeded)))
2776  {
2778 
2780  pvStructInfo = *(BYTE **)pvStructInfo;
2781  attr = pvStructInfo;
2782  attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2783  sizeof(CRYPT_ATTRIBUTE));
2785  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2786  NULL);
2787  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2788  CRYPT_FreeSpace(pDecodePara, attr);
2789  }
2790  }
2791  }
2793  {
2795  }
2796  __ENDTRY
2797  TRACE("returning %d\n", ret);
2798  return ret;
2799 }
2800 
2802  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2803  DWORD *pcbDecoded)
2804 {
2805  struct AsnArrayDescriptor arrayDesc = { 0,
2807  sizeof(CRYPT_ATTRIBUTES),
2809  offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2810  BOOL ret;
2811 
2812  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2813  NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2814  return ret;
2815 }
2816 
2818  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2819  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2820 {
2821  BOOL ret = FALSE;
2822 
2823  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2824  pDecodePara, pvStructInfo, *pcbStructInfo);
2825 
2826  __TRY
2827  {
2828  struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2830  sizeof(CRYPT_ATTRIBUTES),
2832  TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2833  CRYPT_ATTRIBUTES *attrs = pvStructInfo;
2834 
2835  if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2836  attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1);
2837  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2838  dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2839  }
2841  {
2843  }
2844  __ENDTRY
2845  TRACE("returning %d\n", ret);
2846  return ret;
2847 }
2848 
2850  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2851 {
2852  CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2853  BOOL ret = TRUE;
2854  struct AsnDecodeSequenceItem items[] = {
2857  offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2861  };
2862 
2863  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2864  pvStructInfo, *pcbStructInfo, pcbDecoded);
2865 
2867  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2868  pcbDecoded, algo ? algo->pszObjId : NULL);
2869  if (ret && pvStructInfo)
2870  {
2871  TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2872  debugstr_a(algo->pszObjId));
2873  }
2874  return ret;
2875 }
2876 
2878  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2879  DWORD *pcbDecoded)
2880 {
2881  BOOL ret = TRUE;
2882  struct AsnDecodeSequenceItem items[] = {
2886  Algorithm.pszObjId) },
2889  offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2890  };
2891  PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2892 
2894  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2895  pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2896  return ret;
2897 }
2898 
2900  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2901  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2902 {
2903  BOOL ret = TRUE;
2904 
2905  __TRY
2906  {
2907  DWORD bytesNeeded = 0;
2908 
2910  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2911  {
2912  if (!pvStructInfo)
2913  *pcbStructInfo = bytesNeeded;
2914  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2915  pvStructInfo, pcbStructInfo, bytesNeeded)))
2916  {
2918 
2920  pvStructInfo = *(BYTE **)pvStructInfo;
2921  info = pvStructInfo;
2922  info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2923  sizeof(CERT_PUBLIC_KEY_INFO);
2925  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2926  &bytesNeeded, NULL);
2927  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2928  CRYPT_FreeSpace(pDecodePara, info);
2929  }
2930  }
2931  }
2933  {
2935  ret = FALSE;
2936  }
2937  __ENDTRY
2938  return ret;
2939 }
2940 
2941 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2942  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2943 {
2944  BOOL ret;
2945 
2946  if (cbEncoded < 3)
2947  {
2949  return FALSE;
2950  }
2951  if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2952  {
2954  return FALSE;
2955  }
2956  if (pbEncoded[1] > 1)
2957  {
2959  return FALSE;
2960  }
2961  if (pcbDecoded)
2962  *pcbDecoded = 3;
2963  if (!pvStructInfo)
2964  {
2965  *pcbStructInfo = sizeof(BOOL);
2966  ret = TRUE;
2967  }
2968  else if (*pcbStructInfo < sizeof(BOOL))
2969  {
2970  *pcbStructInfo = sizeof(BOOL);
2972  ret = FALSE;
2973  }
2974  else
2975  {
2976  *pcbStructInfo = sizeof(BOOL);
2977  *(BOOL *)pvStructInfo = pbEncoded[2] != 0;
2978  ret = TRUE;
2979  }
2980  TRACE("returning %d (%08x)\n", ret, GetLastError());
2981  return ret;
2982 }
2983 
2985  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2986 {
2987  PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2988  DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2989  BOOL ret;
2990 
2991  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2992  pvStructInfo, *pcbStructInfo);
2993 
2994  if (cbEncoded < 2)
2995  {
2997  return FALSE;
2998  }
2999  lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3000  if (1 + lenBytes > cbEncoded)
3001  {
3003  return FALSE;
3004  }
3005  if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3006  {
3007  switch (pbEncoded[0] & ASN_TYPE_MASK)
3008  {
3009  case 1: /* rfc822Name */
3010  case 2: /* dNSName */
3011  case 6: /* uniformResourceIdentifier */
3012  if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
3013  {
3015  ret = FALSE;
3016  }
3017  else
3018  bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3019  break;
3020  case 4: /* directoryName */
3021  case 7: /* iPAddress */
3022  bytesNeeded += dataLen;
3023  break;
3024  case 8: /* registeredID */
3025  ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3026  &dataLen, NULL);
3027  if (ret)
3028  {
3029  /* FIXME: ugly, shouldn't need to know internals of OID decode
3030  * function to use it.
3031  */
3032  bytesNeeded += dataLen - sizeof(LPSTR);
3033  }
3034  break;
3035  case 0: /* otherName */
3036  FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3038  ret = FALSE;
3039  break;
3040  case 3: /* x400Address, unimplemented */
3041  case 5: /* ediPartyName, unimplemented */
3042  TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3044  ret = FALSE;
3045  break;
3046  default:
3047  TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3049  ret = FALSE;
3050  }
3051  if (ret)
3052  {
3053  if (pcbDecoded)
3054  *pcbDecoded = 1 + lenBytes + dataLen;
3055  if (!entry)
3056  *pcbStructInfo = bytesNeeded;
3057  else if (*pcbStructInfo < bytesNeeded)
3058  {
3059  *pcbStructInfo = bytesNeeded;
3061  ret = FALSE;
3062  }
3063  else
3064  {
3065  *pcbStructInfo = bytesNeeded;
3066  /* MS used values one greater than the asn1 ones.. sigh */
3067  entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3068  switch (pbEncoded[0] & ASN_TYPE_MASK)
3069  {
3070  case 1: /* rfc822Name */
3071  case 2: /* dNSName */
3072  case 6: /* uniformResourceIdentifier */
3073  {
3074  DWORD i;
3075 
3076  for (i = 0; i < dataLen; i++)
3077  entry->u.pwszURL[i] =
3078  (WCHAR)pbEncoded[1 + lenBytes + i];
3079  entry->u.pwszURL[i] = 0;
3080  TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3081  debugstr_w(entry->u.pwszURL));
3082  break;
3083  }
3084  case 4: /* directoryName */
3085  /* The data are memory-equivalent with the IPAddress case,
3086  * fall-through
3087  */
3088  case 7: /* iPAddress */
3089  /* The next data pointer is in the pwszURL spot, that is,
3090  * the first 4 bytes. Need to move it to the next spot.
3091  */
3092  entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3093  entry->u.IPAddress.cbData = dataLen;
3094  memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3095  dataLen);
3096  break;
3097  case 8: /* registeredID */
3098  ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3099  &entry->u.pszRegisteredID, &dataLen, NULL);
3100  break;
3101  }
3102  }
3103  }
3104  }
3105  return ret;
3106 }
3107 
3109  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3110  DWORD *pcbDecoded)
3111 {
3112  BOOL ret;
3113  struct AsnArrayDescriptor arrayDesc = { 0,
3114  offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3115  offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3116  sizeof(CERT_ALT_NAME_INFO),
3118  offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3119 
3120  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3121  pvStructInfo, *pcbStructInfo, pcbDecoded);
3122 
3123  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3124  NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3125  return ret;
3126 }
3127 
3129  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3130  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3131 {
3132  BOOL ret;
3133 
3134  __TRY
3135  {
3136  struct AsnDecodeSequenceItem items[] = {
3139  TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3141  offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3143  offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3145  CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3146  sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3147  offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3148  };
3149 
3151  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3152  pcbStructInfo, NULL, NULL);
3153  }
3155  {
3157  ret = FALSE;
3158  }
3159  __ENDTRY
3160  return ret;
3161 }
3162 
3164  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3165  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3166 {
3167  BOOL ret;
3168 
3169  __TRY
3170  {
3171  struct AsnDecodeSequenceItem items[] = {
3174  TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3176  offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3179  AuthorityCertIssuer.rgAltEntry), 0 },
3181  AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3182  sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3184  AuthorityCertSerialNumber.pbData), 0 },
3185  };
3186 
3188  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3189  pcbStructInfo, NULL, NULL);
3190  }
3192  {
3194  ret = FALSE;
3195  }
3196  __ENDTRY
3197  return ret;
3198 }
3199 
3201  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3202  DWORD *pcbDecoded)
3203 {
3204  struct AsnDecodeSequenceItem items[] = {
3205  { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3207  offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3208  { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3210  TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3211  };
3212  CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3213 
3215  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3216  pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3217 }
3218 
3220  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3221  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3222 {
3223  BOOL ret;
3224 
3225  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3226  pDecodePara, pvStructInfo, *pcbStructInfo);
3227 
3228  __TRY
3229  {
3230  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3232  offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3235  TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3236  CERT_AUTHORITY_INFO_ACCESS *info = pvStructInfo;
3237 
3238  if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3239  info->rgAccDescr = (CERT_ACCESS_DESCRIPTION *)(info + 1);
3240  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3241  dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3242  }
3244  {
3246  ret = FALSE;
3247  }
3248  __ENDTRY
3249  return ret;
3250 }
3251 
3253  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3254 {
3255  BOOL ret;
3256  DWORD dataLen;
3257 
3258  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3259  pvStructInfo, *pcbStructInfo, pcbDecoded);
3260 
3261  /* The caller has already checked the tag, no need to check it again.
3262  * Check the outer length is valid:
3263  */
3264  if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3265  {
3266  BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3267  DWORD innerLen;
3268 
3269  pbEncoded += 1 + lenBytes;
3270  cbEncoded -= 1 + lenBytes;
3271  if (dataLen == CMSG_INDEFINITE_LENGTH)
3272  cbEncoded -= 2; /* space for 0 TLV */
3273  /* Check the inner length is valid: */
3274  if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3275  {
3276  DWORD decodedLen;
3277 
3279  pvStructInfo, pcbStructInfo, &decodedLen);
3280  if (dataLen == CMSG_INDEFINITE_LENGTH)
3281  {
3282  if (*(pbEncoded + decodedLen) != 0 ||
3283  *(pbEncoded + decodedLen + 1) != 0)
3284  {
3285  TRACE("expected 0 TLV, got {%02x,%02x}\n",
3286  *(pbEncoded + decodedLen),
3287  *(pbEncoded + decodedLen + 1));
3289  ret = FALSE;
3290  }
3291  else
3292  decodedLen += 2;
3293  }
3294  if (ret && pcbDecoded)
3295  {
3296  *pcbDecoded = 1 + lenBytes + decodedLen;
3297  TRACE("decoded %d bytes\n", *pcbDecoded);
3298  }
3299  }
3300  }
3301  return ret;
3302 }
3303 
3305  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3306  DWORD *pcbDecoded)
3307 {
3308  CRYPT_CONTENT_INFO *info = pvStructInfo;
3309  struct AsnDecodeSequenceItem items[] = {
3312  offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3313  { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3315  sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3316  offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3317  };
3318  BOOL ret;
3319 
3320  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3321  pvStructInfo, *pcbStructInfo, pcbDecoded);
3322 
3324  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3325  pcbDecoded, info ? info->pszObjId : NULL);
3326  return ret;
3327 }
3328 
3330  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3331  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3332 {
3333  BOOL ret = FALSE;
3334 
3335  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3336  pDecodePara, pvStructInfo, *pcbStructInfo);
3337 
3338  __TRY
3339  {
3341  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3342  if (ret && pvStructInfo)
3343  {
3344  ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3345  pcbStructInfo, *pcbStructInfo);
3346  if (ret)
3347  {
3349 
3351  pvStructInfo = *(BYTE **)pvStructInfo;
3352  info = pvStructInfo;
3353  info->pszObjId = (LPSTR)((BYTE *)info +
3354  sizeof(CRYPT_CONTENT_INFO));
3356  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3357  pcbStructInfo, NULL);
3358  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3359  CRYPT_FreeSpace(pDecodePara, info);
3360  }
3361  }
3362  }
3364  {
3366  }
3367  __ENDTRY
3368  return ret;
3369 }
3370 
3372  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3373  CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3374 {
3375  BOOL ret;
3376  struct AsnDecodeSequenceItem items[] = {
3378  CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3379  { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3381  FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3382  0 },
3383  { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3386  ContentInfo.pszObjId), 0 },
3389  offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3390  };
3391 
3393  pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3394  NULL, NULL);
3395  return ret;
3396 }
3397 
3399  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3400  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3401 {
3402  BOOL ret = TRUE;
3403 
3404  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3405  pDecodePara, pvStructInfo, *pcbStructInfo);
3406 
3407  __TRY
3408  {
3409  DWORD bytesNeeded = 0;
3410 
3411  if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3412  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3413  {
3414  if (!pvStructInfo)
3415  *pcbStructInfo = bytesNeeded;
3416  else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3417  pvStructInfo, pcbStructInfo, bytesNeeded)))
3418  {
3420 
3422  pvStructInfo = *(BYTE **)pvStructInfo;
3423  name = pvStructInfo;
3424  name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3425  ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3427  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3428  &bytesNeeded, NULL);
3429  if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3430  CRYPT_FreeSpace(pDecodePara, name);
3431  }
3432  }
3433  }
3435  {
3437  ret = FALSE;
3438  }
3439  __ENDTRY
3440  return ret;
3441 }
3442 
3444 {
3447 };
3448 
3450  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3451  DWORD *pcbDecoded)
3452 {
3453  BOOL ret = TRUE;
3454  DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3455 
3456  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3457  pvStructInfo, *pcbStructInfo, pcbDecoded);
3458 
3459  if (!pvStructInfo)
3460  {
3462  &size, pcbDecoded);
3463  *pcbStructInfo = bytesNeeded;
3464  }
3465  else if (*pcbStructInfo < bytesNeeded)
3466  {
3468  *pcbStructInfo = bytesNeeded;
3469  ret = FALSE;
3470  }
3471  else
3472  {
3473  struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3474 
3475  *pcbStructInfo = bytesNeeded;
3476  size = sizeof(constraint->dwPathLenConstraint);
3478  &constraint->dwPathLenConstraint, &size, pcbDecoded);
3479  if (ret)
3480  constraint->fPathLenConstraint = TRUE;
3481  TRACE("got an int, dwPathLenConstraint is %d\n",
3482  constraint->dwPathLenConstraint);
3483  }
3484  TRACE("returning %d (%08x)\n", ret, GetLastError());
3485  return ret;
3486 }
3487 
3489  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3490  DWORD *pcbDecoded)
3491 {
3492  BOOL ret;
3493  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3494  offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3495  offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3496  FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3499 
3500  TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3501  pvStructInfo, *pcbStructInfo, pcbDecoded);
3502 
3503  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3504  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3505  TRACE("Returning %d (%08x)\n", ret, GetLastError());
3506  return ret;
3507 }
3508 
3510  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3511  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3512 {
3513  BOOL ret;
3514 
3515  __TRY
3516  {
3517  struct AsnDecodeSequenceItem items[] = {
3520  offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3522  fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3523  sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3525  cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3526  FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3527  TRUE, TRUE,
3528  offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3529  };
3530 
3532  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3533  pcbStructInfo, NULL, NULL);
3534  }
3536  {
3538  ret = FALSE;
3539  }
3540  __ENDTRY
3541  return ret;
3542 }
3543 
3545  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3546  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3547 {
3548  BOOL ret;
3549 
3550  __TRY
3551  {
3552  struct AsnDecodeSequenceItem items[] = {
3554  CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3556  fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3557  sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3558  };
3559 
3561  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3562  pcbStructInfo, NULL, NULL);
3563  }
3565  {
3567  ret = FALSE;
3568  }
3569  __ENDTRY
3570  return ret;
3571 }
3572 
3574  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3575  DWORD *pcbDecoded)
3576 {
3577  struct AsnDecodeSequenceItem items[] = {
3579  pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3580  FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3581  0 },
3582  { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3584  offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3585  };
3586  BOOL ret;
3587  CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3588 
3589  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3590  pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3591 
3593  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3594  pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3595  return ret;
3596 }
3597 
3599  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3600  DWORD *pcbDecoded)
3601 {
3602  BOOL ret;
3603  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3604  offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3605  offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3606  FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3608  offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3609 
3610  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3611  pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3612 
3613  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3614  dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3615  TRACE("Returning %d (%08x)\n", ret, GetLastError());
3616  return ret;
3617 }
3618 
3620  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3621 {
3622  struct AsnDecodeSequenceItem items[] = {
3623  { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3625  offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3626  { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3628  FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3629  TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3630  };
3631  CERT_POLICY_INFO *info = pvStructInfo;
3632  BOOL ret;
3633 
3634  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3635  pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3636 
3638  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3639  pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3640  return ret;
3641 }
3642 
3644  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3645  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3646 {
3647  BOOL ret = FALSE;
3648 
3649  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3650  pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3651 
3652  __TRY
3653  {
3654  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3655  offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3656  offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3657  sizeof(CERT_POLICIES_INFO),
3659  offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3660  CERT_POLICIES_INFO *info = pvStructInfo;
3661 
3662  if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3663  info->rgPolicyInfo = (CERT_POLICY_INFO *)(info + 1);
3664 
3665  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3666  dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3667  }
3669  {
3671  }
3672  __ENDTRY
3673  return ret;
3674 }
3675 
3677  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3678  DWORD *pcbDecoded)
3679 {
3680  struct AsnDecodeSequenceItem items[] = {
3682  pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3683  FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 },
3685  pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3686  FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 },
3687  };
3688  CERT_POLICY_MAPPING *mapping = pvStructInfo;
3689  BOOL ret;
3690 
3691  TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3692  pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3693 
3695  pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3696  pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
3697  return ret;
3698 }
3699 
3701  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3702  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3703 {
3704  BOOL ret = FALSE;
3705 
3706  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3707  pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3708 
3709  __TRY
3710  {
3711  struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3712  offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping),
3713  offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping),
3714  sizeof(CERT_POLICY_MAPPING),
3716  offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) };
3717  CERT_POLICY_MAPPINGS_INFO *info = pvStructInfo;
3718 
3719  if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3720  info->rgPolicyMapping = (CERT_POLICY_MAPPING *)(info + 1);
3721  ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3722  dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3723  }
3725  {
3727  }
3728  __ENDTRY
3729  return ret;
3730 }
3731 
3733  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3734  DWORD *pcbDecoded)
3735 {
3736  BOOL ret;
3737  DWORD skip, size = sizeof(skip);
3738 
3739  if (!cbEncoded)
3740  {
3742  return FALSE;
3743  }
3744  if (pbEncoded[0] != (ASN_CONTEXT | 0))
3745  {
3747  return FALSE;
3748  }
3749  if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3750  &skip, &size, pcbDecoded)))
3751  {
3753  fRequireExplicitPolicy, fInhibitPolicyMapping);
3754 
3755  if (!pvStructInfo)
3756  *pcbStructInfo = bytesNeeded;
3757  else if (*pcbStructInfo < bytesNeeded)
3758  {
3759  *pcbStructInfo = bytesNeeded;
3761  ret = FALSE;
3762  }
3763  else
3764  {
3766  CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy);
3767 
3768  *pcbStructInfo = bytesNeeded;
3769  /* The BOOL is implicit: if the integer is present, then it's
3770  * TRUE.
3771  */
3772  info->fRequireExplicitPolicy = TRUE;
3773  info->dwRequireExplicitPolicySkipCerts = skip;
3774  }
3775  }
3776  return ret;
3777 }
3778 
3780  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3781  DWORD *pcbDecoded)
3782 {
3783  BOOL ret;
3784  DWORD skip, size = sizeof(skip);
3785 
3786  if (!cbEncoded)
3787  {
3789  return FALSE;
3790  }
3791  if (pbEncoded[0] != (ASN_CONTEXT | 1))
3792  {
3794  return FALSE;
3795  }
3796  if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3797  &skip, &size, pcbDecoded)))
3798  {
3800  fInhibitPolicyMapping);
3801 
3802  if (!pvStructInfo)
3803  *pcbStructInfo = bytesNeeded;
3804  else if (*pcbStructInfo < bytesNeeded)
3805  {
3806  *pcbStructInfo = bytesNeeded;
3808  ret = FALSE;
3809  }
3810  else
3811  {
3813  CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping);
3814 
3815  *pcbStructInfo = bytesNeeded;
3816  /* The BOOL is implicit: if the integer is present, then it's
3817  * TRUE.
3818  */
3819  info->fInhibitPolicyMapping = TRUE;
3820  info->dwInhibitPolicyMappingSkipCerts = skip;
3821  }
3822  }
3823  return ret;
3824 }
3825 
3827  DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
3828  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3829  void *pvStructInfo, DWORD *pcbStructInfo)
3830 {
3831  BOOL ret = FALSE;
3832 
3833  TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3834  pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3835 
3836  __TRY
3837  {
3838  struct AsnDecodeSequenceItem items[] = {
3839  { ASN_CONTEXT | 0,
3840  offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy),
3842  MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy,
3843  fInhibitPolicyMapping), TRUE, FALSE, 0, 0 },
3844  { ASN_CONTEXT | 1,
3845  offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3847  FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3848  TRUE, FALSE, 0, 0 },
3849  };
3850 
3852  pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3853  pcbStructInfo, NULL, NULL);
3854  }
3856  {
3858  }
3859  __ENDTRY
3860  return ret;
3861 }
3862 
3863 #define RSA1_MAGIC 0x31415352
3864 
3866 {
3869 };
3870 
3872  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3873  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3874 {
3875  BOOL ret;
3876 
3877  __TRY
3878  {
3879  struct AsnDecodeSequenceItem items[] = {
3882  FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3883  0 },
3884  { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3885  CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3886  };
3887  struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3888  DWORD size = 0;
3889