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"
38 #define NONAMELESSUNION
45 #include "wine/debug.h"
46 #include "wine/exception.h"
47 #include "crypt32_private.h"
49 /* This is a bit arbitrary, but to set some limit: */
50 #define MAX_ENCODED_LEN 0x02000000
52 #define ASN_FLAGS_MASK 0xe0
53 #define ASN_TYPE_MASK 0x1f
55 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
56 WINE_DECLARE_DEBUG_CHANNEL(crypt);
64 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
65 DWORD, DWORD, void *, DWORD *);
66 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
67 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
69 /* Internal decoders don't do memory allocation or exception handling, and
70 * they report how many bytes they decoded.
72 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
73 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
75 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
76 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
78 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
79 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
81 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
82 * time, doesn't do memory allocation, and doesn't do exception handling.
84 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
85 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
87 /* Assumes algo->Parameters.pbData is set ahead of time. */
88 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
89 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
90 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
91 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
92 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
93 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
94 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
96 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
97 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
98 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
99 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
100 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
101 * member has been initialized, doesn't do exception handling, and doesn't do
102 * memory allocation. Also doesn't check tag, assumes the caller has checked
105 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
106 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
108 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
109 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
110 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
113 /* Gets the number of length bytes from the given (leading) length byte */
114 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
116 /* Helper function to get the encoded length of the data starting at pbEncoded,
117 * where pbEncoded[0] is the tag. If the data are too short to contain a
118 * length or if the length is too large for cbEncoded, sets an appropriate
119 * error code and returns FALSE. If the encoded length is unknown due to
120 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
122 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
129 SetLastError(CRYPT_E_ASN1_CORRUPT);
132 else if (pbEncoded[1] <= 0x7f)
134 if (pbEncoded[1] + 1 > cbEncoded)
136 SetLastError(CRYPT_E_ASN1_EOD);
145 else if (pbEncoded[1] == 0x80)
147 *len = CMSG_INDEFINITE_LENGTH;
152 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
154 if (lenLen > sizeof(DWORD) + 1)
156 SetLastError(CRYPT_E_ASN1_LARGE);
159 else if (lenLen + 2 > cbEncoded)
161 SetLastError(CRYPT_E_ASN1_CORRUPT);
174 if (out + lenLen + 1 > cbEncoded)
176 SetLastError(CRYPT_E_ASN1_EOD);
189 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
190 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
194 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
195 *len == CMSG_INDEFINITE_LENGTH)
197 SetLastError(CRYPT_E_ASN1_CORRUPT);
203 /* Helper function to check *pcbStructInfo, set it to the required size, and
204 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
205 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
206 * pointer to the newly allocated memory.
208 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
209 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
214 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
216 if (pDecodePara && pDecodePara->pfnAlloc)
217 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
219 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
220 if (!*(BYTE **)pvStructInfo)
223 *pcbStructInfo = bytesNeeded;
225 else if (*pcbStructInfo < bytesNeeded)
227 *pcbStructInfo = bytesNeeded;
228 SetLastError(ERROR_MORE_DATA);
234 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
236 if (pDecodePara && pDecodePara->pfnFree)
237 pDecodePara->pfnFree(pv);
242 /* Helper function to check *pcbStructInfo and set it to the required size.
243 * Assumes pvStructInfo is not NULL.
245 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
249 if (*pcbStructInfo < bytesNeeded)
251 *pcbStructInfo = bytesNeeded;
252 SetLastError(ERROR_MORE_DATA);
257 *pcbStructInfo = bytesNeeded;
264 * The expected tag of the item. If tag is 0, decodeFunc is called
265 * regardless of the tag value seen.
267 * A sequence is decoded into a struct. The offset member is the
268 * offset of this item within that struct.
270 * The decoder function to use. If this is NULL, then the member isn't
271 * decoded, but minSize space is reserved for it.
273 * The minimum amount of space occupied after decoding. You must set this.
275 * If true, and the tag doesn't match the expected tag for this item,
276 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
277 * filled with 0 for this member.
278 * hasPointer, pointerOffset:
279 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
280 * the offset within the struct of the data pointer (or to the
281 * first data pointer, if more than one exist).
283 * Used by CRYPT_AsnDecodeSequence, not for your use.
285 struct AsnDecodeSequenceItem
289 InternalDecodeFunc decodeFunc;
297 /* Decodes the items in a sequence, where the items are described in items,
298 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
299 * pvStructInfo. nextData is a pointer to the memory location at which the
300 * first decoded item with a dynamic pointer should point.
301 * Upon decoding, *cbDecoded is the total number of bytes decoded.
302 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
304 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
305 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
306 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
309 DWORD i, decoded = 0;
310 const BYTE *ptr = pbEncoded;
312 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
313 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
315 for (i = 0, ret = TRUE; ret && i < cItem; i++)
317 if (cbEncoded - (ptr - pbEncoded) != 0)
321 if ((ret = CRYPT_GetLengthIndefinite(ptr,
322 cbEncoded - (ptr - pbEncoded), &itemLen)))
324 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
326 if (ptr[0] == items[i].tag || !items[i].tag)
328 DWORD itemEncodedLen;
330 if (itemLen == CMSG_INDEFINITE_LENGTH)
331 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
333 itemEncodedLen = 1 + itemLenBytes + itemLen;
334 if (nextData && pvStructInfo && items[i].hasPointer)
336 TRACE("Setting next pointer to %p\n",
338 *(BYTE **)((BYTE *)pvStructInfo +
339 items[i].pointerOffset) = nextData;
341 if (items[i].decodeFunc)
346 TRACE("decoding item %d\n", i);
348 TRACE("sizing item %d\n", i);
349 ret = items[i].decodeFunc(ptr, itemEncodedLen,
350 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
351 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
352 : NULL, &items[i].size, &itemDecoded);
355 /* Account for alignment padding */
356 if (items[i].size % sizeof(DWORD_PTR))
357 items[i].size += sizeof(DWORD_PTR) -
358 items[i].size % sizeof(DWORD_PTR);
359 TRACE("item %d size: %d\n", i, items[i].size);
360 if (nextData && items[i].hasPointer &&
361 items[i].size > items[i].minSize)
362 nextData += items[i].size - items[i].minSize;
363 if (itemDecoded > itemEncodedLen)
365 WARN("decoded length %d exceeds encoded %d\n",
366 itemDecoded, itemEncodedLen);
367 SetLastError(CRYPT_E_ASN1_CORRUPT);
372 if (itemLen == CMSG_INDEFINITE_LENGTH)
374 if (itemDecoded > itemEncodedLen - 2 ||
375 *(ptr + itemDecoded) != 0 ||
376 *(ptr + itemDecoded + 1) != 0)
378 TRACE("expected 0 TLV\n");
379 SetLastError(CRYPT_E_ASN1_CORRUPT);
388 decoded += itemDecoded;
389 TRACE("item %d: decoded %d bytes\n", i,
394 else if (items[i].optional &&
395 GetLastError() == CRYPT_E_ASN1_BADTAG)
397 TRACE("skipping optional item %d\n", i);
398 items[i].size = items[i].minSize;
399 SetLastError(NOERROR);
403 TRACE("item %d failed: %08x\n", i,
406 else if (itemLen == CMSG_INDEFINITE_LENGTH)
408 ERR("can't use indefinite length encoding without a decoder\n");
409 SetLastError(CRYPT_E_ASN1_CORRUPT);
414 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
415 ptr += itemEncodedLen;
416 decoded += itemEncodedLen;
417 items[i].size = items[i].minSize;
420 else if (items[i].optional)
422 TRACE("skipping optional item %d\n", i);
423 items[i].size = items[i].minSize;
427 TRACE("item %d: tag %02x doesn't match expected %02x\n",
428 i, ptr[0], items[i].tag);
429 SetLastError(CRYPT_E_ASN1_BADTAG);
434 else if (items[i].optional)
436 TRACE("missing optional item %d, skipping\n", i);
437 items[i].size = items[i].minSize;
441 TRACE("not enough bytes for item %d, failing\n", i);
442 SetLastError(CRYPT_E_ASN1_CORRUPT);
447 *cbDecoded = decoded;
448 TRACE("returning %d\n", ret);
452 /* This decodes an arbitrary sequence into a contiguous block of memory
453 * (basically, a struct.) Each element being decoded is described by a struct
454 * AsnDecodeSequenceItem, see above.
455 * startingPointer is an optional pointer to the first place where dynamic
456 * data will be stored. If you know the starting offset, you may pass it
457 * here. Otherwise, pass NULL, and one will be inferred from the items.
459 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
460 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
461 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
462 DWORD *pcbDecoded, void *startingPointer)
466 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
467 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
470 if (pbEncoded[0] == ASN_SEQUENCE)
474 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
476 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
477 const BYTE *ptr = pbEncoded + 1 + lenBytes;
478 BOOL indefinite = FALSE;
480 cbEncoded -= 1 + lenBytes;
481 if (dataLen == CMSG_INDEFINITE_LENGTH)
486 else if (cbEncoded < dataLen)
488 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
490 SetLastError(CRYPT_E_ASN1_CORRUPT);
495 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
496 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
497 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
499 if (cbDecoded > cbEncoded - 2)
501 /* Not enough space for 0 TLV */
502 SetLastError(CRYPT_E_ASN1_CORRUPT);
505 else if (*(ptr + cbDecoded) != 0 ||
506 *(ptr + cbDecoded + 1) != 0)
508 TRACE("expected 0 TLV\n");
509 SetLastError(CRYPT_E_ASN1_CORRUPT);
516 if (ret && !indefinite && cbDecoded != dataLen)
518 TRACE("expected %d decoded, got %d, failing\n", dataLen,
520 SetLastError(CRYPT_E_ASN1_CORRUPT);
525 DWORD i, bytesNeeded = 0, structSize = 0;
527 for (i = 0; i < cItem; i++)
529 bytesNeeded += items[i].size;
530 structSize += items[i].minSize;
533 *pcbDecoded = 1 + lenBytes + cbDecoded;
535 *pcbStructInfo = bytesNeeded;
536 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
537 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
541 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
542 pvStructInfo = *(BYTE **)pvStructInfo;
544 nextData = (BYTE *)startingPointer;
546 nextData = (BYTE *)pvStructInfo + structSize;
547 memset(pvStructInfo, 0, structSize);
548 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
549 ptr, dataLen, dwFlags, pvStructInfo, nextData,
551 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
552 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
559 SetLastError(CRYPT_E_ASN1_BADTAG);
562 TRACE("returning %d (%08x)\n", ret, GetLastError());
567 * The expected tag of the entire encoded array (usually a variant
568 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
569 * regardless of the tag seen.
571 * used to decode each item in the array
573 * is the minimum size of each decoded item
575 * indicates whether each item has a dynamic pointer
577 * indicates the offset within itemSize at which the pointer exists
579 struct AsnArrayDescriptor
582 InternalDecodeFunc decodeFunc;
588 struct AsnArrayItemSize
594 /* Decodes an array of like types into a struct GenericArray.
595 * The layout and decoding of the array are described by a struct
596 * AsnArrayDescriptor.
598 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
599 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
600 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
601 DWORD *pcbDecoded, void *startingPointer)
605 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
606 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
609 if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
613 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
615 DWORD bytesNeeded, cItems = 0, decoded;
616 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
617 /* There can be arbitrarily many items, but there is often only one.
619 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
621 decoded = 1 + lenBytes;
622 bytesNeeded = sizeof(struct GenericArray);
626 BOOL doneDecoding = FALSE;
628 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
630 if (dataLen == CMSG_INDEFINITE_LENGTH)
637 SetLastError(CRYPT_E_ASN1_CORRUPT);
644 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
648 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
650 /* Each item decoded may not tolerate extraneous bytes,
651 * so get the length of the next element if known.
653 if ((ret = CRYPT_GetLengthIndefinite(ptr,
654 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
656 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
657 itemEncoded = cbEncoded - (ptr - pbEncoded);
659 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
663 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
664 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
669 if (itemSizes != &itemSize)
670 itemSizes = CryptMemRealloc(itemSizes,
671 cItems * sizeof(struct AsnArrayItemSize));
676 cItems * sizeof(struct AsnArrayItemSize));
678 memcpy(itemSizes, &itemSize,
683 decoded += itemDecoded;
684 itemSizes[cItems - 1].encodedLen = itemEncoded;
685 itemSizes[cItems - 1].size = size;
698 *pcbDecoded = decoded;
700 *pcbStructInfo = bytesNeeded;
701 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
702 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
707 struct GenericArray *array;
709 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
710 pvStructInfo = *(BYTE **)pvStructInfo;
711 array = (struct GenericArray *)pvStructInfo;
712 array->cItems = cItems;
714 array->rgItems = startingPointer;
716 array->rgItems = (BYTE *)array +
717 sizeof(struct GenericArray);
718 nextData = array->rgItems +
719 array->cItems * arrayDesc->itemSize;
720 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
721 i < cItems && ptr - pbEncoded - 1 - lenBytes <
726 if (arrayDesc->hasPointer)
727 *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
728 + arrayDesc->pointerOffset) = nextData;
729 ret = arrayDesc->decodeFunc(ptr,
730 itemSizes[i].encodedLen,
731 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
732 array->rgItems + i * arrayDesc->itemSize,
733 &itemSizes[i].size, &itemDecoded);
736 nextData += itemSizes[i].size - arrayDesc->itemSize;
740 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
741 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
744 if (itemSizes != &itemSize)
745 CryptMemFree(itemSizes);
750 SetLastError(CRYPT_E_ASN1_BADTAG);
756 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
757 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
758 * to CRYPT_E_ASN1_CORRUPT.
759 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
762 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
763 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
768 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
770 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
771 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
773 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
774 bytesNeeded += 1 + lenBytes + dataLen;
777 *pcbDecoded = 1 + lenBytes + dataLen;
779 *pcbStructInfo = bytesNeeded;
780 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
782 CRYPT_DER_BLOB *blob;
784 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
785 pvStructInfo = *(BYTE **)pvStructInfo;
786 blob = (CRYPT_DER_BLOB *)pvStructInfo;
787 blob->cbData = 1 + lenBytes + dataLen;
790 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
791 blob->pbData = (BYTE *)pbEncoded;
794 assert(blob->pbData);
795 memcpy(blob->pbData, pbEncoded, blob->cbData);
800 SetLastError(CRYPT_E_ASN1_CORRUPT);
808 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
809 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
810 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
815 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
816 pvStructInfo, *pcbStructInfo, pcbDecoded);
818 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
821 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
822 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
824 if (ret && pvStructInfo)
826 CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
833 for (i = 0; i < blob->cbData / 2; i++)
835 temp = blob->pbData[i];
836 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
837 blob->pbData[blob->cbData - i - 1] = temp;
841 TRACE("returning %d (%08x)\n", ret, GetLastError());
845 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
846 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
847 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
851 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
852 pDecodePara, pvStructInfo, *pcbStructInfo);
856 struct AsnDecodeSequenceItem items[] = {
857 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
858 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
859 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
860 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
861 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
862 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
863 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
864 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
865 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
866 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
869 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
870 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
871 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
872 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
873 pcbStructInfo, NULL, NULL);
877 SetLastError(STATUS_ACCESS_VIOLATION);
882 TRACE("Returning %d (%08x)\n", ret, GetLastError());
886 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
887 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
892 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
894 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
896 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
897 dwFlags, pvStructInfo, pcbStructInfo, NULL);
899 *pcbDecoded = 1 + lenBytes + dataLen;
904 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
905 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
909 struct AsnDecodeSequenceItem items[] = {
910 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
911 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
912 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
913 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
916 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
917 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
922 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
923 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
929 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
931 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
933 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
934 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
935 if (ret && pcbDecoded)
936 *pcbDecoded = 1 + lenBytes + dataLen;
941 static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
942 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
943 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
946 struct AsnDecodeSequenceItem items[] = {
947 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
948 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
949 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
950 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
951 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
952 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
953 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
954 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
955 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
956 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
958 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
959 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
961 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
962 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
964 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
965 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
966 FALSE, TRUE, offsetof(CERT_INFO,
967 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
968 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
969 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
970 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
971 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
972 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
973 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
974 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
975 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
976 offsetof(CERT_INFO, rgExtension), 0 },
979 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
980 pDecodePara, pvStructInfo, *pcbStructInfo);
982 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
983 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
985 if (ret && pvStructInfo)
989 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
990 info = *(CERT_INFO **)pvStructInfo;
992 info = (CERT_INFO *)pvStructInfo;
993 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
994 !info->Subject.cbData)
996 SetLastError(CRYPT_E_ASN1_CORRUPT);
997 /* Don't need to deallocate, because it should have failed on the
998 * first pass (and no memory was allocated.)
1004 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1008 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1009 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1010 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1014 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1015 pDecodePara, pvStructInfo, *pcbStructInfo);
1021 /* Unless told not to, first try to decode it as a signed cert. */
1022 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1024 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1026 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1027 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1028 (BYTE *)&signedCert, &size);
1032 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1033 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1034 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1035 pvStructInfo, pcbStructInfo);
1036 LocalFree(signedCert);
1039 /* Failing that, try it as an unsigned cert */
1043 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1044 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1045 pDecodePara, pvStructInfo, pcbStructInfo);
1050 SetLastError(STATUS_ACCESS_VIOLATION);
1054 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1058 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1059 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1062 struct AsnDecodeSequenceItem items[] = {
1063 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1064 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1065 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1066 { 0, offsetof(CRL_ENTRY, RevocationDate),
1067 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1068 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1069 CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1070 offsetof(CRL_ENTRY, rgExtension), 0 },
1072 PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1074 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1077 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1078 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1079 entry ? entry->SerialNumber.pbData : NULL);
1080 if (ret && entry && !entry->SerialNumber.cbData)
1082 WARN("empty CRL entry serial number\n");
1083 SetLastError(CRYPT_E_ASN1_CORRUPT);
1089 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1090 * been set prior to calling.
1092 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1093 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1096 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1097 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1098 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1099 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1101 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1102 pvStructInfo, *pcbStructInfo, pcbDecoded);
1104 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1105 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1106 entries ? entries->rgItems : NULL);
1107 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1111 static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1112 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1113 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1115 struct AsnDecodeSequenceItem items[] = {
1116 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1117 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1118 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1119 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1120 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1121 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1122 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1124 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1125 sizeof(FILETIME), FALSE, FALSE, 0 },
1126 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1127 sizeof(FILETIME), TRUE, FALSE, 0 },
1128 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1129 CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1130 offsetof(CRL_INFO, rgCRLEntry), 0 },
1131 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1132 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1133 offsetof(CRL_INFO, rgExtension), 0 },
1137 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1138 pDecodePara, pvStructInfo, *pcbStructInfo);
1140 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1141 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1144 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1148 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1149 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1150 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1154 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1155 pDecodePara, pvStructInfo, *pcbStructInfo);
1161 /* Unless told not to, first try to decode it as a signed crl. */
1162 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1164 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1166 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1167 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1168 (BYTE *)&signedCrl, &size);
1172 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1173 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1174 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1175 pvStructInfo, pcbStructInfo);
1176 LocalFree(signedCrl);
1179 /* Failing that, try it as an unsigned crl */
1183 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1184 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1185 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1190 SetLastError(STATUS_ACCESS_VIOLATION);
1194 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1198 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1199 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1204 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1205 pvStructInfo, *pcbStructInfo);
1207 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1209 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1210 DWORD bytesNeeded = sizeof(LPSTR);
1214 /* The largest possible string for the first two components
1215 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1220 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1221 pbEncoded[1 + lenBytes] / 40,
1222 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1224 bytesNeeded += strlen(firstTwo) + 1;
1225 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1226 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1228 /* large enough for ".4000000" */
1232 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1239 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1242 SetLastError(CRYPT_E_ASN1_CORRUPT);
1249 snprintf(str, sizeof(str), ".%d", val);
1250 bytesNeeded += strlen(str);
1255 *pcbDecoded = 1 + lenBytes + dataLen;
1257 *pcbStructInfo = bytesNeeded;
1258 else if (*pcbStructInfo < bytesNeeded)
1260 *pcbStructInfo = bytesNeeded;
1261 SetLastError(ERROR_MORE_DATA);
1269 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1272 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1273 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1275 pszObjId += strlen(pszObjId);
1276 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1277 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1281 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1290 sprintf(pszObjId, ".%d", val);
1291 pszObjId += strlen(pszObjId);
1295 *(LPSTR *)pvStructInfo = NULL;
1296 *pcbStructInfo = bytesNeeded;
1302 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1303 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1307 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1308 pvStructInfo, *pcbStructInfo);
1310 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1311 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1312 pvStructInfo, pcbStructInfo, pcbDecoded);
1315 SetLastError(CRYPT_E_ASN1_BADTAG);
1321 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1324 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1325 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1327 struct AsnDecodeSequenceItem items[] = {
1328 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1329 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1330 offsetof(CERT_EXTENSION, pszObjId), 0 },
1331 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1332 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1333 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1334 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1335 offsetof(CERT_EXTENSION, Value.pbData) },
1338 PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1340 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1344 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1345 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1346 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1347 pcbDecoded, ext ? ext->pszObjId : NULL);
1349 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1350 debugstr_a(ext->pszObjId));
1351 TRACE("returning %d (%08x)\n", ret, GetLastError());
1355 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1356 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1360 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1361 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1362 offsetof(CERT_EXTENSION, pszObjId) };
1363 PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1365 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1366 pvStructInfo, *pcbStructInfo, pcbDecoded);
1368 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1369 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1370 exts ? exts->rgExtension : NULL);
1374 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1375 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1376 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1382 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1383 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1384 if (ret && pvStructInfo)
1386 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1387 pcbStructInfo, *pcbStructInfo);
1390 CERT_EXTENSIONS *exts;
1392 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1393 pvStructInfo = *(BYTE **)pvStructInfo;
1394 exts = (CERT_EXTENSIONS *)pvStructInfo;
1395 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1396 sizeof(CERT_EXTENSIONS));
1397 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1398 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1399 pcbStructInfo, NULL);
1405 SetLastError(STATUS_ACCESS_VIOLATION);
1412 /* Warning: this assumes the address of value->Value.pbData is already set, in
1413 * order to avoid overwriting memory. (In some cases, it may change it, if it
1414 * doesn't copy anything to memory.) Be sure to set it correctly!
1416 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1417 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1422 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1424 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1426 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1427 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1429 switch (pbEncoded[0])
1431 case ASN_OCTETSTRING:
1432 valueType = CERT_RDN_OCTET_STRING;
1433 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1434 bytesNeeded += dataLen;
1436 case ASN_NUMERICSTRING:
1437 valueType = CERT_RDN_NUMERIC_STRING;
1438 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1439 bytesNeeded += dataLen;
1441 case ASN_PRINTABLESTRING:
1442 valueType = CERT_RDN_PRINTABLE_STRING;
1443 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1444 bytesNeeded += dataLen;
1447 valueType = CERT_RDN_IA5_STRING;
1448 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1449 bytesNeeded += dataLen;
1452 valueType = CERT_RDN_T61_STRING;
1453 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1454 bytesNeeded += dataLen;
1456 case ASN_VIDEOTEXSTRING:
1457 valueType = CERT_RDN_VIDEOTEX_STRING;
1458 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1459 bytesNeeded += dataLen;
1461 case ASN_GRAPHICSTRING:
1462 valueType = CERT_RDN_GRAPHIC_STRING;
1463 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1464 bytesNeeded += dataLen;
1466 case ASN_VISIBLESTRING:
1467 valueType = CERT_RDN_VISIBLE_STRING;
1468 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1469 bytesNeeded += dataLen;
1471 case ASN_GENERALSTRING:
1472 valueType = CERT_RDN_GENERAL_STRING;
1473 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1474 bytesNeeded += dataLen;
1476 case ASN_UNIVERSALSTRING:
1477 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1478 SetLastError(CRYPT_E_ASN1_BADTAG);
1481 valueType = CERT_RDN_BMP_STRING;
1482 bytesNeeded += dataLen;
1484 case ASN_UTF8STRING:
1485 valueType = CERT_RDN_UTF8_STRING;
1486 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1487 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1490 SetLastError(CRYPT_E_ASN1_BADTAG);
1495 *pcbDecoded = 1 + lenBytes + dataLen;
1497 *pcbStructInfo = bytesNeeded;
1498 else if (*pcbStructInfo < bytesNeeded)
1500 *pcbStructInfo = bytesNeeded;
1501 SetLastError(ERROR_MORE_DATA);
1506 *pcbStructInfo = bytesNeeded;
1507 value->dwValueType = valueType;
1512 assert(value->Value.pbData);
1513 switch (pbEncoded[0])
1515 case ASN_OCTETSTRING:
1516 case ASN_NUMERICSTRING:
1517 case ASN_PRINTABLESTRING:
1520 case ASN_VIDEOTEXSTRING:
1521 case ASN_GRAPHICSTRING:
1522 case ASN_VISIBLESTRING:
1523 case ASN_GENERALSTRING:
1524 value->Value.cbData = dataLen;
1527 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1528 memcpy(value->Value.pbData,
1529 pbEncoded + 1 + lenBytes, dataLen);
1531 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1537 LPWSTR str = (LPWSTR)value->Value.pbData;
1539 value->Value.cbData = dataLen;
1540 for (i = 0; i < dataLen / 2; i++)
1541 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1542 pbEncoded[1 + lenBytes + 2 * i + 1];
1545 case ASN_UTF8STRING:
1547 LPWSTR str = (LPWSTR)value->Value.pbData;
1549 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1550 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1551 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1558 value->Value.cbData = 0;
1559 value->Value.pbData = NULL;
1566 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1567 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1568 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1574 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1575 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1576 if (ret && pvStructInfo)
1578 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1579 pcbStructInfo, *pcbStructInfo);
1582 CERT_NAME_VALUE *value;
1584 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1585 pvStructInfo = *(BYTE **)pvStructInfo;
1586 value = (CERT_NAME_VALUE *)pvStructInfo;
1587 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1588 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1589 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1590 pcbStructInfo, NULL);
1596 SetLastError(STATUS_ACCESS_VIOLATION);
1603 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1604 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1609 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1611 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1613 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1614 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1616 switch (pbEncoded[0])
1618 case ASN_NUMERICSTRING:
1619 valueType = CERT_RDN_NUMERIC_STRING;
1620 bytesNeeded += dataLen * 2;
1622 case ASN_PRINTABLESTRING:
1623 valueType = CERT_RDN_PRINTABLE_STRING;
1624 bytesNeeded += dataLen * 2;
1627 valueType = CERT_RDN_IA5_STRING;
1628 bytesNeeded += dataLen * 2;
1631 valueType = CERT_RDN_T61_STRING;
1632 bytesNeeded += dataLen * 2;
1634 case ASN_VIDEOTEXSTRING:
1635 valueType = CERT_RDN_VIDEOTEX_STRING;
1636 bytesNeeded += dataLen * 2;
1638 case ASN_GRAPHICSTRING:
1639 valueType = CERT_RDN_GRAPHIC_STRING;
1640 bytesNeeded += dataLen * 2;
1642 case ASN_VISIBLESTRING:
1643 valueType = CERT_RDN_VISIBLE_STRING;
1644 bytesNeeded += dataLen * 2;
1646 case ASN_GENERALSTRING:
1647 valueType = CERT_RDN_GENERAL_STRING;
1648 bytesNeeded += dataLen * 2;
1650 case ASN_UNIVERSALSTRING:
1651 valueType = CERT_RDN_UNIVERSAL_STRING;
1652 bytesNeeded += dataLen / 2;
1655 valueType = CERT_RDN_BMP_STRING;
1656 bytesNeeded += dataLen;
1658 case ASN_UTF8STRING:
1659 valueType = CERT_RDN_UTF8_STRING;
1660 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1661 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1664 SetLastError(CRYPT_E_ASN1_BADTAG);
1669 *pcbDecoded = 1 + lenBytes + dataLen;
1671 *pcbStructInfo = bytesNeeded;
1672 else if (*pcbStructInfo < bytesNeeded)
1674 *pcbStructInfo = bytesNeeded;
1675 SetLastError(ERROR_MORE_DATA);
1680 *pcbStructInfo = bytesNeeded;
1681 value->dwValueType = valueType;
1685 LPWSTR str = (LPWSTR)value->Value.pbData;
1687 assert(value->Value.pbData);
1688 switch (pbEncoded[0])
1690 case ASN_NUMERICSTRING:
1691 case ASN_PRINTABLESTRING:
1694 case ASN_VIDEOTEXSTRING:
1695 case ASN_GRAPHICSTRING:
1696 case ASN_VISIBLESTRING:
1697 case ASN_GENERALSTRING:
1698 value->Value.cbData = dataLen * 2;
1699 for (i = 0; i < dataLen; i++)
1700 str[i] = pbEncoded[1 + lenBytes + i];
1702 case ASN_UNIVERSALSTRING:
1703 value->Value.cbData = dataLen / 2;
1704 for (i = 0; i < dataLen / 4; i++)
1705 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1706 | pbEncoded[1 + lenBytes + 2 * i + 3];
1709 value->Value.cbData = dataLen;
1710 for (i = 0; i < dataLen / 2; i++)
1711 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1712 pbEncoded[1 + lenBytes + 2 * i + 1];
1714 case ASN_UTF8STRING:
1715 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1716 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1717 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1723 value->Value.cbData = 0;
1724 value->Value.pbData = NULL;
1731 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1732 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1733 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1739 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1740 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1741 if (ret && pvStructInfo)
1743 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1744 pcbStructInfo, *pcbStructInfo);
1747 CERT_NAME_VALUE *value;
1749 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1750 pvStructInfo = *(BYTE **)pvStructInfo;
1751 value = (CERT_NAME_VALUE *)pvStructInfo;
1752 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1753 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1754 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1755 pcbStructInfo, NULL);
1761 SetLastError(STATUS_ACCESS_VIOLATION);
1768 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1769 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1772 struct AsnDecodeSequenceItem items[] = {
1773 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1774 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1775 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1776 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1777 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1778 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1780 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1782 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1783 pvStructInfo, *pcbStructInfo);
1786 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1787 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1788 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1789 attr ? attr->pszObjId : NULL);
1792 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1793 debugstr_a(attr->pszObjId));
1794 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1796 TRACE("returning %d (%08x)\n", ret, GetLastError());
1800 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1801 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1804 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1805 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1806 offsetof(CERT_RDN_ATTR, pszObjId) };
1807 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1809 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1810 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1811 rdn ? rdn->rgRDNAttr : NULL);
1815 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1816 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1817 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1823 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1824 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1825 offsetof(CERT_RDN, rgRDNAttr) };
1827 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1828 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1832 SetLastError(STATUS_ACCESS_VIOLATION);
1839 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1840 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1844 struct AsnDecodeSequenceItem items[] = {
1845 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1846 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1847 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1848 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1849 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1850 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1852 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1854 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1855 pvStructInfo, *pcbStructInfo);
1858 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1859 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1860 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1861 attr ? attr->pszObjId : NULL);
1864 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1865 debugstr_a(attr->pszObjId));
1866 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1868 TRACE("returning %d (%08x)\n", ret, GetLastError());
1872 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1873 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1876 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1877 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1878 offsetof(CERT_RDN_ATTR, pszObjId) };
1879 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1881 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1882 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1883 rdn ? rdn->rgRDNAttr : NULL);
1887 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1888 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1889 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1895 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1896 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1897 offsetof(CERT_RDN, rgRDNAttr) };
1899 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1900 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1904 SetLastError(STATUS_ACCESS_VIOLATION);
1911 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1914 BOOL ret = TRUE, done = FALSE;
1915 DWORD indefiniteNestingLevels = 0, decoded = 0;
1917 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1924 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1927 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1929 if (dataLen == CMSG_INDEFINITE_LENGTH)
1931 indefiniteNestingLevels++;
1932 pbEncoded += 1 + lenBytes;
1933 cbEncoded -= 1 + lenBytes;
1934 decoded += 1 + lenBytes;
1935 TRACE("indefiniteNestingLevels = %d\n",
1936 indefiniteNestingLevels);
1940 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1941 indefiniteNestingLevels)
1943 indefiniteNestingLevels--;
1944 TRACE("indefiniteNestingLevels = %d\n",
1945 indefiniteNestingLevels);
1947 pbEncoded += 1 + lenBytes + dataLen;
1948 cbEncoded -= 1 + lenBytes + dataLen;
1949 decoded += 1 + lenBytes + dataLen;
1950 if (!indefiniteNestingLevels)
1954 } while (ret && !done);
1955 /* If we haven't found all 0 TLVs, we haven't found the end */
1956 if (ret && indefiniteNestingLevels)
1958 SetLastError(CRYPT_E_ASN1_EOD);
1962 *pcbDecoded = decoded;
1963 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1967 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1968 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1972 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
1974 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1975 pvStructInfo, *pcbStructInfo);
1977 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
1979 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1980 bytesNeeded += encodedLen;
1982 *pcbStructInfo = bytesNeeded;
1983 else if (*pcbStructInfo < bytesNeeded)
1985 SetLastError(ERROR_MORE_DATA);
1986 *pcbStructInfo = bytesNeeded;
1991 PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
1993 *pcbStructInfo = bytesNeeded;
1994 blob->cbData = encodedLen;
1995 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
1996 blob->pbData = (LPBYTE)pbEncoded;
1999 assert(blob->pbData);
2000 memcpy(blob->pbData, pbEncoded, blob->cbData);
2004 *pcbDecoded = encodedLen;
2009 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
2010 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2013 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2014 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2015 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
2017 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2018 pvStructInfo, *pcbStructInfo, pcbDecoded);
2020 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2021 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2022 array ? array->rgItems : NULL);
2026 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2027 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2031 struct AsnDecodeSequenceItem items[] = {
2032 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2033 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2034 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2035 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2036 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2037 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2039 PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2041 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2042 pvStructInfo, *pcbStructInfo);
2044 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2045 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2046 pcbDecoded, attr ? attr->pszObjId : NULL);
2047 TRACE("returning %d\n", ret);
2051 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2052 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2053 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2057 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2058 pDecodePara, pvStructInfo, *pcbStructInfo);
2064 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2065 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2069 *pcbStructInfo = bytesNeeded;
2070 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2071 pvStructInfo, pcbStructInfo, bytesNeeded)))
2073 PCRYPT_ATTRIBUTE attr;
2075 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2076 pvStructInfo = *(BYTE **)pvStructInfo;
2077 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2078 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2079 sizeof(CRYPT_ATTRIBUTE));
2080 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2081 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2088 SetLastError(STATUS_ACCESS_VIOLATION);
2091 TRACE("returning %d\n", ret);
2095 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2096 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2099 struct AsnArrayDescriptor arrayDesc = { 0,
2100 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2101 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2102 PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2105 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2106 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2111 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2112 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2113 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2117 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2118 pDecodePara, pvStructInfo, *pcbStructInfo);
2125 SetLastError(CRYPT_E_ASN1_EOD);
2126 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2127 SetLastError(CRYPT_E_ASN1_CORRUPT);
2128 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2129 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2133 *pcbStructInfo = bytesNeeded;
2134 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2135 pvStructInfo, pcbStructInfo, bytesNeeded)))
2137 PCRYPT_ATTRIBUTES attrs;
2139 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2140 pvStructInfo = *(BYTE **)pvStructInfo;
2141 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2142 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2143 sizeof(CRYPT_ATTRIBUTES));
2144 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2145 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2146 &bytesNeeded, NULL);
2152 SetLastError(STATUS_ACCESS_VIOLATION);
2155 TRACE("returning %d\n", ret);
2159 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2160 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2162 CRYPT_ALGORITHM_IDENTIFIER *algo =
2163 (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2165 struct AsnDecodeSequenceItem items[] = {
2166 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2167 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2168 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2169 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2170 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2171 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2174 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2175 pvStructInfo, *pcbStructInfo, pcbDecoded);
2177 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2178 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2179 pcbDecoded, algo ? algo->pszObjId : NULL);
2180 if (ret && pvStructInfo)
2182 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2183 debugstr_a(algo->pszObjId));
2188 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2189 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2193 struct AsnDecodeSequenceItem items[] = {
2194 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2195 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2196 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2197 Algorithm.pszObjId) },
2198 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2199 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2200 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2202 PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2204 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2205 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2206 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2210 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2211 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2212 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2220 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2221 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2224 *pcbStructInfo = bytesNeeded;
2225 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2226 pvStructInfo, pcbStructInfo, bytesNeeded)))
2228 PCERT_PUBLIC_KEY_INFO info;
2230 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2231 pvStructInfo = *(BYTE **)pvStructInfo;
2232 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2233 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2234 sizeof(CERT_PUBLIC_KEY_INFO);
2235 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2236 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2237 &bytesNeeded, NULL);
2243 SetLastError(STATUS_ACCESS_VIOLATION);
2250 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2251 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2257 SetLastError(CRYPT_E_ASN1_CORRUPT);
2260 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2262 SetLastError(CRYPT_E_ASN1_CORRUPT);
2265 if (pbEncoded[1] > 1)
2267 SetLastError(CRYPT_E_ASN1_CORRUPT);
2274 *pcbStructInfo = sizeof(BOOL);
2277 else if (*pcbStructInfo < sizeof(BOOL))
2279 *pcbStructInfo = sizeof(BOOL);
2280 SetLastError(ERROR_MORE_DATA);
2285 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2288 TRACE("returning %d (%08x)\n", ret, GetLastError());
2292 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2293 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2295 PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2296 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2299 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2300 pvStructInfo, *pcbStructInfo);
2304 SetLastError(CRYPT_E_ASN1_CORRUPT);
2307 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2308 if (1 + lenBytes > cbEncoded)
2310 SetLastError(CRYPT_E_ASN1_CORRUPT);
2313 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2315 switch (pbEncoded[0] & ASN_TYPE_MASK)
2317 case 1: /* rfc822Name */
2318 case 2: /* dNSName */
2319 case 6: /* uniformResourceIdentifier */
2320 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2322 case 4: /* directoryName */
2323 case 7: /* iPAddress */
2324 bytesNeeded += dataLen;
2326 case 8: /* registeredID */
2327 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2331 /* FIXME: ugly, shouldn't need to know internals of OID decode
2332 * function to use it.
2334 bytesNeeded += dataLen - sizeof(LPSTR);
2337 case 0: /* otherName */
2338 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2339 SetLastError(CRYPT_E_ASN1_BADTAG);
2342 case 3: /* x400Address, unimplemented */
2343 case 5: /* ediPartyName, unimplemented */
2344 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2345 SetLastError(CRYPT_E_ASN1_BADTAG);
2349 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2350 SetLastError(CRYPT_E_ASN1_CORRUPT);
2356 *pcbDecoded = 1 + lenBytes + dataLen;
2358 *pcbStructInfo = bytesNeeded;
2359 else if (*pcbStructInfo < bytesNeeded)
2361 *pcbStructInfo = bytesNeeded;
2362 SetLastError(ERROR_MORE_DATA);
2367 *pcbStructInfo = bytesNeeded;
2368 /* MS used values one greater than the asn1 ones.. sigh */
2369 entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
2370 switch (pbEncoded[0] & ASN_TYPE_MASK)
2372 case 1: /* rfc822Name */
2373 case 2: /* dNSName */
2374 case 6: /* uniformResourceIdentifier */
2378 for (i = 0; i < dataLen; i++)
2379 entry->u.pwszURL[i] =
2380 (WCHAR)pbEncoded[1 + lenBytes + i];
2381 entry->u.pwszURL[i] = 0;
2382 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2383 debugstr_w(entry->u.pwszURL));
2386 case 4: /* directoryName */
2387 entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
2388 /* The data are memory-equivalent with the IPAddress case,
2391 case 7: /* iPAddress */
2392 /* The next data pointer is in the pwszURL spot, that is,
2393 * the first 4 bytes. Need to move it to the next spot.
2395 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2396 entry->u.IPAddress.cbData = dataLen;
2397 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2400 case 8: /* registeredID */
2401 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2402 &entry->u.pszRegisteredID, &dataLen, NULL);
2411 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2412 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2416 struct AsnArrayDescriptor arrayDesc = { 0,
2417 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2418 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2419 PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2421 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2422 pvStructInfo, *pcbStructInfo, pcbDecoded);
2425 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2426 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2427 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2428 info ? info->rgAltEntry : NULL);
2432 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2433 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2434 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2439 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2440 pvStructInfo, *pcbStructInfo, pcbDecoded);
2442 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2445 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2446 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2448 if (ret && pvStructInfo)
2450 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2457 for (i = 0; i < blob->cbData / 2; i++)
2459 temp = blob->pbData[i];
2460 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2461 blob->pbData[blob->cbData - i - 1] = temp;
2465 TRACE("returning %d (%08x)\n", ret, GetLastError());
2469 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2470 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2471 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2477 struct AsnDecodeSequenceItem items[] = {
2478 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2479 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2480 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2481 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2482 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2483 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2484 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2485 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2486 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2487 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2488 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2491 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2492 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2493 pcbStructInfo, NULL, NULL);
2497 SetLastError(STATUS_ACCESS_VIOLATION);
2504 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2505 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2506 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2512 struct AsnDecodeSequenceItem items[] = {
2513 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2514 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2515 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2516 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2517 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2518 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2519 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2520 AuthorityCertIssuer.rgAltEntry), 0 },
2521 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2522 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2523 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2524 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2525 AuthorityCertSerialNumber.pbData), 0 },
2528 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2529 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2530 pcbStructInfo, NULL, NULL);
2534 SetLastError(STATUS_ACCESS_VIOLATION);
2541 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2542 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2547 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2548 pvStructInfo, *pcbStructInfo, pcbDecoded);
2550 /* The caller has already checked the tag, no need to check it again.
2551 * Check the outer length is valid:
2553 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2555 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2558 pbEncoded += 1 + lenBytes;
2559 cbEncoded -= 1 + lenBytes;
2560 if (dataLen == CMSG_INDEFINITE_LENGTH)
2561 cbEncoded -= 2; /* space for 0 TLV */
2562 /* Check the inner length is valid: */
2563 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2567 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2568 pvStructInfo, pcbStructInfo, &decodedLen);
2569 if (dataLen == CMSG_INDEFINITE_LENGTH)
2571 if (*(pbEncoded + decodedLen) != 0 ||
2572 *(pbEncoded + decodedLen + 1) != 0)
2574 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2575 *(pbEncoded + decodedLen),
2576 *(pbEncoded + decodedLen + 1));
2577 SetLastError(CRYPT_E_ASN1_CORRUPT);
2583 if (ret && pcbDecoded)
2585 *pcbDecoded = 1 + lenBytes + decodedLen;
2586 TRACE("decoded %d bytes\n", *pcbDecoded);
2593 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2594 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2597 CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2598 struct AsnDecodeSequenceItem items[] = {
2599 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2600 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2601 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2602 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2603 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2604 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2605 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2609 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2610 pvStructInfo, *pcbStructInfo, pcbDecoded);
2612 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2613 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2614 pcbDecoded, info ? info->pszObjId : NULL);
2618 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2619 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2620 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2624 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2625 pDecodePara, pvStructInfo, *pcbStructInfo);
2629 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2630 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2631 if (ret && pvStructInfo)
2633 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2634 pcbStructInfo, *pcbStructInfo);
2637 CRYPT_CONTENT_INFO *info;
2639 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2640 pvStructInfo = *(BYTE **)pvStructInfo;
2641 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2642 info->pszObjId = (LPSTR)((BYTE *)info +
2643 sizeof(CRYPT_CONTENT_INFO));
2644 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2645 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2646 pcbStructInfo, NULL);
2652 SetLastError(STATUS_ACCESS_VIOLATION);
2658 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2659 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2660 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2663 struct AsnDecodeSequenceItem items[] = {
2664 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2665 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2666 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2667 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2668 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2670 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2671 CRYPT_AsnDecodePKCSContentInfoInternal,
2672 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2673 ContentInfo.pszObjId), 0 },
2674 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2675 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2676 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2679 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2680 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2685 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2686 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2687 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2691 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2692 pDecodePara, pvStructInfo, *pcbStructInfo);
2698 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2699 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2702 *pcbStructInfo = bytesNeeded;
2703 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2704 pvStructInfo, pcbStructInfo, bytesNeeded)))
2706 CERT_ALT_NAME_INFO *name;
2708 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2709 pvStructInfo = *(BYTE **)pvStructInfo;
2710 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2711 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2712 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2713 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2714 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2715 &bytesNeeded, NULL);
2721 SetLastError(STATUS_ACCESS_VIOLATION);
2728 struct PATH_LEN_CONSTRAINT
2730 BOOL fPathLenConstraint;
2731 DWORD dwPathLenConstraint;
2734 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
2735 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2739 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
2741 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2742 pvStructInfo, *pcbStructInfo, pcbDecoded);
2746 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
2748 *pcbStructInfo = bytesNeeded;
2750 else if (*pcbStructInfo < bytesNeeded)
2752 SetLastError(ERROR_MORE_DATA);
2753 *pcbStructInfo = bytesNeeded;
2758 struct PATH_LEN_CONSTRAINT *constraint =
2759 (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
2761 size = sizeof(constraint->dwPathLenConstraint);
2762 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
2763 &constraint->dwPathLenConstraint, &size, pcbDecoded);
2765 constraint->fPathLenConstraint = TRUE;
2766 TRACE("got an int, dwPathLenConstraint is %d\n",
2767 constraint->dwPathLenConstraint);
2769 TRACE("returning %d (%08x)\n", ret, GetLastError());
2773 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
2774 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2778 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2779 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
2780 offsetof(CERT_NAME_BLOB, pbData) };
2781 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2783 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2784 pvStructInfo, *pcbStructInfo, pcbDecoded);
2786 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2787 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2788 entries ? entries->rgItems : NULL);
2789 TRACE("Returning %d (%08x)\n", ret, GetLastError());
2793 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
2794 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2795 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2801 struct AsnDecodeSequenceItem items[] = {
2802 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
2803 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2804 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
2805 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2806 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2807 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2808 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2809 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
2810 sizeof(struct GenericArray), TRUE, TRUE,
2811 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
2814 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2815 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2816 pcbStructInfo, NULL, NULL);
2820 SetLastError(STATUS_ACCESS_VIOLATION);
2827 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
2828 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2829 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2835 struct AsnDecodeSequenceItem items[] = {
2836 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
2837 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
2838 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
2839 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2840 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2843 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2844 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2845 pcbStructInfo, NULL, NULL);
2849 SetLastError(STATUS_ACCESS_VIOLATION);
2856 #define RSA1_MAGIC 0x31415352
2858 struct DECODED_RSA_PUB_KEY
2861 CRYPT_INTEGER_BLOB modulus;
2864 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
2865 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2866 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2872 struct AsnDecodeSequenceItem items[] = {
2873 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
2874 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2875 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
2877 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
2878 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2880 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
2883 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2884 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
2888 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2889 decodedKey->modulus.cbData;
2893 *pcbStructInfo = bytesNeeded;
2896 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2897 pvStructInfo, pcbStructInfo, bytesNeeded)))
2900 RSAPUBKEY *rsaPubKey;
2902 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2903 pvStructInfo = *(BYTE **)pvStructInfo;
2904 hdr = (BLOBHEADER *)pvStructInfo;
2905 hdr->bType = PUBLICKEYBLOB;
2906 hdr->bVersion = CUR_BLOB_VERSION;
2908 hdr->aiKeyAlg = CALG_RSA_KEYX;
2909 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
2910 sizeof(BLOBHEADER));
2911 rsaPubKey->magic = RSA1_MAGIC;
2912 rsaPubKey->pubexp = decodedKey->pubexp;
2913 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
2914 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
2915 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
2916 decodedKey->modulus.cbData);
2918 LocalFree(decodedKey);
2923 SetLastError(STATUS_ACCESS_VIOLATION);
2930 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
2931 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2935 DWORD bytesNeeded, dataLen;
2937 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2938 pvStructInfo, *pcbStructInfo, pcbDecoded);
2940 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2942 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2944 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2945 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
2947 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
2949 *pcbDecoded = 1 + lenBytes + dataLen;
2951 *pcbStructInfo = bytesNeeded;
2952 else if (*pcbStructInfo < bytesNeeded)
2954 SetLastError(ERROR_MORE_DATA);
2955 *pcbStructInfo = bytesNeeded;
2960 CRYPT_DATA_BLOB *blob;
2962 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2963 blob->cbData = dataLen;
2964 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2965 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
2968 assert(blob->pbData);
2970 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
2978 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
2979 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2980 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2984 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2985 pDecodePara, pvStructInfo, *pcbStructInfo);
2993 SetLastError(CRYPT_E_ASN1_CORRUPT);
2996 else if (pbEncoded[0] != ASN_OCTETSTRING)
2998 SetLastError(CRYPT_E_ASN1_BADTAG);
3001 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3002 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3005 *pcbStructInfo = bytesNeeded;
3006 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3007 pvStructInfo, pcbStructInfo, bytesNeeded)))
3009 CRYPT_DATA_BLOB *blob;
3011 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3012 pvStructInfo = *(BYTE **)pvStructInfo;
3013 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3014 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3015 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3016 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3017 &bytesNeeded, NULL);
3023 SetLastError(STATUS_ACCESS_VIOLATION);
3030 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3031 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3035 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3036 pvStructInfo, *pcbStructInfo, pcbDecoded);
3038 if (pbEncoded[0] == ASN_BITSTRING)
3040 DWORD bytesNeeded, dataLen;
3041 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3043 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3045 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3046 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3048 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3050 *pcbDecoded = 1 + lenBytes + dataLen;
3052 *pcbStructInfo = bytesNeeded;
3053 else if (*pcbStructInfo < bytesNeeded)
3055 *pcbStructInfo = bytesNeeded;
3056 SetLastError(ERROR_MORE_DATA);
3061 CRYPT_BIT_BLOB *blob;
3063 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3064 blob->cbData = dataLen - 1;
3065 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3066 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3068 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3072 assert(blob->pbData);
3075 BYTE mask = 0xff << blob->cUnusedBits;
3077 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3079 blob->pbData[blob->cbData - 1] &= mask;
3087 SetLastError(CRYPT_E_ASN1_BADTAG);
3090 TRACE("returning %d (%08x)\n", ret, GetLastError());
3094 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3095 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3096 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3100 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3101 pDecodePara, pvStructInfo, pcbStructInfo);
3107 if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3108 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3111 *pcbStructInfo = bytesNeeded;
3112 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3113 pvStructInfo, pcbStructInfo, bytesNeeded)))
3115 CRYPT_BIT_BLOB *blob;
3117 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3118 pvStructInfo = *(BYTE **)pvStructInfo;
3119 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3120 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3121 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3122 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3123 &bytesNeeded, NULL);
3129 SetLastError(STATUS_ACCESS_VIOLATION);
3133 TRACE("returning %d (%08x)\n", ret, GetLastError());
3137 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3138 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3139 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3142 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3143 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3144 DWORD size = sizeof(buf);
3146 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3147 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, &buf,
3152 *pcbStructInfo = sizeof(int);
3153 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3157 if (blob->pbData[blob->cbData - 1] & 0x80)
3159 /* initialize to a negative value to sign-extend */
3164 for (i = 0; i < blob->cbData; i++)
3167 val |= blob->pbData[blob->cbData - i - 1];
3169 memcpy(pvStructInfo, &val, sizeof(int));
3172 else if (GetLastError() == ERROR_MORE_DATA)
3173 SetLastError(CRYPT_E_ASN1_LARGE);
3177 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3178 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3179 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3189 SetLastError(CRYPT_E_ASN1_CORRUPT);
3192 else if (pbEncoded[0] != ASN_INTEGER)
3194 SetLastError(CRYPT_E_ASN1_BADTAG);
3198 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3199 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3203 *pcbStructInfo = bytesNeeded;
3204 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3205 pvStructInfo, pcbStructInfo, bytesNeeded)))
3207 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3208 pvStructInfo = *(BYTE **)pvStructInfo;
3209 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3210 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3211 &bytesNeeded, NULL);
3217 SetLastError(STATUS_ACCESS_VIOLATION);
3224 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3225 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3229 DWORD bytesNeeded, dataLen;
3231 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3233 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3235 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3237 *pcbDecoded = 1 + lenBytes + dataLen;
3239 *pcbStructInfo = bytesNeeded;
3240 else if (*pcbStructInfo < bytesNeeded)
3242 *pcbStructInfo = bytesNeeded;
3243 SetLastError(ERROR_MORE_DATA);
3248 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3250 blob->cbData = dataLen;
3251 assert(blob->pbData);
3256 for (i = 0; i < blob->cbData; i++)
3258 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3267 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
3268 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3269 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3277 if (pbEncoded[0] != ASN_INTEGER)
3279 SetLastError(CRYPT_E_ASN1_BADTAG);
3283 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3284 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3288 *pcbStructInfo = bytesNeeded;
3289 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3290 pvStructInfo, pcbStructInfo, bytesNeeded)))
3292 CRYPT_INTEGER_BLOB *blob;
3294 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3295 pvStructInfo = *(BYTE **)pvStructInfo;
3296 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3297 blob->pbData = (BYTE *)pvStructInfo +
3298 sizeof(CRYPT_INTEGER_BLOB);
3299 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3300 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3301 &bytesNeeded, NULL);
3307 SetLastError(STATUS_ACCESS_VIOLATION);
3314 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
3315 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3320 if (pbEncoded[0] == ASN_INTEGER)
3322 DWORD bytesNeeded, dataLen;
3324 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3326 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3329 *pcbDecoded = 1 + lenBytes + dataLen;
3330 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3332 *pcbStructInfo = bytesNeeded;
3333 else if (*pcbStructInfo < bytesNeeded)
3335 *pcbStructInfo = bytesNeeded;
3336 SetLastError(ERROR_MORE_DATA);
3341 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3343 blob->cbData = dataLen;
3344 assert(blob->pbData);
3345 /* remove leading zero byte if it exists */
3346 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
3355 for (i = 0; i < blob->cbData; i++)
3357 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3366 SetLastError(CRYPT_E_ASN1_BADTAG);
3372 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
3373 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3374 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3382 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
3383 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3386 *pcbStructInfo = bytesNeeded;
3387 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3388 pvStructInfo, pcbStructInfo, bytesNeeded)))
3390 CRYPT_INTEGER_BLOB *blob;
3392 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3393 pvStructInfo = *(BYTE **)pvStructInfo;
3394 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3395 blob->pbData = (BYTE *)pvStructInfo +
3396 sizeof(CRYPT_INTEGER_BLOB);
3397 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
3398 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3399 &bytesNeeded, NULL);
3405 SetLastError(STATUS_ACCESS_VIOLATION);
3412 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
3413 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3414 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3420 *pcbStructInfo = sizeof(int);
3425 if (pbEncoded[0] == ASN_ENUMERATED)
3427 unsigned int val = 0, i;
3431 SetLastError(CRYPT_E_ASN1_EOD);
3434 else if (pbEncoded[1] == 0)
3436 SetLastError(CRYPT_E_ASN1_CORRUPT);
3441 /* A little strange looking, but we have to accept a sign byte:
3442 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3443 * assuming a small length is okay here, it has to be in short
3446 if (pbEncoded[1] > sizeof(unsigned int) + 1)
3448 SetLastError(CRYPT_E_ASN1_LARGE);
3451 for (i = 0; i < pbEncoded[1]; i++)
3454 val |= pbEncoded[2 + i];
3456 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3457 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
3459 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3460 pvStructInfo = *(BYTE **)pvStructInfo;
3461 memcpy(pvStructInfo, &val, sizeof(unsigned int));
3467 SetLastError(CRYPT_E_ASN1_BADTAG);
3473 SetLastError(STATUS_ACCESS_VIOLATION);
3480 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3483 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3488 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3490 if (!isdigit(*(pbEncoded))) \
3492 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3498 (word) += *(pbEncoded)++ - '0'; \
3503 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
3504 SYSTEMTIME *sysTime)
3508 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
3510 WORD hours, minutes = 0;
3511 BYTE sign = *pbEncoded++;
3514 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
3515 if (ret && hours >= 24)
3517 SetLastError(CRYPT_E_ASN1_CORRUPT);
3522 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
3523 if (ret && minutes >= 60)
3525 SetLastError(CRYPT_E_ASN1_CORRUPT);
3533 sysTime->wHour += hours;
3534 sysTime->wMinute += minutes;
3538 if (hours > sysTime->wHour)
3541 sysTime->wHour = 24 - (hours - sysTime->wHour);
3544 sysTime->wHour -= hours;
3545 if (minutes > sysTime->wMinute)
3548 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
3551 sysTime->wMinute -= minutes;
3558 #define MIN_ENCODED_TIME_LENGTH 10
3560 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
3561 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3566 if (pbEncoded[0] == ASN_UTCTIME)
3569 SetLastError(CRYPT_E_ASN1_EOD);
3570 else if (pbEncoded[1] > 0x7f)
3572 /* long-form date strings really can't be valid */
3573 SetLastError(CRYPT_E_ASN1_CORRUPT);
3577 SYSTEMTIME sysTime = { 0 };
3578 BYTE len = pbEncoded[1];
3580 if (len < MIN_ENCODED_TIME_LENGTH)
3581 SetLastError(CRYPT_E_ASN1_CORRUPT);
3586 *pcbDecoded = 2 + len;
3588 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
3589 if (sysTime.wYear >= 50)
3590 sysTime.wYear += 1900;
3592 sysTime.wYear += 2000;
3593 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3594 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3595 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3596 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
3599 if (len >= 2 && isdigit(*pbEncoded) &&
3600 isdigit(*(pbEncoded + 1)))
3601 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3603 else if (isdigit(*pbEncoded))
3604 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
3607 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3613 *pcbStructInfo = sizeof(FILETIME);
3614 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3616 ret = SystemTimeToFileTime(&sysTime,
3617 (FILETIME *)pvStructInfo);
3623 SetLastError(CRYPT_E_ASN1_BADTAG);
3627 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
3628 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3629 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3637 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3638 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3642 *pcbStructInfo = bytesNeeded;
3643 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
3644 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
3646 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3647 pvStructInfo = *(BYTE **)pvStructInfo;
3648 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3649 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3650 &bytesNeeded, NULL);
3656 SetLastError(STATUS_ACCESS_VIOLATION);
3662 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
3663 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3668 if (pbEncoded[0] == ASN_GENERALTIME)
3671 SetLastError(CRYPT_E_ASN1_EOD);
3672 else if (pbEncoded[1] > 0x7f)
3674 /* long-form date strings really can't be valid */
3675 SetLastError(CRYPT_E_ASN1_CORRUPT);
3679 BYTE len = pbEncoded[1];
3681 if (len < MIN_ENCODED_TIME_LENGTH)
3682 SetLastError(CRYPT_E_ASN1_CORRUPT);
3685 SYSTEMTIME sysTime = { 0 };
3689 *pcbDecoded = 2 + len;
3691 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
3692 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3693 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3694 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3697 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3700 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3702 if (ret && len > 0 && (*pbEncoded == '.' ||
3709 /* workaround macro weirdness */
3710 digits = min(len, 3);
3711 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
3712 sysTime.wMilliseconds);
3715 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3721 *pcbStructInfo = sizeof(FILETIME);
3722 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3724 ret = SystemTimeToFileTime(&sysTime,
3725 (FILETIME *)pvStructInfo);
3731 SetLastError(CRYPT_E_ASN1_BADTAG);
3735 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
3736 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3740 InternalDecodeFunc decode = NULL;
3742 if (pbEncoded[0] == ASN_UTCTIME)
3743 decode = CRYPT_AsnDecodeUtcTimeInternal;
3744 else if (pbEncoded[0] == ASN_GENERALTIME)
3745 decode = CRYPT_AsnDecodeGeneralizedTime;
3747 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
3748 pcbStructInfo, pcbDecoded);
3751 SetLastError(CRYPT_E_ASN1_BADTAG);
3757 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
3758 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3759 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3767 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3768 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3772 *pcbStructInfo = bytesNeeded;
3773 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3774 pvStructInfo, pcbStructInfo, bytesNeeded)))
3776 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3777 pvStructInfo = *(BYTE **)pvStructInfo;
3778 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3779 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3780 &bytesNeeded, NULL);
3786 SetLastError(STATUS_ACCESS_VIOLATION);
3793 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
3794 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3795 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3801 if (pbEncoded[0] == ASN_SEQUENCEOF)
3803 DWORD bytesNeeded, dataLen, remainingLen, cValue;
3805 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3810 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3811 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
3813 ptr = pbEncoded + 1 + lenBytes;
3814 remainingLen = dataLen;
3815 while (ret && remainingLen)
3819 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3822 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3824 remainingLen -= 1 + nextLenBytes + nextLen;
3825 ptr += 1 + nextLenBytes + nextLen;
3826 bytesNeeded += sizeof(CRYPT_DER_BLOB);
3827 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
3828 bytesNeeded += 1 + nextLenBytes + nextLen;
3834 CRYPT_SEQUENCE_OF_ANY *seq;
3838 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3839 pvStructInfo, pcbStructInfo, bytesNeeded)))
3841 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3842 pvStructInfo = *(BYTE **)pvStructInfo;
3843 seq = (CRYPT_SEQUENCE_OF_ANY *)pvStructInfo;
3844 seq->cValue = cValue;
3845 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
3847 nextPtr = (BYTE *)seq->rgValue +
3848 cValue * sizeof(CRYPT_DER_BLOB);
3849 ptr = pbEncoded + 1 + lenBytes;
3850 remainingLen = dataLen;
3852 while (ret && remainingLen)
3856 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3859 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3861 seq->rgValue[i].cbData = 1 + nextLenBytes +
3863 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3864 seq->rgValue[i].pbData = (BYTE *)ptr;
3867 seq->rgValue[i].pbData = nextPtr;
3868 memcpy(nextPtr, ptr, 1 + nextLenBytes +
3870 nextPtr += 1 + nextLenBytes + nextLen;
3872 remainingLen -= 1 + nextLenBytes + nextLen;
3873 ptr += 1 + nextLenBytes + nextLen;
3883 SetLastError(CRYPT_E_ASN1_BADTAG);
3889 SetLastError(STATUS_ACCESS_VIOLATION);
3896 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
3897 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3902 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
3904 DWORD bytesNeeded, dataLen;
3906 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3908 struct AsnArrayDescriptor arrayDesc = {
3909 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
3910 sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3911 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3912 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3918 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3919 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3920 0, NULL, NULL, &nameLen, NULL, NULL);
3921 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen;
3924 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
3926 *pcbDecoded = 1 + lenBytes + dataLen;
3928 *pcbStructInfo = bytesNeeded;
3929 else if (*pcbStructInfo < bytesNeeded)
3931 *pcbStructInfo = bytesNeeded;
3932 SetLastError(ERROR_MORE_DATA);
3937 CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
3941 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3942 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3943 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3944 0, NULL, &name->u.FullName, pcbStructInfo, NULL,
3945 name->u.FullName.rgAltEntry);
3948 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3954 SetLastError(CRYPT_E_ASN1_BADTAG);
3960 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
3961 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3963 struct AsnDecodeSequenceItem items[] = {
3964 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
3965 DistPointName), CRYPT_AsnDecodeDistPointName,
3966 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
3967 DistPointName.u.FullName.rgAltEntry), 0 },
3968 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
3969 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
3970 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
3971 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
3972 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
3973 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
3977 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3978 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3983 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
3984 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3985 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3989 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3990 pDecodePara, pvStructInfo, *pcbStructInfo);
3994 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3995 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
3996 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
3998 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3999 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4003 SetLastError(STATUS_ACCESS_VIOLATION);
4010 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4011 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4012 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4016 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4017 pDecodePara, pvStructInfo, *pcbStructInfo);
4021 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4022 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4024 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4025 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4029 SetLastError(STATUS_ACCESS_VIOLATION);
4036 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4037 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4038 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4042 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4043 pDecodePara, pvStructInfo, *pcbStructInfo);
4047 struct AsnDecodeSequenceItem items[] = {
4048 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4049 DistPointName), CRYPT_AsnDecodeDistPointName,
4050 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4051 offsetof(CRL_ISSUING_DIST_POINT,
4052 DistPointName.u.FullName.rgAltEntry), 0 },
4053 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4054 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4056 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4057 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4059 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4060 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4061 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4062 OnlySomeReasonFlags.pbData), 0 },
4063 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4064 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4067 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4068 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4069 pcbStructInfo, NULL, NULL);
4073 SetLastError(STATUS_ACCESS_VIOLATION);
4080 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4081 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4086 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4087 pvStructInfo, *pcbStructInfo, pcbDecoded);
4091 SetLastError(CRYPT_E_ASN1_EOD);
4094 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4096 SetLastError(CRYPT_E_ASN1_BADTAG);
4099 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4100 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4101 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4103 if (ret && pvStructInfo)
4104 *(BOOL *)pvStructInfo = TRUE;
4105 TRACE("returning %d\n", ret);
4109 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4110 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4114 struct AsnDecodeSequenceItem items[] = {
4115 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4116 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4117 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4118 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4119 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4120 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4121 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4124 CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)pvStructInfo;
4126 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4127 pvStructInfo, *pcbStructInfo, pcbDecoded);
4129 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4130 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4131 pcbDecoded, subtree ? (BYTE *)subtree->Base.u.pwszURL : NULL);
4134 TRACE("%d\n", *pcbDecoded);
4135 if (*pcbDecoded < cbEncoded)
4136 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4137 *(pbEncoded + *pcbDecoded + 1));
4139 TRACE("returning %d\n", ret);
4143 static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
4144 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4148 struct AsnArrayDescriptor arrayDesc = { 0,
4149 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4150 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4151 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4153 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4154 pvStructInfo, *pcbStructInfo, pcbDecoded);
4156 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4157 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4158 array ? array->rgItems : NULL);
4163 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4164 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4165 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4169 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4170 pDecodePara, pvStructInfo, *pcbStructInfo);
4174 struct AsnDecodeSequenceItem items[] = {
4175 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4176 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4177 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4178 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4179 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4180 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4181 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4182 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4185 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4186 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4187 pcbStructInfo, NULL, NULL);
4191 SetLastError(STATUS_ACCESS_VIOLATION);
4197 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
4198 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4202 struct AsnDecodeSequenceItem items[] = {
4203 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
4204 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
4206 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
4207 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
4208 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
4210 CERT_ISSUER_SERIAL_NUMBER *issuerSerial =
4211 (CERT_ISSUER_SERIAL_NUMBER *)pvStructInfo;
4213 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4214 pvStructInfo, *pcbStructInfo, pcbDecoded);
4216 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4217 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4218 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
4219 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
4221 SetLastError(CRYPT_E_ASN1_CORRUPT);
4224 TRACE("returning %d\n", ret);
4228 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
4229 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4232 CMSG_SIGNER_INFO *info = (CMSG_SIGNER_INFO *)pvStructInfo;
4233 struct AsnDecodeSequenceItem items[] = {
4234 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
4235 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4236 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
4237 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
4238 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
4239 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
4240 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4241 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4242 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4243 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
4244 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4245 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4246 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
4247 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4248 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
4249 HashEncryptionAlgorithm.pszObjId), 0 },
4250 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
4251 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4252 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
4253 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4254 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
4255 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4256 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4260 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4261 pvStructInfo, *pcbStructInfo);
4263 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4264 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4265 pcbDecoded, info ? info->Issuer.pbData : NULL);
4269 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
4270 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4271 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4275 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4276 pDecodePara, pvStructInfo, *pcbStructInfo);
4280 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
4281 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4282 if (ret && pvStructInfo)
4284 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4285 pcbStructInfo, *pcbStructInfo);
4288 CMSG_SIGNER_INFO *info;
4290 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4291 pvStructInfo = *(BYTE **)pvStructInfo;
4292 info = (CMSG_SIGNER_INFO *)pvStructInfo;
4293 info->Issuer.pbData = ((BYTE *)info +
4294 sizeof(CMSG_SIGNER_INFO));
4295 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
4296 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4297 pcbStructInfo, NULL);
4303 SetLastError(STATUS_ACCESS_VIOLATION);
4306 TRACE("returning %d\n", ret);
4310 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
4311 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4314 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
4315 CRYPT_AsnDecodePKCSSignerInfoInternal, sizeof(CMSG_SIGNER_INFO), TRUE,
4316 offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
4317 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4319 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4320 pvStructInfo, *pcbStructInfo, pcbDecoded);
4322 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4323 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4324 array ? array->rgItems : NULL);
4328 BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
4329 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
4330 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
4333 struct AsnDecodeSequenceItem items[] = {
4334 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
4335 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4336 /* Placeholder for the hash algorithms - redundant with those in the
4337 * signers, so just ignore them.
4339 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
4340 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
4341 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
4342 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
4343 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4344 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
4345 CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
4346 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
4347 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4348 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
4349 sizeof(struct GenericArray), TRUE, TRUE,
4350 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
4351 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
4352 CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
4353 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
4356 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4357 pDecodePara, signedInfo, *pcbSignedInfo);
4359 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4360 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
4362 TRACE("returning %d\n", ret);
4366 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
4367 LPCSTR lpszStructType)
4369 CryptDecodeObjectExFunc decodeFunc = NULL;
4371 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
4372 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
4374 SetLastError(ERROR_FILE_NOT_FOUND);
4377 if (!HIWORD(lpszStructType))
4379 switch (LOWORD(lpszStructType))
4381 case LOWORD(X509_CERT):
4382 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
4384 case LOWORD(X509_CERT_TO_BE_SIGNED):
4385 decodeFunc = CRYPT_AsnDecodeCert;
4387 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
4388 decodeFunc = CRYPT_AsnDecodeCRL;
4390 case LOWORD(X509_EXTENSIONS):
4391 decodeFunc = CRYPT_AsnDecodeExtensions;
4393 case LOWORD(X509_NAME_VALUE):
4394 decodeFunc = CRYPT_AsnDecodeNameValue;
4396 case LOWORD(X509_NAME):
4397 decodeFunc = CRYPT_AsnDecodeName;
4399 case LOWORD(X509_PUBLIC_KEY_INFO):
4400 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
4402 case LOWORD(X509_AUTHORITY_KEY_ID):
4403 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4405 case LOWORD(X509_ALTERNATE_NAME):
4406 decodeFunc = CRYPT_AsnDecodeAltName;
4408 case LOWORD(X509_BASIC_CONSTRAINTS):
4409 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4411 case LOWORD(X509_BASIC_CONSTRAINTS2):
4412 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4414 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
4415 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
4417 case LOWORD(X509_UNICODE_NAME):
4418 decodeFunc = CRYPT_AsnDecodeUnicodeName;
4420 case LOWORD(PKCS_ATTRIBUTE):
4421 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
4423 case LOWORD(X509_UNICODE_NAME_VALUE):
4424 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
4426 case LOWORD(X509_OCTET_STRING):
4427 decodeFunc = CRYPT_AsnDecodeOctets;
4429 case LOWORD(X509_BITS):
4430 case LOWORD(X509_KEY_USAGE):
4431 decodeFunc = CRYPT_AsnDecodeBits;
4433 case LOWORD(X509_INTEGER):
4434 decodeFunc = CRYPT_AsnDecodeInt;
4436 case LOWORD(X509_MULTI_BYTE_INTEGER):
4437 decodeFunc = CRYPT_AsnDecodeInteger;
4439 case LOWORD(X509_MULTI_BYTE_UINT):
4440 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
4442 case LOWORD(X509_ENUMERATED):
4443 decodeFunc = CRYPT_AsnDecodeEnumerated;
4445 case LOWORD(X509_CHOICE_OF_TIME):
4446 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
4448 case LOWORD(X509_AUTHORITY_KEY_ID2):
4449 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4451 case LOWORD(PKCS_CONTENT_INFO):
4452 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
4454 case LOWORD(X509_SEQUENCE_OF_ANY):
4455 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
4457 case LOWORD(PKCS_UTC_TIME):
4458 decodeFunc = CRYPT_AsnDecodeUtcTime;
4460 case LOWORD(X509_CRL_DIST_POINTS):
4461 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4463 case LOWORD(X509_ENHANCED_KEY_USAGE):
4464 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4466 case LOWORD(PKCS_ATTRIBUTES):
4467 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
4469 case LOWORD(X509_ISSUING_DIST_POINT):
4470 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4472 case LOWORD(X509_NAME_CONSTRAINTS):
4473 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4475 case LOWORD(PKCS7_SIGNER_INFO):
4476 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
4480 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
4481 decodeFunc = CRYPT_AsnDecodeExtensions;
4482 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
4483 decodeFunc = CRYPT_AsnDecodeUtcTime;
4484 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
4485 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4486 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
4487 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4488 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
4489 decodeFunc = CRYPT_AsnDecodeEnumerated;
4490 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
4491 decodeFunc = CRYPT_AsnDecodeBits;
4492 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
4493 decodeFunc = CRYPT_AsnDecodeOctets;
4494 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
4495 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4496 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
4497 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4498 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
4499 decodeFunc = CRYPT_AsnDecodeAltName;
4500 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
4501 decodeFunc = CRYPT_AsnDecodeAltName;
4502 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
4503 decodeFunc = CRYPT_AsnDecodeAltName;
4504 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
4505 decodeFunc = CRYPT_AsnDecodeAltName;
4506 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
4507 decodeFunc = CRYPT_AsnDecodeAltName;
4508 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
4509 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4510 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
4511 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4512 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
4513 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4514 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
4515 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4519 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
4520 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4522 static HCRYPTOIDFUNCSET set = NULL;
4523 CryptDecodeObjectFunc decodeFunc = NULL;
4526 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
4527 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4528 (void **)&decodeFunc, hFunc);
4532 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
4533 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4535 static HCRYPTOIDFUNCSET set = NULL;
4536 CryptDecodeObjectExFunc decodeFunc = NULL;
4539 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
4540 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4541 (void **)&decodeFunc, hFunc);
4545 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4546 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
4547 DWORD *pcbStructInfo)
4550 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
4551 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
4552 HCRYPTOIDFUNCADDR hFunc = NULL;
4554 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
4555 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
4556 pvStructInfo, pcbStructInfo);
4558 if (!pvStructInfo && !pcbStructInfo)
4560 SetLastError(ERROR_INVALID_PARAMETER);
4565 SetLastError(CRYPT_E_ASN1_EOD);
4568 if (cbEncoded > MAX_ENCODED_LEN)
4570 SetLastError(CRYPT_E_ASN1_LARGE);
4574 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
4577 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4578 debugstr_a(lpszStructType));
4579 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
4580 lpszStructType, &hFunc);
4581 if (!pCryptDecodeObject)
4582 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
4583 lpszStructType, &hFunc);
4585 if (pCryptDecodeObject)
4586 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4587 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4588 else if (pCryptDecodeObjectEx)
4589 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
4590 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
4591 pvStructInfo, pcbStructInfo);
4593 CryptFreeOIDFunctionAddress(hFunc, 0);
4594 TRACE_(crypt)("returning %d\n", ret);
4598 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4599 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4600 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4603 CryptDecodeObjectExFunc decodeFunc;
4604 HCRYPTOIDFUNCADDR hFunc = NULL;
4606 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4607 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
4608 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4610 if (!pvStructInfo && !pcbStructInfo)
4612 SetLastError(ERROR_INVALID_PARAMETER);
4617 SetLastError(CRYPT_E_ASN1_EOD);
4620 if (cbEncoded > MAX_ENCODED_LEN)
4622 SetLastError(CRYPT_E_ASN1_LARGE);
4626 SetLastError(NOERROR);
4627 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
4628 *(BYTE **)pvStructInfo = NULL;
4629 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
4632 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4633 debugstr_a(lpszStructType));
4634 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
4638 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
4639 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4642 CryptDecodeObjectFunc pCryptDecodeObject =
4643 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
4645 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4646 * directly, as that could cause an infinite loop.
4648 if (pCryptDecodeObject)
4650 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4652 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4653 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
4654 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4655 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
4656 ret = pCryptDecodeObject(dwCertEncodingType,
4657 lpszStructType, pbEncoded, cbEncoded, dwFlags,
4658 *(BYTE **)pvStructInfo, pcbStructInfo);
4661 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4662 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4666 CryptFreeOIDFunctionAddress(hFunc, 0);
4667 TRACE_(crypt)("returning %d\n", ret);