2 * Copyright 2005-2007 Juan Lang
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.
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.
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
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.
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.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt);
67 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
68 DWORD, DWORD, void *, DWORD *);
69 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
70 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
76 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
78 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
79 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
81 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
82 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
88 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
92 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
93 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
94 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
97 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
99 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
100 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
101 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
102 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
103 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
104 * member has been initialized, doesn't do exception handling, and doesn't do
105 * memory allocation. Also doesn't check tag, assumes the caller has checked
108 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
111 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
112 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
113 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
116 /* Gets the number of length bytes from the given (leading) length byte */
117 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
119 /* Helper function to get the encoded length of the data starting at pbEncoded,
120 * where pbEncoded[0] is the tag. If the data are too short to contain a
121 * length or if the length is too large for cbEncoded, sets an appropriate
122 * error code and returns FALSE. If the encoded length is unknown due to
123 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
125 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
132 SetLastError(CRYPT_E_ASN1_CORRUPT);
135 else if (pbEncoded[1] <= 0x7f)
137 if (pbEncoded[1] + 1 > cbEncoded)
139 SetLastError(CRYPT_E_ASN1_EOD);
148 else if (pbEncoded[1] == 0x80)
150 *len = CMSG_INDEFINITE_LENGTH;
155 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
157 if (lenLen > sizeof(DWORD) + 1)
159 SetLastError(CRYPT_E_ASN1_LARGE);
162 else if (lenLen + 2 > cbEncoded)
164 SetLastError(CRYPT_E_ASN1_CORRUPT);
177 if (out + lenLen + 1 > cbEncoded)
179 SetLastError(CRYPT_E_ASN1_EOD);
192 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
193 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
197 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
198 *len == CMSG_INDEFINITE_LENGTH)
200 SetLastError(CRYPT_E_ASN1_CORRUPT);
206 /* Helper function to check *pcbStructInfo, set it to the required size, and
207 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
208 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
209 * pointer to the newly allocated memory.
211 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
212 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
217 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
219 if (pDecodePara && pDecodePara->pfnAlloc)
220 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
222 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
223 if (!*(BYTE **)pvStructInfo)
226 *pcbStructInfo = bytesNeeded;
228 else if (*pcbStructInfo < bytesNeeded)
230 *pcbStructInfo = bytesNeeded;
231 SetLastError(ERROR_MORE_DATA);
237 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
239 if (pDecodePara && pDecodePara->pfnFree)
240 pDecodePara->pfnFree(pv);
245 /* Helper function to check *pcbStructInfo and set it to the required size.
246 * Assumes pvStructInfo is not NULL.
248 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
252 if (*pcbStructInfo < bytesNeeded)
254 *pcbStructInfo = bytesNeeded;
255 SetLastError(ERROR_MORE_DATA);
260 *pcbStructInfo = bytesNeeded;
267 * The expected tag of the item. If tag is 0, decodeFunc is called
268 * regardless of the tag value seen.
270 * A sequence is decoded into a struct. The offset member is the
271 * offset of this item within that struct.
273 * The decoder function to use. If this is NULL, then the member isn't
274 * decoded, but minSize space is reserved for it.
276 * The minimum amount of space occupied after decoding. You must set this.
278 * If true, and the tag doesn't match the expected tag for this item,
279 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
280 * filled with 0 for this member.
281 * hasPointer, pointerOffset:
282 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
283 * the offset within the struct of the data pointer (or to the
284 * first data pointer, if more than one exist).
286 * Used by CRYPT_AsnDecodeSequence, not for your use.
288 struct AsnDecodeSequenceItem
292 InternalDecodeFunc decodeFunc;
300 /* Decodes the items in a sequence, where the items are described in items,
301 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
302 * pvStructInfo. nextData is a pointer to the memory location at which the
303 * first decoded item with a dynamic pointer should point.
304 * Upon decoding, *cbDecoded is the total number of bytes decoded.
305 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
307 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
308 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
309 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
312 DWORD i, decoded = 0;
313 const BYTE *ptr = pbEncoded;
315 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
316 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
318 for (i = 0, ret = TRUE; ret && i < cItem; i++)
320 if (cbEncoded - (ptr - pbEncoded) != 0)
324 if ((ret = CRYPT_GetLengthIndefinite(ptr,
325 cbEncoded - (ptr - pbEncoded), &itemLen)))
327 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
329 if (ptr[0] == items[i].tag || !items[i].tag)
331 DWORD itemEncodedLen;
333 if (itemLen == CMSG_INDEFINITE_LENGTH)
334 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
336 itemEncodedLen = 1 + itemLenBytes + itemLen;
337 if (nextData && pvStructInfo && items[i].hasPointer)
339 TRACE("Setting next pointer to %p\n",
341 *(BYTE **)((BYTE *)pvStructInfo +
342 items[i].pointerOffset) = nextData;
344 if (items[i].decodeFunc)
349 TRACE("decoding item %d\n", i);
351 TRACE("sizing item %d\n", i);
352 ret = items[i].decodeFunc(ptr, itemEncodedLen,
353 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
354 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
355 : NULL, &items[i].size, &itemDecoded);
358 /* Account for alignment padding */
359 if (items[i].size % sizeof(DWORD_PTR))
360 items[i].size += sizeof(DWORD_PTR) -
361 items[i].size % sizeof(DWORD_PTR);
362 TRACE("item %d size: %d\n", i, items[i].size);
363 if (nextData && items[i].hasPointer &&
364 items[i].size > items[i].minSize)
365 nextData += items[i].size - items[i].minSize;
366 if (itemDecoded > itemEncodedLen)
368 WARN("decoded length %d exceeds encoded %d\n",
369 itemDecoded, itemEncodedLen);
370 SetLastError(CRYPT_E_ASN1_CORRUPT);
375 if (itemLen == CMSG_INDEFINITE_LENGTH)
377 if (itemDecoded > itemEncodedLen - 2 ||
378 *(ptr + itemDecoded) != 0 ||
379 *(ptr + itemDecoded + 1) != 0)
381 TRACE("expected 0 TLV\n");
382 SetLastError(CRYPT_E_ASN1_CORRUPT);
391 decoded += itemDecoded;
392 TRACE("item %d: decoded %d bytes\n", i,
397 else if (items[i].optional &&
398 GetLastError() == CRYPT_E_ASN1_BADTAG)
400 TRACE("skipping optional item %d\n", i);
401 items[i].size = items[i].minSize;
402 SetLastError(NOERROR);
406 TRACE("item %d failed: %08x\n", i,
409 else if (itemLen == CMSG_INDEFINITE_LENGTH)
411 ERR("can't use indefinite length encoding without a decoder\n");
412 SetLastError(CRYPT_E_ASN1_CORRUPT);
417 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
418 ptr += itemEncodedLen;
419 decoded += itemEncodedLen;
420 items[i].size = items[i].minSize;
423 else if (items[i].optional)
425 TRACE("skipping optional item %d\n", i);
426 items[i].size = items[i].minSize;
430 TRACE("item %d: tag %02x doesn't match expected %02x\n",
431 i, ptr[0], items[i].tag);
432 SetLastError(CRYPT_E_ASN1_BADTAG);
437 else if (items[i].optional)
439 TRACE("missing optional item %d, skipping\n", i);
440 items[i].size = items[i].minSize;
444 TRACE("not enough bytes for item %d, failing\n", i);
445 SetLastError(CRYPT_E_ASN1_CORRUPT);
450 *cbDecoded = decoded;
451 TRACE("returning %d\n", ret);
455 /* This decodes an arbitrary sequence into a contiguous block of memory
456 * (basically, a struct.) Each element being decoded is described by a struct
457 * AsnDecodeSequenceItem, see above.
458 * startingPointer is an optional pointer to the first place where dynamic
459 * data will be stored. If you know the starting offset, you may pass it
460 * here. Otherwise, pass NULL, and one will be inferred from the items.
462 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
463 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
464 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
465 DWORD *pcbDecoded, void *startingPointer)
469 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
470 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
473 if (pbEncoded[0] == ASN_SEQUENCE)
477 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
479 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
480 const BYTE *ptr = pbEncoded + 1 + lenBytes;
481 BOOL indefinite = FALSE;
483 cbEncoded -= 1 + lenBytes;
484 if (dataLen == CMSG_INDEFINITE_LENGTH)
489 else if (cbEncoded < dataLen)
491 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
493 SetLastError(CRYPT_E_ASN1_CORRUPT);
498 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
499 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
500 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
502 if (cbDecoded > cbEncoded - 2)
504 /* Not enough space for 0 TLV */
505 SetLastError(CRYPT_E_ASN1_CORRUPT);
508 else if (*(ptr + cbDecoded) != 0 ||
509 *(ptr + cbDecoded + 1) != 0)
511 TRACE("expected 0 TLV\n");
512 SetLastError(CRYPT_E_ASN1_CORRUPT);
519 if (ret && !indefinite && cbDecoded != dataLen)
521 TRACE("expected %d decoded, got %d, failing\n", dataLen,
523 SetLastError(CRYPT_E_ASN1_CORRUPT);
528 DWORD i, bytesNeeded = 0, structSize = 0;
530 for (i = 0; i < cItem; i++)
532 bytesNeeded += items[i].size;
533 structSize += items[i].minSize;
536 *pcbDecoded = 1 + lenBytes + cbDecoded;
538 *pcbStructInfo = bytesNeeded;
539 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
540 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
544 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
545 pvStructInfo = *(BYTE **)pvStructInfo;
547 nextData = (BYTE *)startingPointer;
549 nextData = (BYTE *)pvStructInfo + structSize;
550 memset(pvStructInfo, 0, structSize);
551 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
552 ptr, dataLen, dwFlags, pvStructInfo, nextData,
554 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
555 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
562 SetLastError(CRYPT_E_ASN1_BADTAG);
565 TRACE("returning %d (%08x)\n", ret, GetLastError());
570 * The expected tag of the entire encoded array (usually a variant
571 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
572 * regardless of the tag seen.
574 * used to decode each item in the array
576 * is the minimum size of each decoded item
578 * indicates whether each item has a dynamic pointer
580 * indicates the offset within itemSize at which the pointer exists
582 struct AsnArrayDescriptor
585 InternalDecodeFunc decodeFunc;
591 struct AsnArrayItemSize
597 /* Decodes an array of like types into a struct GenericArray.
598 * The layout and decoding of the array are described by a struct
599 * AsnArrayDescriptor.
601 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
602 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
603 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
604 DWORD *pcbDecoded, void *startingPointer)
608 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
609 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
612 if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
616 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
618 DWORD bytesNeeded, cItems = 0, decoded;
619 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
620 /* There can be arbitrarily many items, but there is often only one.
622 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
624 decoded = 1 + lenBytes;
625 bytesNeeded = sizeof(struct GenericArray);
629 BOOL doneDecoding = FALSE;
631 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
633 if (dataLen == CMSG_INDEFINITE_LENGTH)
640 SetLastError(CRYPT_E_ASN1_CORRUPT);
647 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
651 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
653 /* Each item decoded may not tolerate extraneous bytes,
654 * so get the length of the next element if known.
656 if ((ret = CRYPT_GetLengthIndefinite(ptr,
657 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
659 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
660 itemEncoded = cbEncoded - (ptr - pbEncoded);
662 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
666 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
667 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
672 if (itemSizes != &itemSize)
673 itemSizes = CryptMemRealloc(itemSizes,
674 cItems * sizeof(struct AsnArrayItemSize));
679 cItems * sizeof(struct AsnArrayItemSize));
681 memcpy(itemSizes, &itemSize,
686 decoded += itemDecoded;
687 itemSizes[cItems - 1].encodedLen = itemEncoded;
688 itemSizes[cItems - 1].size = size;
701 *pcbDecoded = decoded;
703 *pcbStructInfo = bytesNeeded;
704 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
705 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
710 struct GenericArray *array;
712 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
713 pvStructInfo = *(BYTE **)pvStructInfo;
714 array = (struct GenericArray *)pvStructInfo;
715 array->cItems = cItems;
717 array->rgItems = startingPointer;
719 array->rgItems = (BYTE *)array +
720 sizeof(struct GenericArray);
721 nextData = array->rgItems +
722 array->cItems * arrayDesc->itemSize;
723 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
724 i < cItems && ptr - pbEncoded - 1 - lenBytes <
729 if (arrayDesc->hasPointer)
730 *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
731 + arrayDesc->pointerOffset) = nextData;
732 ret = arrayDesc->decodeFunc(ptr,
733 itemSizes[i].encodedLen,
734 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
735 array->rgItems + i * arrayDesc->itemSize,
736 &itemSizes[i].size, &itemDecoded);
739 nextData += itemSizes[i].size - arrayDesc->itemSize;
743 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
744 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
747 if (itemSizes != &itemSize)
748 CryptMemFree(itemSizes);
753 SetLastError(CRYPT_E_ASN1_BADTAG);
759 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
760 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
761 * to CRYPT_E_ASN1_CORRUPT.
762 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
765 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
766 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
771 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
773 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
774 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
776 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
777 bytesNeeded += 1 + lenBytes + dataLen;
780 *pcbDecoded = 1 + lenBytes + dataLen;
782 *pcbStructInfo = bytesNeeded;
783 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
785 CRYPT_DER_BLOB *blob;
787 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
788 pvStructInfo = *(BYTE **)pvStructInfo;
789 blob = (CRYPT_DER_BLOB *)pvStructInfo;
790 blob->cbData = 1 + lenBytes + dataLen;
793 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
794 blob->pbData = (BYTE *)pbEncoded;
797 assert(blob->pbData);
798 memcpy(blob->pbData, pbEncoded, blob->cbData);
803 SetLastError(CRYPT_E_ASN1_CORRUPT);
811 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
812 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
813 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
818 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
819 pvStructInfo, *pcbStructInfo, pcbDecoded);
821 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
824 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
825 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
827 if (ret && pvStructInfo)
829 CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
836 for (i = 0; i < blob->cbData / 2; i++)
838 temp = blob->pbData[i];
839 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
840 blob->pbData[blob->cbData - i - 1] = temp;
844 TRACE("returning %d (%08x)\n", ret, GetLastError());
848 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
849 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
850 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
854 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
855 pDecodePara, pvStructInfo, *pcbStructInfo);
859 struct AsnDecodeSequenceItem items[] = {
860 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
861 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
862 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
863 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
864 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
865 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
866 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
867 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
868 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
869 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
872 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
873 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
874 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
875 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
876 pcbStructInfo, NULL, NULL);
880 SetLastError(STATUS_ACCESS_VIOLATION);
885 TRACE("Returning %d (%08x)\n", ret, GetLastError());
889 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
890 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
895 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
897 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
899 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
900 dwFlags, pvStructInfo, pcbStructInfo, NULL);
902 *pcbDecoded = 1 + lenBytes + dataLen;
907 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
908 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
912 struct AsnDecodeSequenceItem items[] = {
913 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
914 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
915 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
916 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
919 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
920 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
925 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
926 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
932 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
934 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
936 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
937 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
938 if (ret && pcbDecoded)
939 *pcbDecoded = 1 + lenBytes + dataLen;
944 static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
945 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
946 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
949 struct AsnDecodeSequenceItem items[] = {
950 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
951 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
952 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
953 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
954 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
955 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
956 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
957 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
958 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
959 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
961 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
962 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
964 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
965 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
967 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
968 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
969 FALSE, TRUE, offsetof(CERT_INFO,
970 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
971 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
972 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
973 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
974 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
975 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
976 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
977 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
978 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
979 offsetof(CERT_INFO, rgExtension), 0 },
982 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
983 pDecodePara, pvStructInfo, *pcbStructInfo);
985 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
986 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
988 if (ret && pvStructInfo)
992 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
993 info = *(CERT_INFO **)pvStructInfo;
995 info = (CERT_INFO *)pvStructInfo;
996 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
997 !info->Subject.cbData)
999 SetLastError(CRYPT_E_ASN1_CORRUPT);
1000 /* Don't need to deallocate, because it should have failed on the
1001 * first pass (and no memory was allocated.)
1007 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1011 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1012 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1013 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1017 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1018 pDecodePara, pvStructInfo, *pcbStructInfo);
1024 /* Unless told not to, first try to decode it as a signed cert. */
1025 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1027 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1029 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1030 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1031 (BYTE *)&signedCert, &size);
1035 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1036 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1037 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1038 pvStructInfo, pcbStructInfo);
1039 LocalFree(signedCert);
1042 /* Failing that, try it as an unsigned cert */
1046 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1047 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1048 pDecodePara, pvStructInfo, pcbStructInfo);
1053 SetLastError(STATUS_ACCESS_VIOLATION);
1057 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1061 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1062 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1065 struct AsnDecodeSequenceItem items[] = {
1066 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1067 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1068 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1069 { 0, offsetof(CRL_ENTRY, RevocationDate),
1070 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1071 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1072 CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1073 offsetof(CRL_ENTRY, rgExtension), 0 },
1075 PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1077 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1080 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1081 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1082 entry ? entry->SerialNumber.pbData : NULL);
1083 if (ret && entry && !entry->SerialNumber.cbData)
1085 WARN("empty CRL entry serial number\n");
1086 SetLastError(CRYPT_E_ASN1_CORRUPT);
1092 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1093 * been set prior to calling.
1095 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1096 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1099 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1100 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1101 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1102 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1104 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1105 pvStructInfo, *pcbStructInfo, pcbDecoded);
1107 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1108 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1109 entries ? entries->rgItems : NULL);
1110 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1114 static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1115 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1116 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1118 struct AsnDecodeSequenceItem items[] = {
1119 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1120 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1121 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1122 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1123 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1124 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1125 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1127 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1128 sizeof(FILETIME), FALSE, FALSE, 0 },
1129 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1130 sizeof(FILETIME), TRUE, FALSE, 0 },
1131 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1132 CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1133 offsetof(CRL_INFO, rgCRLEntry), 0 },
1134 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1135 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1136 offsetof(CRL_INFO, rgExtension), 0 },
1140 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1141 pDecodePara, pvStructInfo, *pcbStructInfo);
1143 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1144 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1147 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1151 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1152 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1153 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1157 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1158 pDecodePara, pvStructInfo, *pcbStructInfo);
1164 /* Unless told not to, first try to decode it as a signed crl. */
1165 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1167 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1169 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1170 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1171 (BYTE *)&signedCrl, &size);
1175 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1176 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1177 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1178 pvStructInfo, pcbStructInfo);
1179 LocalFree(signedCrl);
1182 /* Failing that, try it as an unsigned crl */
1186 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1187 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1188 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1193 SetLastError(STATUS_ACCESS_VIOLATION);
1197 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1201 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1202 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1207 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1208 pvStructInfo, *pcbStructInfo);
1210 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1212 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1213 DWORD bytesNeeded = sizeof(LPSTR);
1217 /* The largest possible string for the first two components
1218 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1223 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1224 pbEncoded[1 + lenBytes] / 40,
1225 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1227 bytesNeeded += strlen(firstTwo) + 1;
1228 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1229 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1231 /* large enough for ".4000000" */
1235 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1242 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1245 SetLastError(CRYPT_E_ASN1_CORRUPT);
1252 snprintf(str, sizeof(str), ".%d", val);
1253 bytesNeeded += strlen(str);
1258 *pcbDecoded = 1 + lenBytes + dataLen;
1260 *pcbStructInfo = bytesNeeded;
1261 else if (*pcbStructInfo < bytesNeeded)
1263 *pcbStructInfo = bytesNeeded;
1264 SetLastError(ERROR_MORE_DATA);
1272 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1275 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1276 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1278 pszObjId += strlen(pszObjId);
1279 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1280 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1284 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1293 sprintf(pszObjId, ".%d", val);
1294 pszObjId += strlen(pszObjId);
1298 *(LPSTR *)pvStructInfo = NULL;
1299 *pcbStructInfo = bytesNeeded;
1305 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1306 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1310 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1311 pvStructInfo, *pcbStructInfo);
1313 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1314 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1315 pvStructInfo, pcbStructInfo, pcbDecoded);
1318 SetLastError(CRYPT_E_ASN1_BADTAG);
1324 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1327 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1328 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1330 struct AsnDecodeSequenceItem items[] = {
1331 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1332 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1333 offsetof(CERT_EXTENSION, pszObjId), 0 },
1334 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1335 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1336 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1337 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1338 offsetof(CERT_EXTENSION, Value.pbData) },
1341 PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1343 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1347 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1348 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1349 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1350 pcbDecoded, ext ? ext->pszObjId : NULL);
1352 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1353 debugstr_a(ext->pszObjId));
1354 TRACE("returning %d (%08x)\n", ret, GetLastError());
1358 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1359 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1363 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1364 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1365 offsetof(CERT_EXTENSION, pszObjId) };
1366 PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1368 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1369 pvStructInfo, *pcbStructInfo, pcbDecoded);
1371 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1372 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1373 exts ? exts->rgExtension : NULL);
1377 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1378 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1379 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1385 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1386 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1387 if (ret && pvStructInfo)
1389 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1390 pcbStructInfo, *pcbStructInfo);
1393 CERT_EXTENSIONS *exts;
1395 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1396 pvStructInfo = *(BYTE **)pvStructInfo;
1397 exts = (CERT_EXTENSIONS *)pvStructInfo;
1398 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1399 sizeof(CERT_EXTENSIONS));
1400 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1401 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1402 pcbStructInfo, NULL);
1408 SetLastError(STATUS_ACCESS_VIOLATION);
1415 /* Warning: this assumes the address of value->Value.pbData is already set, in
1416 * order to avoid overwriting memory. (In some cases, it may change it, if it
1417 * doesn't copy anything to memory.) Be sure to set it correctly!
1419 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1420 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1425 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1427 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1429 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1430 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1432 switch (pbEncoded[0])
1434 case ASN_OCTETSTRING:
1435 valueType = CERT_RDN_OCTET_STRING;
1436 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1437 bytesNeeded += dataLen;
1439 case ASN_NUMERICSTRING:
1440 valueType = CERT_RDN_NUMERIC_STRING;
1441 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1442 bytesNeeded += dataLen;
1444 case ASN_PRINTABLESTRING:
1445 valueType = CERT_RDN_PRINTABLE_STRING;
1446 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1447 bytesNeeded += dataLen;
1450 valueType = CERT_RDN_IA5_STRING;
1451 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1452 bytesNeeded += dataLen;
1455 valueType = CERT_RDN_T61_STRING;
1456 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1457 bytesNeeded += dataLen;
1459 case ASN_VIDEOTEXSTRING:
1460 valueType = CERT_RDN_VIDEOTEX_STRING;
1461 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1462 bytesNeeded += dataLen;
1464 case ASN_GRAPHICSTRING:
1465 valueType = CERT_RDN_GRAPHIC_STRING;
1466 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1467 bytesNeeded += dataLen;
1469 case ASN_VISIBLESTRING:
1470 valueType = CERT_RDN_VISIBLE_STRING;
1471 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1472 bytesNeeded += dataLen;
1474 case ASN_GENERALSTRING:
1475 valueType = CERT_RDN_GENERAL_STRING;
1476 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1477 bytesNeeded += dataLen;
1479 case ASN_UNIVERSALSTRING:
1480 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1481 SetLastError(CRYPT_E_ASN1_BADTAG);
1484 valueType = CERT_RDN_BMP_STRING;
1485 bytesNeeded += dataLen;
1487 case ASN_UTF8STRING:
1488 valueType = CERT_RDN_UTF8_STRING;
1489 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1490 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1493 SetLastError(CRYPT_E_ASN1_BADTAG);
1498 *pcbDecoded = 1 + lenBytes + dataLen;
1500 *pcbStructInfo = bytesNeeded;
1501 else if (*pcbStructInfo < bytesNeeded)
1503 *pcbStructInfo = bytesNeeded;
1504 SetLastError(ERROR_MORE_DATA);
1509 *pcbStructInfo = bytesNeeded;
1510 value->dwValueType = valueType;
1515 assert(value->Value.pbData);
1516 switch (pbEncoded[0])
1518 case ASN_OCTETSTRING:
1519 case ASN_NUMERICSTRING:
1520 case ASN_PRINTABLESTRING:
1523 case ASN_VIDEOTEXSTRING:
1524 case ASN_GRAPHICSTRING:
1525 case ASN_VISIBLESTRING:
1526 case ASN_GENERALSTRING:
1527 value->Value.cbData = dataLen;
1530 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1531 memcpy(value->Value.pbData,
1532 pbEncoded + 1 + lenBytes, dataLen);
1534 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1540 LPWSTR str = (LPWSTR)value->Value.pbData;
1542 value->Value.cbData = dataLen;
1543 for (i = 0; i < dataLen / 2; i++)
1544 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1545 pbEncoded[1 + lenBytes + 2 * i + 1];
1548 case ASN_UTF8STRING:
1550 LPWSTR str = (LPWSTR)value->Value.pbData;
1552 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1553 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1554 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1561 value->Value.cbData = 0;
1562 value->Value.pbData = NULL;
1569 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1570 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1571 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1577 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1578 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1579 if (ret && pvStructInfo)
1581 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1582 pcbStructInfo, *pcbStructInfo);
1585 CERT_NAME_VALUE *value;
1587 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1588 pvStructInfo = *(BYTE **)pvStructInfo;
1589 value = (CERT_NAME_VALUE *)pvStructInfo;
1590 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1591 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1592 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1593 pcbStructInfo, NULL);
1599 SetLastError(STATUS_ACCESS_VIOLATION);
1606 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1607 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1612 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1614 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1616 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1617 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1619 switch (pbEncoded[0])
1621 case ASN_NUMERICSTRING:
1622 valueType = CERT_RDN_NUMERIC_STRING;
1623 bytesNeeded += dataLen * 2;
1625 case ASN_PRINTABLESTRING:
1626 valueType = CERT_RDN_PRINTABLE_STRING;
1627 bytesNeeded += dataLen * 2;
1630 valueType = CERT_RDN_IA5_STRING;
1631 bytesNeeded += dataLen * 2;
1634 valueType = CERT_RDN_T61_STRING;
1635 bytesNeeded += dataLen * 2;
1637 case ASN_VIDEOTEXSTRING:
1638 valueType = CERT_RDN_VIDEOTEX_STRING;
1639 bytesNeeded += dataLen * 2;
1641 case ASN_GRAPHICSTRING:
1642 valueType = CERT_RDN_GRAPHIC_STRING;
1643 bytesNeeded += dataLen * 2;
1645 case ASN_VISIBLESTRING:
1646 valueType = CERT_RDN_VISIBLE_STRING;
1647 bytesNeeded += dataLen * 2;
1649 case ASN_GENERALSTRING:
1650 valueType = CERT_RDN_GENERAL_STRING;
1651 bytesNeeded += dataLen * 2;
1653 case ASN_UNIVERSALSTRING:
1654 valueType = CERT_RDN_UNIVERSAL_STRING;
1655 bytesNeeded += dataLen / 2;
1658 valueType = CERT_RDN_BMP_STRING;
1659 bytesNeeded += dataLen;
1661 case ASN_UTF8STRING:
1662 valueType = CERT_RDN_UTF8_STRING;
1663 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1664 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1667 SetLastError(CRYPT_E_ASN1_BADTAG);
1672 *pcbDecoded = 1 + lenBytes + dataLen;
1674 *pcbStructInfo = bytesNeeded;
1675 else if (*pcbStructInfo < bytesNeeded)
1677 *pcbStructInfo = bytesNeeded;
1678 SetLastError(ERROR_MORE_DATA);
1683 *pcbStructInfo = bytesNeeded;
1684 value->dwValueType = valueType;
1688 LPWSTR str = (LPWSTR)value->Value.pbData;
1690 assert(value->Value.pbData);
1691 switch (pbEncoded[0])
1693 case ASN_NUMERICSTRING:
1694 case ASN_PRINTABLESTRING:
1697 case ASN_VIDEOTEXSTRING:
1698 case ASN_GRAPHICSTRING:
1699 case ASN_VISIBLESTRING:
1700 case ASN_GENERALSTRING:
1701 value->Value.cbData = dataLen * 2;
1702 for (i = 0; i < dataLen; i++)
1703 str[i] = pbEncoded[1 + lenBytes + i];
1705 case ASN_UNIVERSALSTRING:
1706 value->Value.cbData = dataLen / 2;
1707 for (i = 0; i < dataLen / 4; i++)
1708 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1709 | pbEncoded[1 + lenBytes + 2 * i + 3];
1712 value->Value.cbData = dataLen;
1713 for (i = 0; i < dataLen / 2; i++)
1714 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1715 pbEncoded[1 + lenBytes + 2 * i + 1];
1717 case ASN_UTF8STRING:
1718 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1719 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1720 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1726 value->Value.cbData = 0;
1727 value->Value.pbData = NULL;
1734 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1735 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1736 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1742 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1743 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1744 if (ret && pvStructInfo)
1746 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1747 pcbStructInfo, *pcbStructInfo);
1750 CERT_NAME_VALUE *value;
1752 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1753 pvStructInfo = *(BYTE **)pvStructInfo;
1754 value = (CERT_NAME_VALUE *)pvStructInfo;
1755 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1756 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1757 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1758 pcbStructInfo, NULL);
1764 SetLastError(STATUS_ACCESS_VIOLATION);
1771 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1772 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1775 struct AsnDecodeSequenceItem items[] = {
1776 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1777 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1778 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1779 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1780 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1781 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1783 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1785 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1786 pvStructInfo, *pcbStructInfo);
1789 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1790 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1791 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1792 attr ? attr->pszObjId : NULL);
1795 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1796 debugstr_a(attr->pszObjId));
1797 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1799 TRACE("returning %d (%08x)\n", ret, GetLastError());
1803 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1804 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1807 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1808 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1809 offsetof(CERT_RDN_ATTR, pszObjId) };
1810 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1812 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1813 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1814 rdn ? rdn->rgRDNAttr : NULL);
1818 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1819 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1820 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1826 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1827 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1828 offsetof(CERT_RDN, rgRDNAttr) };
1830 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1831 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1835 SetLastError(STATUS_ACCESS_VIOLATION);
1842 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1843 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1847 struct AsnDecodeSequenceItem items[] = {
1848 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1849 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1850 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1851 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1852 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1853 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1855 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1857 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1858 pvStructInfo, *pcbStructInfo);
1861 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1862 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1863 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1864 attr ? attr->pszObjId : NULL);
1867 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1868 debugstr_a(attr->pszObjId));
1869 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1871 TRACE("returning %d (%08x)\n", ret, GetLastError());
1875 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1876 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1879 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1880 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1881 offsetof(CERT_RDN_ATTR, pszObjId) };
1882 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1884 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1885 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1886 rdn ? rdn->rgRDNAttr : NULL);
1890 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1891 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1892 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1898 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1899 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1900 offsetof(CERT_RDN, rgRDNAttr) };
1902 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1903 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1907 SetLastError(STATUS_ACCESS_VIOLATION);
1914 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1917 BOOL ret = TRUE, done = FALSE;
1918 DWORD indefiniteNestingLevels = 0, decoded = 0;
1920 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1927 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1930 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1932 if (dataLen == CMSG_INDEFINITE_LENGTH)
1934 indefiniteNestingLevels++;
1935 pbEncoded += 1 + lenBytes;
1936 cbEncoded -= 1 + lenBytes;
1937 decoded += 1 + lenBytes;
1938 TRACE("indefiniteNestingLevels = %d\n",
1939 indefiniteNestingLevels);
1943 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1944 indefiniteNestingLevels)
1946 indefiniteNestingLevels--;
1947 TRACE("indefiniteNestingLevels = %d\n",
1948 indefiniteNestingLevels);
1950 pbEncoded += 1 + lenBytes + dataLen;
1951 cbEncoded -= 1 + lenBytes + dataLen;
1952 decoded += 1 + lenBytes + dataLen;
1953 if (!indefiniteNestingLevels)
1957 } while (ret && !done);
1958 /* If we haven't found all 0 TLVs, we haven't found the end */
1959 if (ret && indefiniteNestingLevels)
1961 SetLastError(CRYPT_E_ASN1_EOD);
1965 *pcbDecoded = decoded;
1966 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1970 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1971 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1975 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
1977 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1978 pvStructInfo, *pcbStructInfo);
1980 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
1982 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1983 bytesNeeded += encodedLen;
1985 *pcbStructInfo = bytesNeeded;
1986 else if (*pcbStructInfo < bytesNeeded)
1988 SetLastError(ERROR_MORE_DATA);
1989 *pcbStructInfo = bytesNeeded;
1994 PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
1996 *pcbStructInfo = bytesNeeded;
1997 blob->cbData = encodedLen;
1998 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
1999 blob->pbData = (LPBYTE)pbEncoded;
2002 assert(blob->pbData);
2003 memcpy(blob->pbData, pbEncoded, blob->cbData);
2007 *pcbDecoded = encodedLen;
2012 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
2013 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2016 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2017 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2018 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
2020 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2021 pvStructInfo, *pcbStructInfo, pcbDecoded);
2023 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2024 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2025 array ? array->rgItems : NULL);
2029 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2030 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2034 struct AsnDecodeSequenceItem items[] = {
2035 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2036 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2037 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2038 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2039 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2040 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2042 PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2044 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2045 pvStructInfo, *pcbStructInfo);
2047 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2048 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2049 pcbDecoded, attr ? attr->pszObjId : NULL);
2050 TRACE("returning %d\n", ret);
2054 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2055 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2056 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2060 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2061 pDecodePara, pvStructInfo, *pcbStructInfo);
2067 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2068 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2072 *pcbStructInfo = bytesNeeded;
2073 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2074 pvStructInfo, pcbStructInfo, bytesNeeded)))
2076 PCRYPT_ATTRIBUTE attr;
2078 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2079 pvStructInfo = *(BYTE **)pvStructInfo;
2080 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2081 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2082 sizeof(CRYPT_ATTRIBUTE));
2083 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2084 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2091 SetLastError(STATUS_ACCESS_VIOLATION);
2094 TRACE("returning %d\n", ret);
2098 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2099 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2102 struct AsnArrayDescriptor arrayDesc = { 0,
2103 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2104 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2105 PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2108 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2109 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2114 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2115 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2116 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2120 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2121 pDecodePara, pvStructInfo, *pcbStructInfo);
2128 SetLastError(CRYPT_E_ASN1_EOD);
2129 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2130 SetLastError(CRYPT_E_ASN1_CORRUPT);
2131 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2132 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2136 *pcbStructInfo = bytesNeeded;
2137 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2138 pvStructInfo, pcbStructInfo, bytesNeeded)))
2140 PCRYPT_ATTRIBUTES attrs;
2142 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2143 pvStructInfo = *(BYTE **)pvStructInfo;
2144 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2145 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2146 sizeof(CRYPT_ATTRIBUTES));
2147 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2148 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2149 &bytesNeeded, NULL);
2155 SetLastError(STATUS_ACCESS_VIOLATION);
2158 TRACE("returning %d\n", ret);
2162 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2163 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2165 CRYPT_ALGORITHM_IDENTIFIER *algo =
2166 (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2168 struct AsnDecodeSequenceItem items[] = {
2169 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2170 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2171 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2172 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2173 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2174 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2177 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2178 pvStructInfo, *pcbStructInfo, pcbDecoded);
2180 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2181 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2182 pcbDecoded, algo ? algo->pszObjId : NULL);
2183 if (ret && pvStructInfo)
2185 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2186 debugstr_a(algo->pszObjId));
2191 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2192 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2196 struct AsnDecodeSequenceItem items[] = {
2197 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2198 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2199 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2200 Algorithm.pszObjId) },
2201 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2202 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2203 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2205 PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2207 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2208 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2209 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2213 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2214 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2215 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2223 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2224 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2227 *pcbStructInfo = bytesNeeded;
2228 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2229 pvStructInfo, pcbStructInfo, bytesNeeded)))
2231 PCERT_PUBLIC_KEY_INFO info;
2233 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2234 pvStructInfo = *(BYTE **)pvStructInfo;
2235 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2236 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2237 sizeof(CERT_PUBLIC_KEY_INFO);
2238 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2239 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2240 &bytesNeeded, NULL);
2246 SetLastError(STATUS_ACCESS_VIOLATION);
2253 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2254 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2260 SetLastError(CRYPT_E_ASN1_CORRUPT);
2263 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2265 SetLastError(CRYPT_E_ASN1_CORRUPT);
2268 if (pbEncoded[1] > 1)
2270 SetLastError(CRYPT_E_ASN1_CORRUPT);
2277 *pcbStructInfo = sizeof(BOOL);
2280 else if (*pcbStructInfo < sizeof(BOOL))
2282 *pcbStructInfo = sizeof(BOOL);
2283 SetLastError(ERROR_MORE_DATA);
2288 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2291 TRACE("returning %d (%08x)\n", ret, GetLastError());
2295 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2296 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2298 PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2299 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2302 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2303 pvStructInfo, *pcbStructInfo);
2307 SetLastError(CRYPT_E_ASN1_CORRUPT);
2310 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2311 if (1 + lenBytes > cbEncoded)
2313 SetLastError(CRYPT_E_ASN1_CORRUPT);
2316 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2318 switch (pbEncoded[0] & ASN_TYPE_MASK)
2320 case 1: /* rfc822Name */
2321 case 2: /* dNSName */
2322 case 6: /* uniformResourceIdentifier */
2323 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2325 case 4: /* directoryName */
2326 case 7: /* iPAddress */
2327 bytesNeeded += dataLen;
2329 case 8: /* registeredID */
2330 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2334 /* FIXME: ugly, shouldn't need to know internals of OID decode
2335 * function to use it.
2337 bytesNeeded += dataLen - sizeof(LPSTR);
2340 case 0: /* otherName */
2341 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2342 SetLastError(CRYPT_E_ASN1_BADTAG);
2345 case 3: /* x400Address, unimplemented */
2346 case 5: /* ediPartyName, unimplemented */
2347 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2348 SetLastError(CRYPT_E_ASN1_BADTAG);
2352 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2353 SetLastError(CRYPT_E_ASN1_CORRUPT);
2359 *pcbDecoded = 1 + lenBytes + dataLen;
2361 *pcbStructInfo = bytesNeeded;
2362 else if (*pcbStructInfo < bytesNeeded)
2364 *pcbStructInfo = bytesNeeded;
2365 SetLastError(ERROR_MORE_DATA);
2370 *pcbStructInfo = bytesNeeded;
2371 /* MS used values one greater than the asn1 ones.. sigh */
2372 entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
2373 switch (pbEncoded[0] & ASN_TYPE_MASK)
2375 case 1: /* rfc822Name */
2376 case 2: /* dNSName */
2377 case 6: /* uniformResourceIdentifier */
2381 for (i = 0; i < dataLen; i++)
2382 entry->u.pwszURL[i] =
2383 (WCHAR)pbEncoded[1 + lenBytes + i];
2384 entry->u.pwszURL[i] = 0;
2385 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2386 debugstr_w(entry->u.pwszURL));
2389 case 4: /* directoryName */
2390 entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
2391 /* The data are memory-equivalent with the IPAddress case,
2394 case 7: /* iPAddress */
2395 /* The next data pointer is in the pwszURL spot, that is,
2396 * the first 4 bytes. Need to move it to the next spot.
2398 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2399 entry->u.IPAddress.cbData = dataLen;
2400 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2403 case 8: /* registeredID */
2404 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2405 &entry->u.pszRegisteredID, &dataLen, NULL);
2414 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2415 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2419 struct AsnArrayDescriptor arrayDesc = { 0,
2420 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2421 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2422 PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2424 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2425 pvStructInfo, *pcbStructInfo, pcbDecoded);
2428 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2429 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2430 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2431 info ? info->rgAltEntry : NULL);
2435 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2436 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2437 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2442 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2443 pvStructInfo, *pcbStructInfo, pcbDecoded);
2445 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2448 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2449 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2451 if (ret && pvStructInfo)
2453 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2460 for (i = 0; i < blob->cbData / 2; i++)
2462 temp = blob->pbData[i];
2463 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2464 blob->pbData[blob->cbData - i - 1] = temp;
2468 TRACE("returning %d (%08x)\n", ret, GetLastError());
2472 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2473 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2474 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2480 struct AsnDecodeSequenceItem items[] = {
2481 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2482 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2483 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2484 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2485 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2486 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2487 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2488 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2489 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2490 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2491 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2494 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2495 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2496 pcbStructInfo, NULL, NULL);
2500 SetLastError(STATUS_ACCESS_VIOLATION);
2507 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2508 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2509 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2515 struct AsnDecodeSequenceItem items[] = {
2516 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2517 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2518 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2519 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2520 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2521 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2522 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2523 AuthorityCertIssuer.rgAltEntry), 0 },
2524 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2525 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2526 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2527 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2528 AuthorityCertSerialNumber.pbData), 0 },
2531 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2532 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2533 pcbStructInfo, NULL, NULL);
2537 SetLastError(STATUS_ACCESS_VIOLATION);
2544 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2545 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2550 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2551 pvStructInfo, *pcbStructInfo, pcbDecoded);
2553 /* The caller has already checked the tag, no need to check it again.
2554 * Check the outer length is valid:
2556 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2558 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2561 pbEncoded += 1 + lenBytes;
2562 cbEncoded -= 1 + lenBytes;
2563 if (dataLen == CMSG_INDEFINITE_LENGTH)
2564 cbEncoded -= 2; /* space for 0 TLV */
2565 /* Check the inner length is valid: */
2566 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2570 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2571 pvStructInfo, pcbStructInfo, &decodedLen);
2572 if (dataLen == CMSG_INDEFINITE_LENGTH)
2574 if (*(pbEncoded + decodedLen) != 0 ||
2575 *(pbEncoded + decodedLen + 1) != 0)
2577 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2578 *(pbEncoded + decodedLen),
2579 *(pbEncoded + decodedLen + 1));
2580 SetLastError(CRYPT_E_ASN1_CORRUPT);
2586 if (ret && pcbDecoded)
2588 *pcbDecoded = 1 + lenBytes + decodedLen;
2589 TRACE("decoded %d bytes\n", *pcbDecoded);
2596 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2597 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2600 CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2601 struct AsnDecodeSequenceItem items[] = {
2602 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2603 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2604 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2605 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2606 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2607 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2608 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2612 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2613 pvStructInfo, *pcbStructInfo, pcbDecoded);
2615 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2616 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2617 pcbDecoded, info ? info->pszObjId : NULL);
2621 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2622 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2623 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2627 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2628 pDecodePara, pvStructInfo, *pcbStructInfo);
2632 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2633 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2634 if (ret && pvStructInfo)
2636 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2637 pcbStructInfo, *pcbStructInfo);
2640 CRYPT_CONTENT_INFO *info;
2642 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2643 pvStructInfo = *(BYTE **)pvStructInfo;
2644 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2645 info->pszObjId = (LPSTR)((BYTE *)info +
2646 sizeof(CRYPT_CONTENT_INFO));
2647 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2648 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2649 pcbStructInfo, NULL);
2655 SetLastError(STATUS_ACCESS_VIOLATION);
2661 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2662 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2663 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2666 struct AsnDecodeSequenceItem items[] = {
2667 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2668 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2669 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2670 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2671 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2673 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2674 CRYPT_AsnDecodePKCSContentInfoInternal,
2675 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2676 ContentInfo.pszObjId), 0 },
2677 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2678 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2679 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2682 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2683 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2688 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2689 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2690 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2694 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2695 pDecodePara, pvStructInfo, *pcbStructInfo);
2701 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2702 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2705 *pcbStructInfo = bytesNeeded;
2706 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2707 pvStructInfo, pcbStructInfo, bytesNeeded)))
2709 CERT_ALT_NAME_INFO *name;
2711 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2712 pvStructInfo = *(BYTE **)pvStructInfo;
2713 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2714 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2715 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2716 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2717 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2718 &bytesNeeded, NULL);
2724 SetLastError(STATUS_ACCESS_VIOLATION);
2731 struct PATH_LEN_CONSTRAINT
2733 BOOL fPathLenConstraint;
2734 DWORD dwPathLenConstraint;
2737 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
2738 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2742 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
2744 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2745 pvStructInfo, *pcbStructInfo, pcbDecoded);
2749 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
2751 *pcbStructInfo = bytesNeeded;
2753 else if (*pcbStructInfo < bytesNeeded)
2755 SetLastError(ERROR_MORE_DATA);
2756 *pcbStructInfo = bytesNeeded;
2761 struct PATH_LEN_CONSTRAINT *constraint =
2762 (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
2764 size = sizeof(constraint->dwPathLenConstraint);
2765 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
2766 &constraint->dwPathLenConstraint, &size, pcbDecoded);
2768 constraint->fPathLenConstraint = TRUE;
2769 TRACE("got an int, dwPathLenConstraint is %d\n",
2770 constraint->dwPathLenConstraint);
2772 TRACE("returning %d (%08x)\n", ret, GetLastError());
2776 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
2777 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2781 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2782 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
2783 offsetof(CERT_NAME_BLOB, pbData) };
2784 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2786 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2787 pvStructInfo, *pcbStructInfo, pcbDecoded);
2789 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2790 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2791 entries ? entries->rgItems : NULL);
2792 TRACE("Returning %d (%08x)\n", ret, GetLastError());
2796 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
2797 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2798 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2804 struct AsnDecodeSequenceItem items[] = {
2805 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
2806 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2807 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
2808 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2809 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2810 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2811 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2812 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
2813 sizeof(struct GenericArray), TRUE, TRUE,
2814 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
2817 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2818 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2819 pcbStructInfo, NULL, NULL);
2823 SetLastError(STATUS_ACCESS_VIOLATION);
2830 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
2831 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2832 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2838 struct AsnDecodeSequenceItem items[] = {
2839 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
2840 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
2841 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
2842 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2843 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2846 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2847 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2848 pcbStructInfo, NULL, NULL);
2852 SetLastError(STATUS_ACCESS_VIOLATION);
2859 #define RSA1_MAGIC 0x31415352
2861 struct DECODED_RSA_PUB_KEY
2864 CRYPT_INTEGER_BLOB modulus;
2867 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
2868 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2869 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2875 struct AsnDecodeSequenceItem items[] = {
2876 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
2877 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2878 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
2880 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
2881 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2883 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
2886 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2887 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
2891 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2892 decodedKey->modulus.cbData;
2896 *pcbStructInfo = bytesNeeded;
2899 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2900 pvStructInfo, pcbStructInfo, bytesNeeded)))
2903 RSAPUBKEY *rsaPubKey;
2905 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2906 pvStructInfo = *(BYTE **)pvStructInfo;
2907 hdr = (BLOBHEADER *)pvStructInfo;
2908 hdr->bType = PUBLICKEYBLOB;
2909 hdr->bVersion = CUR_BLOB_VERSION;
2911 hdr->aiKeyAlg = CALG_RSA_KEYX;
2912 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
2913 sizeof(BLOBHEADER));
2914 rsaPubKey->magic = RSA1_MAGIC;
2915 rsaPubKey->pubexp = decodedKey->pubexp;
2916 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
2917 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
2918 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
2919 decodedKey->modulus.cbData);
2921 LocalFree(decodedKey);
2926 SetLastError(STATUS_ACCESS_VIOLATION);
2933 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
2934 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2938 DWORD bytesNeeded, dataLen;
2940 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2941 pvStructInfo, *pcbStructInfo, pcbDecoded);
2943 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2945 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2947 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2948 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
2950 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
2952 *pcbDecoded = 1 + lenBytes + dataLen;
2954 *pcbStructInfo = bytesNeeded;
2955 else if (*pcbStructInfo < bytesNeeded)
2957 SetLastError(ERROR_MORE_DATA);
2958 *pcbStructInfo = bytesNeeded;
2963 CRYPT_DATA_BLOB *blob;
2965 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2966 blob->cbData = dataLen;
2967 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2968 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
2971 assert(blob->pbData);
2973 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
2981 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
2982 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2983 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2987 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2988 pDecodePara, pvStructInfo, *pcbStructInfo);
2996 SetLastError(CRYPT_E_ASN1_CORRUPT);
2999 else if (pbEncoded[0] != ASN_OCTETSTRING)
3001 SetLastError(CRYPT_E_ASN1_BADTAG);
3004 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3005 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3008 *pcbStructInfo = bytesNeeded;
3009 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3010 pvStructInfo, pcbStructInfo, bytesNeeded)))
3012 CRYPT_DATA_BLOB *blob;
3014 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3015 pvStructInfo = *(BYTE **)pvStructInfo;
3016 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3017 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3018 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3019 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3020 &bytesNeeded, NULL);
3026 SetLastError(STATUS_ACCESS_VIOLATION);
3033 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3034 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3038 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3039 pvStructInfo, *pcbStructInfo, pcbDecoded);
3041 if (pbEncoded[0] == ASN_BITSTRING)
3043 DWORD bytesNeeded, dataLen;
3044 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3046 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3048 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3049 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3051 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3053 *pcbDecoded = 1 + lenBytes + dataLen;
3055 *pcbStructInfo = bytesNeeded;
3056 else if (*pcbStructInfo < bytesNeeded)
3058 *pcbStructInfo = bytesNeeded;
3059 SetLastError(ERROR_MORE_DATA);
3064 CRYPT_BIT_BLOB *blob;
3066 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3067 blob->cbData = dataLen - 1;
3068 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3069 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3071 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3075 assert(blob->pbData);
3078 BYTE mask = 0xff << blob->cUnusedBits;
3080 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3082 blob->pbData[blob->cbData - 1] &= mask;
3090 SetLastError(CRYPT_E_ASN1_BADTAG);
3093 TRACE("returning %d (%08x)\n", ret, GetLastError());
3097 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3098 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3099 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3103 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3104 pDecodePara, pvStructInfo, pcbStructInfo);
3110 if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3111 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3114 *pcbStructInfo = bytesNeeded;
3115 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3116 pvStructInfo, pcbStructInfo, bytesNeeded)))
3118 CRYPT_BIT_BLOB *blob;
3120 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3121 pvStructInfo = *(BYTE **)pvStructInfo;
3122 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3123 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3124 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3125 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3126 &bytesNeeded, NULL);
3132 SetLastError(STATUS_ACCESS_VIOLATION);
3136 TRACE("returning %d (%08x)\n", ret, GetLastError());
3140 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3141 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3142 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3145 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3146 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3147 DWORD size = sizeof(buf);
3149 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3150 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, &buf,
3155 *pcbStructInfo = sizeof(int);
3156 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3160 if (blob->pbData[blob->cbData - 1] & 0x80)
3162 /* initialize to a negative value to sign-extend */
3167 for (i = 0; i < blob->cbData; i++)
3170 val |= blob->pbData[blob->cbData - i - 1];
3172 memcpy(pvStructInfo, &val, sizeof(int));
3175 else if (GetLastError() == ERROR_MORE_DATA)
3176 SetLastError(CRYPT_E_ASN1_LARGE);
3180 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3181 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3182 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3192 SetLastError(CRYPT_E_ASN1_CORRUPT);
3195 else if (pbEncoded[0] != ASN_INTEGER)
3197 SetLastError(CRYPT_E_ASN1_BADTAG);
3201 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3202 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3206 *pcbStructInfo = bytesNeeded;
3207 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3208 pvStructInfo, pcbStructInfo, bytesNeeded)))
3210 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3211 pvStructInfo = *(BYTE **)pvStructInfo;
3212 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3213 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3214 &bytesNeeded, NULL);
3220 SetLastError(STATUS_ACCESS_VIOLATION);
3227 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3228 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3232 DWORD bytesNeeded, dataLen;
3234 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3236 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3238 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3240 *pcbDecoded = 1 + lenBytes + dataLen;
3242 *pcbStructInfo = bytesNeeded;
3243 else if (*pcbStructInfo < bytesNeeded)
3245 *pcbStructInfo = bytesNeeded;
3246 SetLastError(ERROR_MORE_DATA);
3251 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3253 blob->cbData = dataLen;
3254 assert(blob->pbData);
3259 for (i = 0; i < blob->cbData; i++)
3261 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3270 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
3271 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3272 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3280 if (pbEncoded[0] != ASN_INTEGER)
3282 SetLastError(CRYPT_E_ASN1_BADTAG);
3286 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3287 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3291 *pcbStructInfo = bytesNeeded;
3292 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3293 pvStructInfo, pcbStructInfo, bytesNeeded)))
3295 CRYPT_INTEGER_BLOB *blob;
3297 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3298 pvStructInfo = *(BYTE **)pvStructInfo;
3299 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3300 blob->pbData = (BYTE *)pvStructInfo +
3301 sizeof(CRYPT_INTEGER_BLOB);
3302 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3303 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3304 &bytesNeeded, NULL);
3310 SetLastError(STATUS_ACCESS_VIOLATION);
3317 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
3318 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3323 if (pbEncoded[0] == ASN_INTEGER)
3325 DWORD bytesNeeded, dataLen;
3327 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3329 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3332 *pcbDecoded = 1 + lenBytes + dataLen;
3333 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3335 *pcbStructInfo = bytesNeeded;
3336 else if (*pcbStructInfo < bytesNeeded)
3338 *pcbStructInfo = bytesNeeded;
3339 SetLastError(ERROR_MORE_DATA);
3344 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3346 blob->cbData = dataLen;
3347 assert(blob->pbData);
3348 /* remove leading zero byte if it exists */
3349 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
3358 for (i = 0; i < blob->cbData; i++)
3360 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3369 SetLastError(CRYPT_E_ASN1_BADTAG);
3375 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
3376 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3377 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3385 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
3386 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3389 *pcbStructInfo = bytesNeeded;
3390 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3391 pvStructInfo, pcbStructInfo, bytesNeeded)))
3393 CRYPT_INTEGER_BLOB *blob;
3395 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3396 pvStructInfo = *(BYTE **)pvStructInfo;
3397 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3398 blob->pbData = (BYTE *)pvStructInfo +
3399 sizeof(CRYPT_INTEGER_BLOB);
3400 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
3401 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3402 &bytesNeeded, NULL);
3408 SetLastError(STATUS_ACCESS_VIOLATION);
3415 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
3416 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3417 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3423 *pcbStructInfo = sizeof(int);
3428 if (pbEncoded[0] == ASN_ENUMERATED)
3430 unsigned int val = 0, i;
3434 SetLastError(CRYPT_E_ASN1_EOD);
3437 else if (pbEncoded[1] == 0)
3439 SetLastError(CRYPT_E_ASN1_CORRUPT);
3444 /* A little strange looking, but we have to accept a sign byte:
3445 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3446 * assuming a small length is okay here, it has to be in short
3449 if (pbEncoded[1] > sizeof(unsigned int) + 1)
3451 SetLastError(CRYPT_E_ASN1_LARGE);
3454 for (i = 0; i < pbEncoded[1]; i++)
3457 val |= pbEncoded[2 + i];
3459 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3460 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
3462 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3463 pvStructInfo = *(BYTE **)pvStructInfo;
3464 memcpy(pvStructInfo, &val, sizeof(unsigned int));
3470 SetLastError(CRYPT_E_ASN1_BADTAG);
3476 SetLastError(STATUS_ACCESS_VIOLATION);
3483 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3486 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3491 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3493 if (!isdigit(*(pbEncoded))) \
3495 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3501 (word) += *(pbEncoded)++ - '0'; \
3506 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
3507 SYSTEMTIME *sysTime)
3511 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
3513 WORD hours, minutes = 0;
3514 BYTE sign = *pbEncoded++;
3517 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
3518 if (ret && hours >= 24)
3520 SetLastError(CRYPT_E_ASN1_CORRUPT);
3525 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
3526 if (ret && minutes >= 60)
3528 SetLastError(CRYPT_E_ASN1_CORRUPT);
3536 sysTime->wHour += hours;
3537 sysTime->wMinute += minutes;
3541 if (hours > sysTime->wHour)
3544 sysTime->wHour = 24 - (hours - sysTime->wHour);
3547 sysTime->wHour -= hours;
3548 if (minutes > sysTime->wMinute)
3551 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
3554 sysTime->wMinute -= minutes;
3561 #define MIN_ENCODED_TIME_LENGTH 10
3563 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
3564 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3569 if (pbEncoded[0] == ASN_UTCTIME)
3572 SetLastError(CRYPT_E_ASN1_EOD);
3573 else if (pbEncoded[1] > 0x7f)
3575 /* long-form date strings really can't be valid */
3576 SetLastError(CRYPT_E_ASN1_CORRUPT);
3580 SYSTEMTIME sysTime = { 0 };
3581 BYTE len = pbEncoded[1];
3583 if (len < MIN_ENCODED_TIME_LENGTH)
3584 SetLastError(CRYPT_E_ASN1_CORRUPT);
3589 *pcbDecoded = 2 + len;
3591 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
3592 if (sysTime.wYear >= 50)
3593 sysTime.wYear += 1900;
3595 sysTime.wYear += 2000;
3596 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3597 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3598 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3599 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
3602 if (len >= 2 && isdigit(*pbEncoded) &&
3603 isdigit(*(pbEncoded + 1)))
3604 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3606 else if (isdigit(*pbEncoded))
3607 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
3610 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3616 *pcbStructInfo = sizeof(FILETIME);
3617 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3619 ret = SystemTimeToFileTime(&sysTime,
3620 (FILETIME *)pvStructInfo);
3626 SetLastError(CRYPT_E_ASN1_BADTAG);
3630 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
3631 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3632 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3640 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3641 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3645 *pcbStructInfo = bytesNeeded;
3646 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
3647 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
3649 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3650 pvStructInfo = *(BYTE **)pvStructInfo;
3651 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3652 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3653 &bytesNeeded, NULL);
3659 SetLastError(STATUS_ACCESS_VIOLATION);
3665 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
3666 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3671 if (pbEncoded[0] == ASN_GENERALTIME)
3674 SetLastError(CRYPT_E_ASN1_EOD);
3675 else if (pbEncoded[1] > 0x7f)
3677 /* long-form date strings really can't be valid */
3678 SetLastError(CRYPT_E_ASN1_CORRUPT);
3682 BYTE len = pbEncoded[1];
3684 if (len < MIN_ENCODED_TIME_LENGTH)
3685 SetLastError(CRYPT_E_ASN1_CORRUPT);
3688 SYSTEMTIME sysTime = { 0 };
3692 *pcbDecoded = 2 + len;
3694 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
3695 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3696 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3697 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3700 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3703 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3705 if (ret && len > 0 && (*pbEncoded == '.' ||
3712 /* workaround macro weirdness */
3713 digits = min(len, 3);
3714 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
3715 sysTime.wMilliseconds);
3718 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3724 *pcbStructInfo = sizeof(FILETIME);
3725 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3727 ret = SystemTimeToFileTime(&sysTime,
3728 (FILETIME *)pvStructInfo);
3734 SetLastError(CRYPT_E_ASN1_BADTAG);
3738 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
3739 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3743 InternalDecodeFunc decode = NULL;
3745 if (pbEncoded[0] == ASN_UTCTIME)
3746 decode = CRYPT_AsnDecodeUtcTimeInternal;
3747 else if (pbEncoded[0] == ASN_GENERALTIME)
3748 decode = CRYPT_AsnDecodeGeneralizedTime;
3750 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
3751 pcbStructInfo, pcbDecoded);
3754 SetLastError(CRYPT_E_ASN1_BADTAG);
3760 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
3761 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3762 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3770 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3771 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3775 *pcbStructInfo = bytesNeeded;
3776 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3777 pvStructInfo, pcbStructInfo, bytesNeeded)))
3779 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3780 pvStructInfo = *(BYTE **)pvStructInfo;
3781 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3782 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3783 &bytesNeeded, NULL);
3789 SetLastError(STATUS_ACCESS_VIOLATION);
3796 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
3797 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3798 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3804 if (pbEncoded[0] == ASN_SEQUENCEOF)
3806 DWORD bytesNeeded, dataLen, remainingLen, cValue;
3808 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3813 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3814 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
3816 ptr = pbEncoded + 1 + lenBytes;
3817 remainingLen = dataLen;
3818 while (ret && remainingLen)
3822 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3825 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3827 remainingLen -= 1 + nextLenBytes + nextLen;
3828 ptr += 1 + nextLenBytes + nextLen;
3829 bytesNeeded += sizeof(CRYPT_DER_BLOB);
3830 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
3831 bytesNeeded += 1 + nextLenBytes + nextLen;
3837 CRYPT_SEQUENCE_OF_ANY *seq;
3841 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3842 pvStructInfo, pcbStructInfo, bytesNeeded)))
3844 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3845 pvStructInfo = *(BYTE **)pvStructInfo;
3846 seq = (CRYPT_SEQUENCE_OF_ANY *)pvStructInfo;
3847 seq->cValue = cValue;
3848 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
3850 nextPtr = (BYTE *)seq->rgValue +
3851 cValue * sizeof(CRYPT_DER_BLOB);
3852 ptr = pbEncoded + 1 + lenBytes;
3853 remainingLen = dataLen;
3855 while (ret && remainingLen)
3859 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3862 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3864 seq->rgValue[i].cbData = 1 + nextLenBytes +
3866 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3867 seq->rgValue[i].pbData = (BYTE *)ptr;
3870 seq->rgValue[i].pbData = nextPtr;
3871 memcpy(nextPtr, ptr, 1 + nextLenBytes +
3873 nextPtr += 1 + nextLenBytes + nextLen;
3875 remainingLen -= 1 + nextLenBytes + nextLen;
3876 ptr += 1 + nextLenBytes + nextLen;
3886 SetLastError(CRYPT_E_ASN1_BADTAG);
3892 SetLastError(STATUS_ACCESS_VIOLATION);
3899 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
3900 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3905 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
3907 DWORD bytesNeeded, dataLen;
3909 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3911 struct AsnArrayDescriptor arrayDesc = {
3912 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
3913 sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3914 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3915 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3921 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3922 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3923 0, NULL, NULL, &nameLen, NULL, NULL);
3924 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen;
3927 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
3929 *pcbDecoded = 1 + lenBytes + dataLen;
3931 *pcbStructInfo = bytesNeeded;
3932 else if (*pcbStructInfo < bytesNeeded)
3934 *pcbStructInfo = bytesNeeded;
3935 SetLastError(ERROR_MORE_DATA);
3940 CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
3944 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3945 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3946 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3947 0, NULL, &name->u.FullName, pcbStructInfo, NULL,
3948 name->u.FullName.rgAltEntry);
3951 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3957 SetLastError(CRYPT_E_ASN1_BADTAG);
3963 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
3964 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3966 struct AsnDecodeSequenceItem items[] = {
3967 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
3968 DistPointName), CRYPT_AsnDecodeDistPointName,
3969 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
3970 DistPointName.u.FullName.rgAltEntry), 0 },
3971 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
3972 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
3973 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
3974 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
3975 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
3976 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
3980 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3981 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3986 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
3987 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3988 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3992 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3993 pDecodePara, pvStructInfo, *pcbStructInfo);
3997 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3998 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
3999 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4001 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4002 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4006 SetLastError(STATUS_ACCESS_VIOLATION);
4013 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4014 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4015 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4019 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4020 pDecodePara, pvStructInfo, *pcbStructInfo);
4024 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4025 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4027 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4028 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4032 SetLastError(STATUS_ACCESS_VIOLATION);
4039 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4040 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4041 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4045 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4046 pDecodePara, pvStructInfo, *pcbStructInfo);
4050 struct AsnDecodeSequenceItem items[] = {
4051 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4052 DistPointName), CRYPT_AsnDecodeDistPointName,
4053 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4054 offsetof(CRL_ISSUING_DIST_POINT,
4055 DistPointName.u.FullName.rgAltEntry), 0 },
4056 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4057 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4059 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4060 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4062 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4063 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4064 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4065 OnlySomeReasonFlags.pbData), 0 },
4066 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4067 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4070 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4071 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4072 pcbStructInfo, NULL, NULL);
4076 SetLastError(STATUS_ACCESS_VIOLATION);
4083 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4084 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4089 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4090 pvStructInfo, *pcbStructInfo, pcbDecoded);
4094 SetLastError(CRYPT_E_ASN1_EOD);
4097 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4099 SetLastError(CRYPT_E_ASN1_BADTAG);
4102 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4103 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4104 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4106 if (ret && pvStructInfo)
4107 *(BOOL *)pvStructInfo = TRUE;
4108 TRACE("returning %d\n", ret);
4112 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4113 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4117 struct AsnDecodeSequenceItem items[] = {
4118 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4119 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4120 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4121 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4122 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4123 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4124 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4127 CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)pvStructInfo;
4129 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4130 pvStructInfo, *pcbStructInfo, pcbDecoded);
4132 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4133 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4134 pcbDecoded, subtree ? (BYTE *)subtree->Base.u.pwszURL : NULL);
4137 TRACE("%d\n", *pcbDecoded);
4138 if (*pcbDecoded < cbEncoded)
4139 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4140 *(pbEncoded + *pcbDecoded + 1));
4142 TRACE("returning %d\n", ret);
4146 static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
4147 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4151 struct AsnArrayDescriptor arrayDesc = { 0,
4152 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4153 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4154 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4156 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4157 pvStructInfo, *pcbStructInfo, pcbDecoded);
4159 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4160 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4161 array ? array->rgItems : NULL);
4166 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4167 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4168 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4172 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4173 pDecodePara, pvStructInfo, *pcbStructInfo);
4177 struct AsnDecodeSequenceItem items[] = {
4178 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4179 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4180 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4181 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4182 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4183 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4184 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4185 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4188 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4189 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4190 pcbStructInfo, NULL, NULL);
4194 SetLastError(STATUS_ACCESS_VIOLATION);
4200 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
4201 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4205 struct AsnDecodeSequenceItem items[] = {
4206 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
4207 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
4209 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
4210 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
4211 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
4213 CERT_ISSUER_SERIAL_NUMBER *issuerSerial =
4214 (CERT_ISSUER_SERIAL_NUMBER *)pvStructInfo;
4216 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4217 pvStructInfo, *pcbStructInfo, pcbDecoded);
4219 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4220 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4221 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
4222 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
4224 SetLastError(CRYPT_E_ASN1_CORRUPT);
4227 TRACE("returning %d\n", ret);
4231 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
4232 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4235 CMSG_SIGNER_INFO *info = (CMSG_SIGNER_INFO *)pvStructInfo;
4236 struct AsnDecodeSequenceItem items[] = {
4237 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
4238 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4239 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
4240 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
4241 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
4242 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
4243 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4244 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4245 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4246 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
4247 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4248 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4249 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
4250 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4251 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
4252 HashEncryptionAlgorithm.pszObjId), 0 },
4253 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
4254 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4255 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
4256 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4257 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
4258 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4259 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4263 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4264 pvStructInfo, *pcbStructInfo);
4266 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4267 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4268 pcbDecoded, info ? info->Issuer.pbData : NULL);
4272 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
4273 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4274 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4278 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4279 pDecodePara, pvStructInfo, *pcbStructInfo);
4283 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
4284 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4285 if (ret && pvStructInfo)
4287 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4288 pcbStructInfo, *pcbStructInfo);
4291 CMSG_SIGNER_INFO *info;
4293 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4294 pvStructInfo = *(BYTE **)pvStructInfo;
4295 info = (CMSG_SIGNER_INFO *)pvStructInfo;
4296 info->Issuer.pbData = ((BYTE *)info +
4297 sizeof(CMSG_SIGNER_INFO));
4298 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
4299 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4300 pcbStructInfo, NULL);
4306 SetLastError(STATUS_ACCESS_VIOLATION);
4309 TRACE("returning %d\n", ret);
4313 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
4314 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4317 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
4318 CRYPT_AsnDecodePKCSSignerInfoInternal, sizeof(CMSG_SIGNER_INFO), TRUE,
4319 offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
4320 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4322 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4323 pvStructInfo, *pcbStructInfo, pcbDecoded);
4325 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4326 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4327 array ? array->rgItems : NULL);
4331 BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
4332 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
4333 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
4336 struct AsnDecodeSequenceItem items[] = {
4337 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
4338 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4339 /* Placeholder for the hash algorithms - redundant with those in the
4340 * signers, so just ignore them.
4342 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
4343 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
4344 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
4345 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
4346 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4347 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
4348 CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
4349 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
4350 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4351 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
4352 sizeof(struct GenericArray), TRUE, TRUE,
4353 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
4354 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
4355 CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
4356 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
4359 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4360 pDecodePara, signedInfo, *pcbSignedInfo);
4362 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4363 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
4365 TRACE("returning %d\n", ret);
4369 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
4370 LPCSTR lpszStructType)
4372 CryptDecodeObjectExFunc decodeFunc = NULL;
4374 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
4375 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
4377 SetLastError(ERROR_FILE_NOT_FOUND);
4380 if (!HIWORD(lpszStructType))
4382 switch (LOWORD(lpszStructType))
4384 case LOWORD(X509_CERT):
4385 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
4387 case LOWORD(X509_CERT_TO_BE_SIGNED):
4388 decodeFunc = CRYPT_AsnDecodeCert;
4390 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
4391 decodeFunc = CRYPT_AsnDecodeCRL;
4393 case LOWORD(X509_EXTENSIONS):
4394 decodeFunc = CRYPT_AsnDecodeExtensions;
4396 case LOWORD(X509_NAME_VALUE):
4397 decodeFunc = CRYPT_AsnDecodeNameValue;
4399 case LOWORD(X509_NAME):
4400 decodeFunc = CRYPT_AsnDecodeName;
4402 case LOWORD(X509_PUBLIC_KEY_INFO):
4403 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
4405 case LOWORD(X509_AUTHORITY_KEY_ID):
4406 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4408 case LOWORD(X509_ALTERNATE_NAME):
4409 decodeFunc = CRYPT_AsnDecodeAltName;
4411 case LOWORD(X509_BASIC_CONSTRAINTS):
4412 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4414 case LOWORD(X509_BASIC_CONSTRAINTS2):
4415 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4417 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
4418 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
4420 case LOWORD(X509_UNICODE_NAME):
4421 decodeFunc = CRYPT_AsnDecodeUnicodeName;
4423 case LOWORD(PKCS_ATTRIBUTE):
4424 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
4426 case LOWORD(X509_UNICODE_NAME_VALUE):
4427 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
4429 case LOWORD(X509_OCTET_STRING):
4430 decodeFunc = CRYPT_AsnDecodeOctets;
4432 case LOWORD(X509_BITS):
4433 case LOWORD(X509_KEY_USAGE):
4434 decodeFunc = CRYPT_AsnDecodeBits;
4436 case LOWORD(X509_INTEGER):
4437 decodeFunc = CRYPT_AsnDecodeInt;
4439 case LOWORD(X509_MULTI_BYTE_INTEGER):
4440 decodeFunc = CRYPT_AsnDecodeInteger;
4442 case LOWORD(X509_MULTI_BYTE_UINT):
4443 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
4445 case LOWORD(X509_ENUMERATED):
4446 decodeFunc = CRYPT_AsnDecodeEnumerated;
4448 case LOWORD(X509_CHOICE_OF_TIME):
4449 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
4451 case LOWORD(X509_AUTHORITY_KEY_ID2):
4452 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4454 case LOWORD(PKCS_CONTENT_INFO):
4455 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
4457 case LOWORD(X509_SEQUENCE_OF_ANY):
4458 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
4460 case LOWORD(PKCS_UTC_TIME):
4461 decodeFunc = CRYPT_AsnDecodeUtcTime;
4463 case LOWORD(X509_CRL_DIST_POINTS):
4464 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4466 case LOWORD(X509_ENHANCED_KEY_USAGE):
4467 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4469 case LOWORD(PKCS_ATTRIBUTES):
4470 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
4472 case LOWORD(X509_ISSUING_DIST_POINT):
4473 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4475 case LOWORD(X509_NAME_CONSTRAINTS):
4476 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4478 case LOWORD(PKCS7_SIGNER_INFO):
4479 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
4483 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
4484 decodeFunc = CRYPT_AsnDecodeExtensions;
4485 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
4486 decodeFunc = CRYPT_AsnDecodeUtcTime;
4487 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
4488 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4489 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
4490 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4491 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
4492 decodeFunc = CRYPT_AsnDecodeEnumerated;
4493 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
4494 decodeFunc = CRYPT_AsnDecodeBits;
4495 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
4496 decodeFunc = CRYPT_AsnDecodeOctets;
4497 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
4498 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4499 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
4500 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4501 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
4502 decodeFunc = CRYPT_AsnDecodeAltName;
4503 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
4504 decodeFunc = CRYPT_AsnDecodeAltName;
4505 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
4506 decodeFunc = CRYPT_AsnDecodeAltName;
4507 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
4508 decodeFunc = CRYPT_AsnDecodeAltName;
4509 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
4510 decodeFunc = CRYPT_AsnDecodeAltName;
4511 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
4512 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4513 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
4514 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4515 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
4516 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4517 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
4518 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4522 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
4523 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4525 static HCRYPTOIDFUNCSET set = NULL;
4526 CryptDecodeObjectFunc decodeFunc = NULL;
4529 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
4530 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4531 (void **)&decodeFunc, hFunc);
4535 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
4536 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4538 static HCRYPTOIDFUNCSET set = NULL;
4539 CryptDecodeObjectExFunc decodeFunc = NULL;
4542 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
4543 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4544 (void **)&decodeFunc, hFunc);
4548 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4549 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
4550 DWORD *pcbStructInfo)
4553 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
4554 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
4555 HCRYPTOIDFUNCADDR hFunc = NULL;
4557 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
4558 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
4559 pvStructInfo, pcbStructInfo);
4561 if (!pvStructInfo && !pcbStructInfo)
4563 SetLastError(ERROR_INVALID_PARAMETER);
4568 SetLastError(CRYPT_E_ASN1_EOD);
4571 if (cbEncoded > MAX_ENCODED_LEN)
4573 SetLastError(CRYPT_E_ASN1_LARGE);
4577 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
4580 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4581 debugstr_a(lpszStructType));
4582 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
4583 lpszStructType, &hFunc);
4584 if (!pCryptDecodeObject)
4585 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
4586 lpszStructType, &hFunc);
4588 if (pCryptDecodeObject)
4589 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4590 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4591 else if (pCryptDecodeObjectEx)
4592 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
4593 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
4594 pvStructInfo, pcbStructInfo);
4596 CryptFreeOIDFunctionAddress(hFunc, 0);
4597 TRACE_(crypt)("returning %d\n", ret);
4601 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4602 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4603 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4606 CryptDecodeObjectExFunc decodeFunc;
4607 HCRYPTOIDFUNCADDR hFunc = NULL;
4609 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4610 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
4611 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4613 if (!pvStructInfo && !pcbStructInfo)
4615 SetLastError(ERROR_INVALID_PARAMETER);
4620 SetLastError(CRYPT_E_ASN1_EOD);
4623 if (cbEncoded > MAX_ENCODED_LEN)
4625 SetLastError(CRYPT_E_ASN1_LARGE);
4629 SetLastError(NOERROR);
4630 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
4631 *(BYTE **)pvStructInfo = NULL;
4632 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
4635 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4636 debugstr_a(lpszStructType));
4637 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
4641 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
4642 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4645 CryptDecodeObjectFunc pCryptDecodeObject =
4646 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
4648 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4649 * directly, as that could cause an infinite loop.
4651 if (pCryptDecodeObject)
4653 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4655 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4656 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
4657 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4658 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
4659 ret = pCryptDecodeObject(dwCertEncodingType,
4660 lpszStructType, pbEncoded, cbEncoded, dwFlags,
4661 *(BYTE **)pvStructInfo, pcbStructInfo);
4664 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4665 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4669 CryptFreeOIDFunctionAddress(hFunc, 0);
4670 TRACE_(crypt)("returning %d\n", ret);