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 /* Helper function to check *pcbStructInfo and set it to the required size.
235 * Assumes pvStructInfo is not NULL.
237 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
241 if (*pcbStructInfo < bytesNeeded)
243 *pcbStructInfo = bytesNeeded;
244 SetLastError(ERROR_MORE_DATA);
249 *pcbStructInfo = bytesNeeded;
256 * The expected tag of the item. If tag is 0, decodeFunc is called
257 * regardless of the tag value seen.
259 * A sequence is decoded into a struct. The offset member is the
260 * offset of this item within that struct.
262 * The decoder function to use. If this is NULL, then the member isn't
263 * decoded, but minSize space is reserved for it.
265 * The minimum amount of space occupied after decoding. You must set this.
267 * If true, and the tag doesn't match the expected tag for this item,
268 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
269 * filled with 0 for this member.
270 * hasPointer, pointerOffset:
271 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
272 * the offset within the struct of the data pointer (or to the
273 * first data pointer, if more than one exist).
275 * Used by CRYPT_AsnDecodeSequence, not for your use.
277 struct AsnDecodeSequenceItem
281 InternalDecodeFunc decodeFunc;
289 /* Decodes the items in a sequence, where the items are described in items,
290 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
291 * pvStructInfo. nextData is a pointer to the memory location at which the
292 * first decoded item with a dynamic pointer should point.
293 * Upon decoding, *cbDecoded is the total number of bytes decoded.
294 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
296 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
297 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
298 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
301 DWORD i, decoded = 0;
302 const BYTE *ptr = pbEncoded;
304 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
305 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
307 for (i = 0, ret = TRUE; ret && i < cItem; i++)
309 if (cbEncoded - (ptr - pbEncoded) != 0)
313 if ((ret = CRYPT_GetLengthIndefinite(ptr,
314 cbEncoded - (ptr - pbEncoded), &itemLen)))
316 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
318 if (ptr[0] == items[i].tag || !items[i].tag)
320 DWORD itemEncodedLen;
322 if (itemLen == CMSG_INDEFINITE_LENGTH)
323 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
325 itemEncodedLen = 1 + itemLenBytes + itemLen;
326 if (nextData && pvStructInfo && items[i].hasPointer)
328 TRACE("Setting next pointer to %p\n",
330 *(BYTE **)((BYTE *)pvStructInfo +
331 items[i].pointerOffset) = nextData;
333 if (items[i].decodeFunc)
338 TRACE("decoding item %d\n", i);
340 TRACE("sizing item %d\n", i);
341 ret = items[i].decodeFunc(ptr, itemEncodedLen,
342 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
343 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
344 : NULL, &items[i].size, &itemDecoded);
347 /* Account for alignment padding */
348 if (items[i].size % sizeof(DWORD_PTR))
349 items[i].size += sizeof(DWORD_PTR) -
350 items[i].size % sizeof(DWORD_PTR);
351 TRACE("item %d size: %d\n", i, items[i].size);
352 if (nextData && items[i].hasPointer &&
353 items[i].size > items[i].minSize)
354 nextData += items[i].size - items[i].minSize;
355 if (itemDecoded > itemEncodedLen)
357 WARN("decoded length %d exceeds encoded %d\n",
358 itemDecoded, itemEncodedLen);
359 SetLastError(CRYPT_E_ASN1_CORRUPT);
364 if (itemLen == CMSG_INDEFINITE_LENGTH)
366 if (itemDecoded > itemEncodedLen - 2 ||
367 *(ptr + itemDecoded) != 0 ||
368 *(ptr + itemDecoded + 1) != 0)
370 TRACE("expected 0 TLV\n");
371 SetLastError(CRYPT_E_ASN1_CORRUPT);
380 decoded += itemDecoded;
381 TRACE("item %d: decoded %d bytes\n", i,
386 else if (items[i].optional &&
387 GetLastError() == CRYPT_E_ASN1_BADTAG)
389 TRACE("skipping optional item %d\n", i);
390 items[i].size = items[i].minSize;
391 SetLastError(NOERROR);
395 TRACE("item %d failed: %08x\n", i,
398 else if (itemLen == CMSG_INDEFINITE_LENGTH)
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT);
406 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
407 ptr += itemEncodedLen;
408 decoded += itemEncodedLen;
409 items[i].size = items[i].minSize;
412 else if (items[i].optional)
414 TRACE("skipping optional item %d\n", i);
415 items[i].size = items[i].minSize;
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i, ptr[0], items[i].tag);
421 SetLastError(CRYPT_E_ASN1_BADTAG);
426 else if (items[i].optional)
428 TRACE("missing optional item %d, skipping\n", i);
429 items[i].size = items[i].minSize;
433 TRACE("not enough bytes for item %d, failing\n", i);
434 SetLastError(CRYPT_E_ASN1_CORRUPT);
439 *cbDecoded = decoded;
440 TRACE("returning %d\n", ret);
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
451 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
452 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
454 DWORD *pcbDecoded, void *startingPointer)
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
459 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
462 if (pbEncoded[0] == ASN_SEQUENCE)
466 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
468 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
469 const BYTE *ptr = pbEncoded + 1 + lenBytes;
470 BOOL indefinite = FALSE;
472 cbEncoded -= 1 + lenBytes;
473 if (dataLen == CMSG_INDEFINITE_LENGTH)
478 else if (cbEncoded < dataLen)
480 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
482 SetLastError(CRYPT_E_ASN1_CORRUPT);
487 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
488 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
489 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
491 if (cbDecoded > cbEncoded - 2)
493 /* Not enough space for 0 TLV */
494 SetLastError(CRYPT_E_ASN1_CORRUPT);
497 else if (*(ptr + cbDecoded) != 0 ||
498 *(ptr + cbDecoded + 1) != 0)
500 TRACE("expected 0 TLV\n");
501 SetLastError(CRYPT_E_ASN1_CORRUPT);
508 if (ret && !indefinite && cbDecoded != dataLen)
510 TRACE("expected %d decoded, got %d, failing\n", dataLen,
512 SetLastError(CRYPT_E_ASN1_CORRUPT);
517 DWORD i, bytesNeeded = 0, structSize = 0;
519 for (i = 0; i < cItem; i++)
521 bytesNeeded += items[i].size;
522 structSize += items[i].minSize;
525 *pcbDecoded = 1 + lenBytes + cbDecoded;
527 *pcbStructInfo = bytesNeeded;
528 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
529 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
533 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
534 pvStructInfo = *(BYTE **)pvStructInfo;
536 nextData = (BYTE *)startingPointer;
538 nextData = (BYTE *)pvStructInfo + structSize;
539 memset(pvStructInfo, 0, structSize);
540 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
541 ptr, dataLen, dwFlags, pvStructInfo, nextData,
549 SetLastError(CRYPT_E_ASN1_BADTAG);
552 TRACE("returning %d (%08x)\n", ret, GetLastError());
557 * The expected tag of the entire encoded array (usually a variant
558 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
559 * regardless of the tag seen.
561 * used to decode each item in the array
563 * is the minimum size of each decoded item
565 * indicates whether each item has a dynamic pointer
567 * indicates the offset within itemSize at which the pointer exists
569 struct AsnArrayDescriptor
572 InternalDecodeFunc decodeFunc;
578 struct AsnArrayItemSize
584 /* Decodes an array of like types into a struct GenericArray.
585 * The layout and decoding of the array are described by a struct
586 * AsnArrayDescriptor.
588 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
589 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
590 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
591 DWORD *pcbDecoded, void *startingPointer)
595 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
596 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
599 if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
603 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
605 DWORD bytesNeeded, cItems = 0, decoded;
606 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
607 /* There can be arbitrarily many items, but there is often only one.
609 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
611 decoded = 1 + lenBytes;
612 bytesNeeded = sizeof(struct GenericArray);
616 BOOL doneDecoding = FALSE;
618 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
620 if (dataLen == CMSG_INDEFINITE_LENGTH)
627 SetLastError(CRYPT_E_ASN1_CORRUPT);
634 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
638 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
640 /* Each item decoded may not tolerate extraneous bytes,
641 * so get the length of the next element if known.
643 if ((ret = CRYPT_GetLengthIndefinite(ptr,
644 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
646 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
647 itemEncoded = cbEncoded - (ptr - pbEncoded);
649 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
653 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
654 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
659 if (itemSizes != &itemSize)
660 itemSizes = CryptMemRealloc(itemSizes,
661 cItems * sizeof(struct AsnArrayItemSize));
666 cItems * sizeof(struct AsnArrayItemSize));
668 memcpy(itemSizes, &itemSize,
673 decoded += itemDecoded;
674 itemSizes[cItems - 1].encodedLen = itemEncoded;
675 itemSizes[cItems - 1].size = size;
688 *pcbDecoded = decoded;
690 *pcbStructInfo = bytesNeeded;
691 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
692 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
697 struct GenericArray *array;
699 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
700 pvStructInfo = *(BYTE **)pvStructInfo;
701 array = (struct GenericArray *)pvStructInfo;
702 array->cItems = cItems;
704 array->rgItems = startingPointer;
706 array->rgItems = (BYTE *)array +
707 sizeof(struct GenericArray);
708 nextData = (BYTE *)array->rgItems +
709 array->cItems * arrayDesc->itemSize;
710 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
711 i < cItems && ptr - pbEncoded - 1 - lenBytes <
716 if (arrayDesc->hasPointer)
717 *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
718 + arrayDesc->pointerOffset) = nextData;
719 ret = arrayDesc->decodeFunc(ptr,
720 itemSizes[i].encodedLen,
721 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
722 array->rgItems + i * arrayDesc->itemSize,
723 &itemSizes[i].size, &itemDecoded);
726 nextData += itemSizes[i].size - arrayDesc->itemSize;
732 if (itemSizes != &itemSize)
733 CryptMemFree(itemSizes);
738 SetLastError(CRYPT_E_ASN1_BADTAG);
744 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
745 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
746 * to CRYPT_E_ASN1_CORRUPT.
747 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
750 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
751 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
756 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
758 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
759 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
761 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
762 bytesNeeded += 1 + lenBytes + dataLen;
765 *pcbDecoded = 1 + lenBytes + dataLen;
767 *pcbStructInfo = bytesNeeded;
768 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
770 CRYPT_DER_BLOB *blob;
772 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
773 pvStructInfo = *(BYTE **)pvStructInfo;
774 blob = (CRYPT_DER_BLOB *)pvStructInfo;
775 blob->cbData = 1 + lenBytes + dataLen;
778 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
779 blob->pbData = (BYTE *)pbEncoded;
782 assert(blob->pbData);
783 memcpy(blob->pbData, pbEncoded, blob->cbData);
788 SetLastError(CRYPT_E_ASN1_CORRUPT);
796 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
797 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
798 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
803 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
804 pvStructInfo, *pcbStructInfo, pcbDecoded);
806 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
809 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
810 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
812 if (ret && pvStructInfo)
814 CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
821 for (i = 0; i < blob->cbData / 2; i++)
823 temp = blob->pbData[i];
824 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
825 blob->pbData[blob->cbData - i - 1] = temp;
829 TRACE("returning %d (%08x)\n", ret, GetLastError());
833 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
834 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
835 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
839 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
840 pDecodePara, pvStructInfo, *pcbStructInfo);
844 struct AsnDecodeSequenceItem items[] = {
845 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
846 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
847 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
848 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
849 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
850 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
851 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
852 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
853 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
854 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
857 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
858 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
859 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
860 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
861 pcbStructInfo, NULL, NULL);
865 SetLastError(STATUS_ACCESS_VIOLATION);
870 TRACE("Returning %d (%08x)\n", ret, GetLastError());
874 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
875 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
880 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
882 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
884 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
885 dwFlags, pvStructInfo, pcbStructInfo, NULL);
887 *pcbDecoded = 1 + lenBytes + dataLen;
892 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
893 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
897 struct AsnDecodeSequenceItem items[] = {
898 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
899 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
900 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
901 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
904 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
905 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
910 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
911 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
917 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
919 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
921 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
922 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
923 if (ret && pcbDecoded)
924 *pcbDecoded = 1 + lenBytes + dataLen;
929 static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
930 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
931 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
934 struct AsnDecodeSequenceItem items[] = {
935 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
936 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
937 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
938 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
939 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
940 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
941 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
942 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
943 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
944 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
946 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
947 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
949 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
950 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
952 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
953 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
954 FALSE, TRUE, offsetof(CERT_INFO,
955 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
956 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
957 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
958 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
959 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
960 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
961 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
962 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
963 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
964 offsetof(CERT_INFO, rgExtension), 0 },
967 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
968 pDecodePara, pvStructInfo, *pcbStructInfo);
970 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
971 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
973 if (ret && pvStructInfo)
977 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
978 info = *(CERT_INFO **)pvStructInfo;
980 info = (CERT_INFO *)pvStructInfo;
981 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
982 !info->Subject.cbData)
984 SetLastError(CRYPT_E_ASN1_CORRUPT);
985 /* Don't need to deallocate, because it should have failed on the
986 * first pass (and no memory was allocated.)
992 TRACE("Returning %d (%08x)\n", ret, GetLastError());
996 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
997 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
998 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1002 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1003 pDecodePara, pvStructInfo, *pcbStructInfo);
1009 /* Unless told not to, first try to decode it as a signed cert. */
1010 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1012 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1014 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1015 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1016 (BYTE *)&signedCert, &size);
1020 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1021 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1022 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1023 pvStructInfo, pcbStructInfo);
1024 LocalFree(signedCert);
1027 /* Failing that, try it as an unsigned cert */
1031 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1032 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1033 pDecodePara, pvStructInfo, pcbStructInfo);
1038 SetLastError(STATUS_ACCESS_VIOLATION);
1042 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1046 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1047 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1050 struct AsnDecodeSequenceItem items[] = {
1051 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1052 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1053 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1054 { 0, offsetof(CRL_ENTRY, RevocationDate),
1055 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1056 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1057 CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1058 offsetof(CRL_ENTRY, rgExtension), 0 },
1060 PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1062 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1065 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1066 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1067 entry ? entry->SerialNumber.pbData : NULL);
1071 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1072 * been set prior to calling.
1074 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1075 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1078 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1079 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1080 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1081 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1083 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1084 pvStructInfo, *pcbStructInfo, pcbDecoded);
1086 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1087 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1088 entries ? entries->rgItems : NULL);
1089 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1093 static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1094 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1095 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1097 struct AsnDecodeSequenceItem items[] = {
1098 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1099 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1100 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1101 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1102 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1103 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1104 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1106 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1107 sizeof(FILETIME), FALSE, FALSE, 0 },
1108 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1109 sizeof(FILETIME), TRUE, FALSE, 0 },
1110 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1111 CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1112 offsetof(CRL_INFO, rgCRLEntry), 0 },
1113 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1114 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1115 offsetof(CRL_INFO, rgExtension), 0 },
1119 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1120 pDecodePara, pvStructInfo, *pcbStructInfo);
1122 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1123 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1126 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1130 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1131 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1132 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1136 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1137 pDecodePara, pvStructInfo, *pcbStructInfo);
1143 /* Unless told not to, first try to decode it as a signed crl. */
1144 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1146 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1148 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1149 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1150 (BYTE *)&signedCrl, &size);
1154 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1155 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1156 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1157 pvStructInfo, pcbStructInfo);
1158 LocalFree(signedCrl);
1161 /* Failing that, try it as an unsigned crl */
1165 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1166 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1167 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1172 SetLastError(STATUS_ACCESS_VIOLATION);
1176 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1180 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1181 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1186 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1187 pvStructInfo, *pcbStructInfo);
1189 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1191 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1192 DWORD bytesNeeded = sizeof(LPSTR);
1196 /* The largest possible string for the first two components
1197 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1202 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1203 pbEncoded[1 + lenBytes] / 40,
1204 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1206 bytesNeeded += strlen(firstTwo) + 1;
1207 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1208 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1210 /* large enough for ".4000000" */
1214 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1221 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1224 SetLastError(CRYPT_E_ASN1_CORRUPT);
1231 snprintf(str, sizeof(str), ".%d", val);
1232 bytesNeeded += strlen(str);
1237 *pcbDecoded = 1 + lenBytes + dataLen;
1239 *pcbStructInfo = bytesNeeded;
1240 else if (*pcbStructInfo < bytesNeeded)
1242 *pcbStructInfo = bytesNeeded;
1243 SetLastError(ERROR_MORE_DATA);
1251 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1254 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1255 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1257 pszObjId += strlen(pszObjId);
1258 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1259 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1263 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1272 sprintf(pszObjId, ".%d", val);
1273 pszObjId += strlen(pszObjId);
1277 *(LPSTR *)pvStructInfo = NULL;
1278 *pcbStructInfo = bytesNeeded;
1284 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1285 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1289 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1290 pvStructInfo, *pcbStructInfo);
1292 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1293 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1294 pvStructInfo, pcbStructInfo, pcbDecoded);
1297 SetLastError(CRYPT_E_ASN1_BADTAG);
1303 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1306 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1307 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1309 struct AsnDecodeSequenceItem items[] = {
1310 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1311 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1312 offsetof(CERT_EXTENSION, pszObjId), 0 },
1313 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1314 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1315 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1316 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1317 offsetof(CERT_EXTENSION, Value.pbData) },
1320 PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1322 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1326 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1327 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1328 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1329 pcbDecoded, ext ? ext->pszObjId : NULL);
1331 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1332 debugstr_a(ext->pszObjId));
1333 TRACE("returning %d (%08x)\n", ret, GetLastError());
1337 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1338 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1342 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1343 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1344 offsetof(CERT_EXTENSION, pszObjId) };
1345 PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1347 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1348 pvStructInfo, *pcbStructInfo, pcbDecoded);
1350 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1351 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1352 exts ? exts->rgExtension : NULL);
1356 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1357 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1358 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1364 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1365 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1366 if (ret && pvStructInfo)
1368 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1369 pcbStructInfo, *pcbStructInfo);
1372 CERT_EXTENSIONS *exts;
1374 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1375 pvStructInfo = *(BYTE **)pvStructInfo;
1376 exts = (CERT_EXTENSIONS *)pvStructInfo;
1377 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1378 sizeof(CERT_EXTENSIONS));
1379 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1380 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1381 pcbStructInfo, NULL);
1387 SetLastError(STATUS_ACCESS_VIOLATION);
1394 /* Warning: this assumes the address of value->Value.pbData is already set, in
1395 * order to avoid overwriting memory. (In some cases, it may change it, if it
1396 * doesn't copy anything to memory.) Be sure to set it correctly!
1398 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1399 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1404 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1406 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1408 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1409 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1411 switch (pbEncoded[0])
1413 case ASN_OCTETSTRING:
1414 valueType = CERT_RDN_OCTET_STRING;
1415 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1416 bytesNeeded += dataLen;
1418 case ASN_NUMERICSTRING:
1419 valueType = CERT_RDN_NUMERIC_STRING;
1420 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1421 bytesNeeded += dataLen;
1423 case ASN_PRINTABLESTRING:
1424 valueType = CERT_RDN_PRINTABLE_STRING;
1425 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1426 bytesNeeded += dataLen;
1429 valueType = CERT_RDN_IA5_STRING;
1430 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1431 bytesNeeded += dataLen;
1434 valueType = CERT_RDN_T61_STRING;
1435 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1436 bytesNeeded += dataLen;
1438 case ASN_VIDEOTEXSTRING:
1439 valueType = CERT_RDN_VIDEOTEX_STRING;
1440 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1441 bytesNeeded += dataLen;
1443 case ASN_GRAPHICSTRING:
1444 valueType = CERT_RDN_GRAPHIC_STRING;
1445 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1446 bytesNeeded += dataLen;
1448 case ASN_VISIBLESTRING:
1449 valueType = CERT_RDN_VISIBLE_STRING;
1450 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1451 bytesNeeded += dataLen;
1453 case ASN_GENERALSTRING:
1454 valueType = CERT_RDN_GENERAL_STRING;
1455 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1456 bytesNeeded += dataLen;
1458 case ASN_UNIVERSALSTRING:
1459 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1460 SetLastError(CRYPT_E_ASN1_BADTAG);
1463 valueType = CERT_RDN_BMP_STRING;
1464 bytesNeeded += dataLen;
1466 case ASN_UTF8STRING:
1467 valueType = CERT_RDN_UTF8_STRING;
1468 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1469 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1472 SetLastError(CRYPT_E_ASN1_BADTAG);
1477 *pcbDecoded = 1 + lenBytes + dataLen;
1479 *pcbStructInfo = bytesNeeded;
1480 else if (*pcbStructInfo < bytesNeeded)
1482 *pcbStructInfo = bytesNeeded;
1483 SetLastError(ERROR_MORE_DATA);
1488 *pcbStructInfo = bytesNeeded;
1489 value->dwValueType = valueType;
1494 assert(value->Value.pbData);
1495 switch (pbEncoded[0])
1497 case ASN_OCTETSTRING:
1498 case ASN_NUMERICSTRING:
1499 case ASN_PRINTABLESTRING:
1502 case ASN_VIDEOTEXSTRING:
1503 case ASN_GRAPHICSTRING:
1504 case ASN_VISIBLESTRING:
1505 case ASN_GENERALSTRING:
1506 value->Value.cbData = dataLen;
1509 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1510 memcpy(value->Value.pbData,
1511 pbEncoded + 1 + lenBytes, dataLen);
1513 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1519 LPWSTR str = (LPWSTR)value->Value.pbData;
1521 value->Value.cbData = dataLen;
1522 for (i = 0; i < dataLen / 2; i++)
1523 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1524 pbEncoded[1 + lenBytes + 2 * i + 1];
1527 case ASN_UTF8STRING:
1529 LPWSTR str = (LPWSTR)value->Value.pbData;
1531 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1532 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1533 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1540 value->Value.cbData = 0;
1541 value->Value.pbData = NULL;
1548 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1549 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1550 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1556 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1557 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1558 if (ret && pvStructInfo)
1560 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1561 pcbStructInfo, *pcbStructInfo);
1564 CERT_NAME_VALUE *value;
1566 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1567 pvStructInfo = *(BYTE **)pvStructInfo;
1568 value = (CERT_NAME_VALUE *)pvStructInfo;
1569 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1570 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1571 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1572 pcbStructInfo, NULL);
1578 SetLastError(STATUS_ACCESS_VIOLATION);
1585 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1586 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1591 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1593 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1595 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1596 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1598 switch (pbEncoded[0])
1600 case ASN_NUMERICSTRING:
1601 valueType = CERT_RDN_NUMERIC_STRING;
1602 bytesNeeded += dataLen * 2;
1604 case ASN_PRINTABLESTRING:
1605 valueType = CERT_RDN_PRINTABLE_STRING;
1606 bytesNeeded += dataLen * 2;
1609 valueType = CERT_RDN_IA5_STRING;
1610 bytesNeeded += dataLen * 2;
1613 valueType = CERT_RDN_T61_STRING;
1614 bytesNeeded += dataLen * 2;
1616 case ASN_VIDEOTEXSTRING:
1617 valueType = CERT_RDN_VIDEOTEX_STRING;
1618 bytesNeeded += dataLen * 2;
1620 case ASN_GRAPHICSTRING:
1621 valueType = CERT_RDN_GRAPHIC_STRING;
1622 bytesNeeded += dataLen * 2;
1624 case ASN_VISIBLESTRING:
1625 valueType = CERT_RDN_VISIBLE_STRING;
1626 bytesNeeded += dataLen * 2;
1628 case ASN_GENERALSTRING:
1629 valueType = CERT_RDN_GENERAL_STRING;
1630 bytesNeeded += dataLen * 2;
1632 case ASN_UNIVERSALSTRING:
1633 valueType = CERT_RDN_UNIVERSAL_STRING;
1634 bytesNeeded += dataLen / 2;
1637 valueType = CERT_RDN_BMP_STRING;
1638 bytesNeeded += dataLen;
1640 case ASN_UTF8STRING:
1641 valueType = CERT_RDN_UTF8_STRING;
1642 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1643 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1646 SetLastError(CRYPT_E_ASN1_BADTAG);
1651 *pcbDecoded = 1 + lenBytes + dataLen;
1653 *pcbStructInfo = bytesNeeded;
1654 else if (*pcbStructInfo < bytesNeeded)
1656 *pcbStructInfo = bytesNeeded;
1657 SetLastError(ERROR_MORE_DATA);
1662 *pcbStructInfo = bytesNeeded;
1663 value->dwValueType = valueType;
1667 LPWSTR str = (LPWSTR)value->Value.pbData;
1669 assert(value->Value.pbData);
1670 switch (pbEncoded[0])
1672 case ASN_NUMERICSTRING:
1673 case ASN_PRINTABLESTRING:
1676 case ASN_VIDEOTEXSTRING:
1677 case ASN_GRAPHICSTRING:
1678 case ASN_VISIBLESTRING:
1679 case ASN_GENERALSTRING:
1680 value->Value.cbData = dataLen * 2;
1681 for (i = 0; i < dataLen; i++)
1682 str[i] = pbEncoded[1 + lenBytes + i];
1684 case ASN_UNIVERSALSTRING:
1685 value->Value.cbData = dataLen / 2;
1686 for (i = 0; i < dataLen / 4; i++)
1687 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1688 | pbEncoded[1 + lenBytes + 2 * i + 3];
1691 value->Value.cbData = dataLen;
1692 for (i = 0; i < dataLen / 2; i++)
1693 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1694 pbEncoded[1 + lenBytes + 2 * i + 1];
1696 case ASN_UTF8STRING:
1697 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1698 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1699 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1705 value->Value.cbData = 0;
1706 value->Value.pbData = NULL;
1713 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1714 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1715 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1721 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1722 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1723 if (ret && pvStructInfo)
1725 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1726 pcbStructInfo, *pcbStructInfo);
1729 CERT_NAME_VALUE *value;
1731 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1732 pvStructInfo = *(BYTE **)pvStructInfo;
1733 value = (CERT_NAME_VALUE *)pvStructInfo;
1734 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1735 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1736 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1737 pcbStructInfo, NULL);
1743 SetLastError(STATUS_ACCESS_VIOLATION);
1750 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1751 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1754 struct AsnDecodeSequenceItem items[] = {
1755 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1756 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1757 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1758 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1759 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1760 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1762 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1764 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1765 pvStructInfo, *pcbStructInfo);
1768 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1769 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1770 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1771 attr ? attr->pszObjId : NULL);
1774 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1775 debugstr_a(attr->pszObjId));
1776 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1778 TRACE("returning %d (%08x)\n", ret, GetLastError());
1782 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1783 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1786 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1787 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1788 offsetof(CERT_RDN_ATTR, pszObjId) };
1789 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1791 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1792 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1793 rdn ? rdn->rgRDNAttr : NULL);
1797 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1798 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1799 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1805 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1806 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1807 offsetof(CERT_RDN, rgRDNAttr) };
1809 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1810 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1814 SetLastError(STATUS_ACCESS_VIOLATION);
1821 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1822 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1826 struct AsnDecodeSequenceItem items[] = {
1827 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1828 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1829 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1830 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1831 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1832 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1834 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1836 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1837 pvStructInfo, *pcbStructInfo);
1840 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1841 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1842 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1843 attr ? attr->pszObjId : NULL);
1846 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1847 debugstr_a(attr->pszObjId));
1848 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1850 TRACE("returning %d (%08x)\n", ret, GetLastError());
1854 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1855 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1858 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1859 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1860 offsetof(CERT_RDN_ATTR, pszObjId) };
1861 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1863 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1864 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1865 rdn ? rdn->rgRDNAttr : NULL);
1869 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1870 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1871 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1877 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1878 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1879 offsetof(CERT_RDN, rgRDNAttr) };
1881 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1882 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1886 SetLastError(STATUS_ACCESS_VIOLATION);
1893 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1896 BOOL ret = TRUE, done = FALSE;
1897 DWORD indefiniteNestingLevels = 0, decoded = 0;
1899 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1906 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1909 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1911 if (dataLen == CMSG_INDEFINITE_LENGTH)
1913 indefiniteNestingLevels++;
1914 pbEncoded += 1 + lenBytes;
1915 cbEncoded -= 1 + lenBytes;
1916 decoded += 1 + lenBytes;
1917 TRACE("indefiniteNestingLevels = %d\n",
1918 indefiniteNestingLevels);
1922 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1923 indefiniteNestingLevels)
1925 indefiniteNestingLevels--;
1926 TRACE("indefiniteNestingLevels = %d\n",
1927 indefiniteNestingLevels);
1929 pbEncoded += 1 + lenBytes + dataLen;
1930 cbEncoded -= 1 + lenBytes + dataLen;
1931 decoded += 1 + lenBytes + dataLen;
1932 if (!indefiniteNestingLevels)
1936 } while (ret && !done);
1937 /* If we haven't found all 0 TLVs, we haven't found the end */
1938 if (ret && indefiniteNestingLevels)
1940 SetLastError(CRYPT_E_ASN1_EOD);
1944 *pcbDecoded = decoded;
1945 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1949 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1950 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1954 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
1956 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1957 pvStructInfo, *pcbStructInfo);
1959 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
1961 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1962 bytesNeeded += encodedLen;
1964 *pcbStructInfo = bytesNeeded;
1965 else if (*pcbStructInfo < bytesNeeded)
1967 SetLastError(ERROR_MORE_DATA);
1968 *pcbStructInfo = bytesNeeded;
1973 PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
1975 *pcbStructInfo = bytesNeeded;
1976 blob->cbData = encodedLen;
1977 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
1978 blob->pbData = (LPBYTE)pbEncoded;
1981 assert(blob->pbData);
1982 memcpy(blob->pbData, pbEncoded, blob->cbData);
1986 *pcbDecoded = encodedLen;
1991 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
1992 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1995 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
1996 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
1997 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
1999 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2000 pvStructInfo, *pcbStructInfo, pcbDecoded);
2002 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2003 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2004 array ? array->rgItems : NULL);
2008 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2009 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2013 struct AsnDecodeSequenceItem items[] = {
2014 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2015 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2016 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2017 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2018 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2019 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2021 PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2023 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2024 pvStructInfo, *pcbStructInfo);
2026 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2027 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2028 pcbDecoded, attr ? attr->pszObjId : NULL);
2029 TRACE("returning %d\n", ret);
2033 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2034 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2035 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2039 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2040 pDecodePara, pvStructInfo, *pcbStructInfo);
2046 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2047 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2051 *pcbStructInfo = bytesNeeded;
2052 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2053 pvStructInfo, pcbStructInfo, bytesNeeded)))
2055 PCRYPT_ATTRIBUTE attr;
2057 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2058 pvStructInfo = *(BYTE **)pvStructInfo;
2059 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2060 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2061 sizeof(CRYPT_ATTRIBUTE));
2062 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2063 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2070 SetLastError(STATUS_ACCESS_VIOLATION);
2073 TRACE("returning %d\n", ret);
2077 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2078 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2081 struct AsnArrayDescriptor arrayDesc = { 0,
2082 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2083 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2084 PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2087 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2088 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2093 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2094 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2095 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2099 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2100 pDecodePara, pvStructInfo, *pcbStructInfo);
2107 SetLastError(CRYPT_E_ASN1_EOD);
2108 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2109 SetLastError(CRYPT_E_ASN1_CORRUPT);
2110 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2111 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2115 *pcbStructInfo = bytesNeeded;
2116 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2117 pvStructInfo, pcbStructInfo, bytesNeeded)))
2119 PCRYPT_ATTRIBUTES attrs;
2121 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2122 pvStructInfo = *(BYTE **)pvStructInfo;
2123 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2124 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2125 sizeof(CRYPT_ATTRIBUTES));
2126 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2127 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2128 &bytesNeeded, NULL);
2134 SetLastError(STATUS_ACCESS_VIOLATION);
2137 TRACE("returning %d\n", ret);
2141 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2142 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2144 CRYPT_ALGORITHM_IDENTIFIER *algo =
2145 (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2147 struct AsnDecodeSequenceItem items[] = {
2148 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2149 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2150 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2151 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2152 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2153 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2156 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2157 pvStructInfo, *pcbStructInfo, pcbDecoded);
2159 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2160 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2161 pcbDecoded, algo ? algo->pszObjId : NULL);
2162 if (ret && pvStructInfo)
2164 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2165 debugstr_a(algo->pszObjId));
2170 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2171 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2175 struct AsnDecodeSequenceItem items[] = {
2176 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2177 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2178 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2179 Algorithm.pszObjId) },
2180 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2181 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2182 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2184 PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2186 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2187 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2188 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2192 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2193 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2194 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2202 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2203 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2206 *pcbStructInfo = bytesNeeded;
2207 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2208 pvStructInfo, pcbStructInfo, bytesNeeded)))
2210 PCERT_PUBLIC_KEY_INFO info;
2212 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2213 pvStructInfo = *(BYTE **)pvStructInfo;
2214 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2215 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2216 sizeof(CERT_PUBLIC_KEY_INFO);
2217 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2218 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2219 &bytesNeeded, NULL);
2225 SetLastError(STATUS_ACCESS_VIOLATION);
2232 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2233 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2239 SetLastError(CRYPT_E_ASN1_CORRUPT);
2242 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2244 SetLastError(CRYPT_E_ASN1_CORRUPT);
2247 if (pbEncoded[1] > 1)
2249 SetLastError(CRYPT_E_ASN1_CORRUPT);
2256 *pcbStructInfo = sizeof(BOOL);
2259 else if (*pcbStructInfo < sizeof(BOOL))
2261 *pcbStructInfo = sizeof(BOOL);
2262 SetLastError(ERROR_MORE_DATA);
2267 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2270 TRACE("returning %d (%08x)\n", ret, GetLastError());
2274 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2275 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2277 PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2278 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2281 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2282 pvStructInfo, *pcbStructInfo);
2286 SetLastError(CRYPT_E_ASN1_CORRUPT);
2289 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2290 if (1 + lenBytes > cbEncoded)
2292 SetLastError(CRYPT_E_ASN1_CORRUPT);
2295 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2297 switch (pbEncoded[0] & ASN_TYPE_MASK)
2299 case 1: /* rfc822Name */
2300 case 2: /* dNSName */
2301 case 6: /* uniformResourceIdentifier */
2302 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2304 case 4: /* directoryName */
2305 case 7: /* iPAddress */
2306 bytesNeeded += dataLen;
2308 case 8: /* registeredID */
2309 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2313 /* FIXME: ugly, shouldn't need to know internals of OID decode
2314 * function to use it.
2316 bytesNeeded += dataLen - sizeof(LPSTR);
2319 case 0: /* otherName */
2320 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2321 SetLastError(CRYPT_E_ASN1_BADTAG);
2324 case 3: /* x400Address, unimplemented */
2325 case 5: /* ediPartyName, unimplemented */
2326 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2327 SetLastError(CRYPT_E_ASN1_BADTAG);
2331 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2332 SetLastError(CRYPT_E_ASN1_CORRUPT);
2338 *pcbDecoded = 1 + lenBytes + dataLen;
2340 *pcbStructInfo = bytesNeeded;
2341 else if (*pcbStructInfo < bytesNeeded)
2343 *pcbStructInfo = bytesNeeded;
2344 SetLastError(ERROR_MORE_DATA);
2349 *pcbStructInfo = bytesNeeded;
2350 /* MS used values one greater than the asn1 ones.. sigh */
2351 entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
2352 switch (pbEncoded[0] & ASN_TYPE_MASK)
2354 case 1: /* rfc822Name */
2355 case 2: /* dNSName */
2356 case 6: /* uniformResourceIdentifier */
2360 for (i = 0; i < dataLen; i++)
2361 entry->u.pwszURL[i] =
2362 (WCHAR)pbEncoded[1 + lenBytes + i];
2363 entry->u.pwszURL[i] = 0;
2364 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2365 debugstr_w(entry->u.pwszURL));
2368 case 4: /* directoryName */
2369 entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
2370 /* The data are memory-equivalent with the IPAddress case,
2373 case 7: /* iPAddress */
2374 /* The next data pointer is in the pwszURL spot, that is,
2375 * the first 4 bytes. Need to move it to the next spot.
2377 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2378 entry->u.IPAddress.cbData = dataLen;
2379 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2382 case 8: /* registeredID */
2383 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2384 &entry->u.pszRegisteredID, &dataLen, NULL);
2393 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2394 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2398 struct AsnArrayDescriptor arrayDesc = { 0,
2399 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2400 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2401 PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2403 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2404 pvStructInfo, *pcbStructInfo, pcbDecoded);
2407 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2408 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2409 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2410 info ? info->rgAltEntry : NULL);
2414 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2415 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2416 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2421 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2422 pvStructInfo, *pcbStructInfo, pcbDecoded);
2424 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2427 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2428 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2430 if (ret && pvStructInfo)
2432 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2439 for (i = 0; i < blob->cbData / 2; i++)
2441 temp = blob->pbData[i];
2442 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2443 blob->pbData[blob->cbData - i - 1] = temp;
2447 TRACE("returning %d (%08x)\n", ret, GetLastError());
2451 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2452 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2459 struct AsnDecodeSequenceItem items[] = {
2460 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2461 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2462 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2463 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2464 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2465 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2466 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2467 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2468 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2469 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2470 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2473 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2474 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2475 pcbStructInfo, NULL, NULL);
2479 SetLastError(STATUS_ACCESS_VIOLATION);
2486 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2487 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2488 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2494 struct AsnDecodeSequenceItem items[] = {
2495 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2496 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2497 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2498 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2499 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2500 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2501 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2502 AuthorityCertIssuer.rgAltEntry), 0 },
2503 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2504 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2505 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2506 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2507 AuthorityCertSerialNumber.pbData), 0 },
2510 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2511 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2512 pcbStructInfo, NULL, NULL);
2516 SetLastError(STATUS_ACCESS_VIOLATION);
2523 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2524 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2529 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2530 pvStructInfo, *pcbStructInfo, pcbDecoded);
2532 /* The caller has already checked the tag, no need to check it again.
2533 * Check the outer length is valid:
2535 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2537 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2540 pbEncoded += 1 + lenBytes;
2541 cbEncoded -= 1 + lenBytes;
2542 if (dataLen == CMSG_INDEFINITE_LENGTH)
2543 cbEncoded -= 2; /* space for 0 TLV */
2544 /* Check the inner length is valid: */
2545 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2549 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2550 pvStructInfo, pcbStructInfo, &decodedLen);
2551 if (dataLen == CMSG_INDEFINITE_LENGTH)
2553 if (*(pbEncoded + decodedLen) != 0 ||
2554 *(pbEncoded + decodedLen + 1) != 0)
2556 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2557 *(pbEncoded + decodedLen),
2558 *(pbEncoded + decodedLen + 1));
2559 SetLastError(CRYPT_E_ASN1_CORRUPT);
2565 if (ret && pcbDecoded)
2567 *pcbDecoded = 1 + lenBytes + decodedLen;
2568 TRACE("decoded %d bytes\n", *pcbDecoded);
2575 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2576 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2579 CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2580 struct AsnDecodeSequenceItem items[] = {
2581 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2582 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2583 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2584 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2585 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2586 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2587 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2591 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2592 pvStructInfo, *pcbStructInfo, pcbDecoded);
2594 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2595 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2596 pcbDecoded, info ? info->pszObjId : NULL);
2600 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2601 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2602 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2606 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2607 pDecodePara, pvStructInfo, *pcbStructInfo);
2611 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2612 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2613 if (ret && pvStructInfo)
2615 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2616 pcbStructInfo, *pcbStructInfo);
2619 CRYPT_CONTENT_INFO *info;
2621 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2622 pvStructInfo = *(BYTE **)pvStructInfo;
2623 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2624 info->pszObjId = (LPSTR)((BYTE *)info +
2625 sizeof(CRYPT_CONTENT_INFO));
2626 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2627 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2628 pcbStructInfo, NULL);
2634 SetLastError(STATUS_ACCESS_VIOLATION);
2640 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2641 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2642 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2645 struct AsnDecodeSequenceItem items[] = {
2646 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2647 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2648 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2649 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2650 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2652 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2653 CRYPT_AsnDecodePKCSContentInfoInternal,
2654 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2655 ContentInfo.pszObjId), 0 },
2656 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2657 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2658 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2661 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2662 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2667 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2668 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2669 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2673 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2674 pDecodePara, pvStructInfo, *pcbStructInfo);
2680 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2681 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2684 *pcbStructInfo = bytesNeeded;
2685 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2686 pvStructInfo, pcbStructInfo, bytesNeeded)))
2688 CERT_ALT_NAME_INFO *name;
2690 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2691 pvStructInfo = *(BYTE **)pvStructInfo;
2692 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2693 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2694 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2695 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2696 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2697 &bytesNeeded, NULL);
2703 SetLastError(STATUS_ACCESS_VIOLATION);
2710 struct PATH_LEN_CONSTRAINT
2712 BOOL fPathLenConstraint;
2713 DWORD dwPathLenConstraint;
2716 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
2717 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2721 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
2723 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2724 pvStructInfo, *pcbStructInfo, pcbDecoded);
2728 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
2730 *pcbStructInfo = bytesNeeded;
2732 else if (*pcbStructInfo < bytesNeeded)
2734 SetLastError(ERROR_MORE_DATA);
2735 *pcbStructInfo = bytesNeeded;
2740 struct PATH_LEN_CONSTRAINT *constraint =
2741 (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
2743 size = sizeof(constraint->dwPathLenConstraint);
2744 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
2745 &constraint->dwPathLenConstraint, &size, pcbDecoded);
2747 constraint->fPathLenConstraint = TRUE;
2748 TRACE("got an int, dwPathLenConstraint is %d\n",
2749 constraint->dwPathLenConstraint);
2751 TRACE("returning %d (%08x)\n", ret, GetLastError());
2755 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
2756 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2760 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2761 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
2762 offsetof(CERT_NAME_BLOB, pbData) };
2763 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2765 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2766 pvStructInfo, *pcbStructInfo, pcbDecoded);
2768 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2769 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2770 entries ? entries->rgItems : NULL);
2771 TRACE("Returning %d (%08x)\n", ret, GetLastError());
2775 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
2776 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2777 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2783 struct AsnDecodeSequenceItem items[] = {
2784 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
2785 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2786 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
2787 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2788 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2789 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2790 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2791 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
2792 sizeof(struct GenericArray), TRUE, TRUE,
2793 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
2796 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2797 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2798 pcbStructInfo, NULL, NULL);
2802 SetLastError(STATUS_ACCESS_VIOLATION);
2809 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
2810 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2811 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2817 struct AsnDecodeSequenceItem items[] = {
2818 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
2819 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
2820 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
2821 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2822 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2825 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2826 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2827 pcbStructInfo, NULL, NULL);
2831 SetLastError(STATUS_ACCESS_VIOLATION);
2838 #define RSA1_MAGIC 0x31415352
2840 struct DECODED_RSA_PUB_KEY
2843 CRYPT_INTEGER_BLOB modulus;
2846 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
2847 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2848 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2854 struct AsnDecodeSequenceItem items[] = {
2855 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
2856 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2857 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
2859 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
2860 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2862 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
2865 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2866 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
2870 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2871 decodedKey->modulus.cbData;
2875 *pcbStructInfo = bytesNeeded;
2878 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2879 pvStructInfo, pcbStructInfo, bytesNeeded)))
2882 RSAPUBKEY *rsaPubKey;
2884 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2885 pvStructInfo = *(BYTE **)pvStructInfo;
2886 hdr = (BLOBHEADER *)pvStructInfo;
2887 hdr->bType = PUBLICKEYBLOB;
2888 hdr->bVersion = CUR_BLOB_VERSION;
2890 hdr->aiKeyAlg = CALG_RSA_KEYX;
2891 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
2892 sizeof(BLOBHEADER));
2893 rsaPubKey->magic = RSA1_MAGIC;
2894 rsaPubKey->pubexp = decodedKey->pubexp;
2895 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
2896 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
2897 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
2898 decodedKey->modulus.cbData);
2900 LocalFree(decodedKey);
2905 SetLastError(STATUS_ACCESS_VIOLATION);
2912 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
2913 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2917 DWORD bytesNeeded, dataLen;
2919 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2920 pvStructInfo, *pcbStructInfo, pcbDecoded);
2922 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2924 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2926 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2927 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
2929 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
2931 *pcbDecoded = 1 + lenBytes + dataLen;
2933 *pcbStructInfo = bytesNeeded;
2934 else if (*pcbStructInfo < bytesNeeded)
2936 SetLastError(ERROR_MORE_DATA);
2937 *pcbStructInfo = bytesNeeded;
2942 CRYPT_DATA_BLOB *blob;
2944 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2945 blob->cbData = dataLen;
2946 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2947 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
2950 assert(blob->pbData);
2952 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
2960 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
2961 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2962 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2966 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2967 pDecodePara, pvStructInfo, *pcbStructInfo);
2975 SetLastError(CRYPT_E_ASN1_CORRUPT);
2978 else if (pbEncoded[0] != ASN_OCTETSTRING)
2980 SetLastError(CRYPT_E_ASN1_BADTAG);
2983 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
2984 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2987 *pcbStructInfo = bytesNeeded;
2988 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2989 pvStructInfo, pcbStructInfo, bytesNeeded)))
2991 CRYPT_DATA_BLOB *blob;
2993 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2994 pvStructInfo = *(BYTE **)pvStructInfo;
2995 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2996 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
2997 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
2998 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2999 &bytesNeeded, NULL);
3005 SetLastError(STATUS_ACCESS_VIOLATION);
3012 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3013 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3017 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3018 pvStructInfo, *pcbStructInfo, pcbDecoded);
3020 if (pbEncoded[0] == ASN_BITSTRING)
3022 DWORD bytesNeeded, dataLen;
3023 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3025 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3027 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3028 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3030 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3032 *pcbDecoded = 1 + lenBytes + dataLen;
3034 *pcbStructInfo = bytesNeeded;
3035 else if (*pcbStructInfo < bytesNeeded)
3037 *pcbStructInfo = bytesNeeded;
3038 SetLastError(ERROR_MORE_DATA);
3043 CRYPT_BIT_BLOB *blob;
3045 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3046 blob->cbData = dataLen - 1;
3047 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3048 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3050 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3054 assert(blob->pbData);
3057 BYTE mask = 0xff << blob->cUnusedBits;
3059 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3061 blob->pbData[blob->cbData - 1] &= mask;
3069 SetLastError(CRYPT_E_ASN1_BADTAG);
3072 TRACE("returning %d (%08x)\n", ret, GetLastError());
3076 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3077 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3078 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3082 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3083 pDecodePara, pvStructInfo, pcbStructInfo);
3089 if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3090 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3093 *pcbStructInfo = bytesNeeded;
3094 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3095 pvStructInfo, pcbStructInfo, bytesNeeded)))
3097 CRYPT_BIT_BLOB *blob;
3099 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3100 pvStructInfo = *(BYTE **)pvStructInfo;
3101 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3102 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3103 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3104 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3105 &bytesNeeded, NULL);
3111 SetLastError(STATUS_ACCESS_VIOLATION);
3115 TRACE("returning %d (%08x)\n", ret, GetLastError());
3119 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3120 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3121 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3124 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3125 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3126 DWORD size = sizeof(buf);
3128 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3129 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, &buf,
3134 *pcbStructInfo = sizeof(int);
3135 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3139 if (blob->pbData[blob->cbData - 1] & 0x80)
3141 /* initialize to a negative value to sign-extend */
3146 for (i = 0; i < blob->cbData; i++)
3149 val |= blob->pbData[blob->cbData - i - 1];
3151 memcpy(pvStructInfo, &val, sizeof(int));
3154 else if (GetLastError() == ERROR_MORE_DATA)
3155 SetLastError(CRYPT_E_ASN1_LARGE);
3159 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3160 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3161 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3171 SetLastError(CRYPT_E_ASN1_CORRUPT);
3174 else if (pbEncoded[0] != ASN_INTEGER)
3176 SetLastError(CRYPT_E_ASN1_BADTAG);
3180 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3181 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3185 *pcbStructInfo = bytesNeeded;
3186 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3187 pvStructInfo, pcbStructInfo, bytesNeeded)))
3189 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3190 pvStructInfo = *(BYTE **)pvStructInfo;
3191 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3192 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3193 &bytesNeeded, NULL);
3199 SetLastError(STATUS_ACCESS_VIOLATION);
3206 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3207 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3211 DWORD bytesNeeded, dataLen;
3213 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3215 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3217 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3219 *pcbDecoded = 1 + lenBytes + dataLen;
3221 *pcbStructInfo = bytesNeeded;
3222 else if (*pcbStructInfo < bytesNeeded)
3224 *pcbStructInfo = bytesNeeded;
3225 SetLastError(ERROR_MORE_DATA);
3230 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3232 blob->cbData = dataLen;
3233 assert(blob->pbData);
3238 for (i = 0; i < blob->cbData; i++)
3240 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3249 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
3250 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3251 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3259 if (pbEncoded[0] != ASN_INTEGER)
3261 SetLastError(CRYPT_E_ASN1_BADTAG);
3265 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3266 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3270 *pcbStructInfo = bytesNeeded;
3271 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3272 pvStructInfo, pcbStructInfo, bytesNeeded)))
3274 CRYPT_INTEGER_BLOB *blob;
3276 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3277 pvStructInfo = *(BYTE **)pvStructInfo;
3278 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3279 blob->pbData = (BYTE *)pvStructInfo +
3280 sizeof(CRYPT_INTEGER_BLOB);
3281 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3282 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3283 &bytesNeeded, NULL);
3289 SetLastError(STATUS_ACCESS_VIOLATION);
3296 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
3297 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3302 if (pbEncoded[0] == ASN_INTEGER)
3304 DWORD bytesNeeded, dataLen;
3306 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3308 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3311 *pcbDecoded = 1 + lenBytes + dataLen;
3312 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3314 *pcbStructInfo = bytesNeeded;
3315 else if (*pcbStructInfo < bytesNeeded)
3317 *pcbStructInfo = bytesNeeded;
3318 SetLastError(ERROR_MORE_DATA);
3323 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3325 blob->cbData = dataLen;
3326 assert(blob->pbData);
3327 /* remove leading zero byte if it exists */
3328 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
3337 for (i = 0; i < blob->cbData; i++)
3339 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3348 SetLastError(CRYPT_E_ASN1_BADTAG);
3354 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
3355 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3356 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3364 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
3365 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3368 *pcbStructInfo = bytesNeeded;
3369 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3370 pvStructInfo, pcbStructInfo, bytesNeeded)))
3372 CRYPT_INTEGER_BLOB *blob;
3374 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3375 pvStructInfo = *(BYTE **)pvStructInfo;
3376 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3377 blob->pbData = (BYTE *)pvStructInfo +
3378 sizeof(CRYPT_INTEGER_BLOB);
3379 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
3380 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3381 &bytesNeeded, NULL);
3387 SetLastError(STATUS_ACCESS_VIOLATION);
3394 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
3395 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3396 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3402 *pcbStructInfo = sizeof(int);
3407 if (pbEncoded[0] == ASN_ENUMERATED)
3409 unsigned int val = 0, i;
3413 SetLastError(CRYPT_E_ASN1_EOD);
3416 else if (pbEncoded[1] == 0)
3418 SetLastError(CRYPT_E_ASN1_CORRUPT);
3423 /* A little strange looking, but we have to accept a sign byte:
3424 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3425 * assuming a small length is okay here, it has to be in short
3428 if (pbEncoded[1] > sizeof(unsigned int) + 1)
3430 SetLastError(CRYPT_E_ASN1_LARGE);
3433 for (i = 0; i < pbEncoded[1]; i++)
3436 val |= pbEncoded[2 + i];
3438 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3439 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
3441 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3442 pvStructInfo = *(BYTE **)pvStructInfo;
3443 memcpy(pvStructInfo, &val, sizeof(unsigned int));
3449 SetLastError(CRYPT_E_ASN1_BADTAG);
3455 SetLastError(STATUS_ACCESS_VIOLATION);
3462 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3465 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3470 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3472 if (!isdigit(*(pbEncoded))) \
3474 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3480 (word) += *(pbEncoded)++ - '0'; \
3485 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
3486 SYSTEMTIME *sysTime)
3490 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
3492 WORD hours, minutes = 0;
3493 BYTE sign = *pbEncoded++;
3496 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
3497 if (ret && hours >= 24)
3499 SetLastError(CRYPT_E_ASN1_CORRUPT);
3504 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
3505 if (ret && minutes >= 60)
3507 SetLastError(CRYPT_E_ASN1_CORRUPT);
3515 sysTime->wHour += hours;
3516 sysTime->wMinute += minutes;
3520 if (hours > sysTime->wHour)
3523 sysTime->wHour = 24 - (hours - sysTime->wHour);
3526 sysTime->wHour -= hours;
3527 if (minutes > sysTime->wMinute)
3530 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
3533 sysTime->wMinute -= minutes;
3540 #define MIN_ENCODED_TIME_LENGTH 10
3542 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
3543 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3548 if (pbEncoded[0] == ASN_UTCTIME)
3551 SetLastError(CRYPT_E_ASN1_EOD);
3552 else if (pbEncoded[1] > 0x7f)
3554 /* long-form date strings really can't be valid */
3555 SetLastError(CRYPT_E_ASN1_CORRUPT);
3559 SYSTEMTIME sysTime = { 0 };
3560 BYTE len = pbEncoded[1];
3562 if (len < MIN_ENCODED_TIME_LENGTH)
3563 SetLastError(CRYPT_E_ASN1_CORRUPT);
3568 *pcbDecoded = 2 + len;
3570 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
3571 if (sysTime.wYear >= 50)
3572 sysTime.wYear += 1900;
3574 sysTime.wYear += 2000;
3575 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3576 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3577 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3578 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
3581 if (len >= 2 && isdigit(*pbEncoded) &&
3582 isdigit(*(pbEncoded + 1)))
3583 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3585 else if (isdigit(*pbEncoded))
3586 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
3589 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3595 *pcbStructInfo = sizeof(FILETIME);
3596 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3598 ret = SystemTimeToFileTime(&sysTime,
3599 (FILETIME *)pvStructInfo);
3605 SetLastError(CRYPT_E_ASN1_BADTAG);
3609 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
3610 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3611 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3619 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3620 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3624 *pcbStructInfo = bytesNeeded;
3625 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
3626 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
3628 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3629 pvStructInfo = *(BYTE **)pvStructInfo;
3630 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3631 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3632 &bytesNeeded, NULL);
3638 SetLastError(STATUS_ACCESS_VIOLATION);
3644 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
3645 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3650 if (pbEncoded[0] == ASN_GENERALTIME)
3653 SetLastError(CRYPT_E_ASN1_EOD);
3654 else if (pbEncoded[1] > 0x7f)
3656 /* long-form date strings really can't be valid */
3657 SetLastError(CRYPT_E_ASN1_CORRUPT);
3661 BYTE len = pbEncoded[1];
3663 if (len < MIN_ENCODED_TIME_LENGTH)
3664 SetLastError(CRYPT_E_ASN1_CORRUPT);
3667 SYSTEMTIME sysTime = { 0 };
3671 *pcbDecoded = 2 + len;
3673 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
3674 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3675 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3676 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3679 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3682 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3684 if (ret && len > 0 && (*pbEncoded == '.' ||
3691 /* workaround macro weirdness */
3692 digits = min(len, 3);
3693 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
3694 sysTime.wMilliseconds);
3697 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3703 *pcbStructInfo = sizeof(FILETIME);
3704 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3706 ret = SystemTimeToFileTime(&sysTime,
3707 (FILETIME *)pvStructInfo);
3713 SetLastError(CRYPT_E_ASN1_BADTAG);
3717 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
3718 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3722 InternalDecodeFunc decode = NULL;
3724 if (pbEncoded[0] == ASN_UTCTIME)
3725 decode = CRYPT_AsnDecodeUtcTimeInternal;
3726 else if (pbEncoded[0] == ASN_GENERALTIME)
3727 decode = CRYPT_AsnDecodeGeneralizedTime;
3729 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
3730 pcbStructInfo, pcbDecoded);
3733 SetLastError(CRYPT_E_ASN1_BADTAG);
3739 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
3740 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3741 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3749 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3750 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3754 *pcbStructInfo = bytesNeeded;
3755 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3756 pvStructInfo, pcbStructInfo, bytesNeeded)))
3758 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3759 pvStructInfo = *(BYTE **)pvStructInfo;
3760 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3761 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3762 &bytesNeeded, NULL);
3768 SetLastError(STATUS_ACCESS_VIOLATION);
3775 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
3776 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3777 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3783 if (pbEncoded[0] == ASN_SEQUENCEOF)
3785 DWORD bytesNeeded, dataLen, remainingLen, cValue;
3787 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3792 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3793 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
3795 ptr = pbEncoded + 1 + lenBytes;
3796 remainingLen = dataLen;
3797 while (ret && remainingLen)
3801 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3804 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3806 remainingLen -= 1 + nextLenBytes + nextLen;
3807 ptr += 1 + nextLenBytes + nextLen;
3808 bytesNeeded += sizeof(CRYPT_DER_BLOB);
3809 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
3810 bytesNeeded += 1 + nextLenBytes + nextLen;
3816 CRYPT_SEQUENCE_OF_ANY *seq;
3820 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3821 pvStructInfo, pcbStructInfo, bytesNeeded)))
3823 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3824 pvStructInfo = *(BYTE **)pvStructInfo;
3825 seq = (CRYPT_SEQUENCE_OF_ANY *)pvStructInfo;
3826 seq->cValue = cValue;
3827 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
3829 nextPtr = (BYTE *)seq->rgValue +
3830 cValue * sizeof(CRYPT_DER_BLOB);
3831 ptr = pbEncoded + 1 + lenBytes;
3832 remainingLen = dataLen;
3834 while (ret && remainingLen)
3838 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3841 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3843 seq->rgValue[i].cbData = 1 + nextLenBytes +
3845 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3846 seq->rgValue[i].pbData = (BYTE *)ptr;
3849 seq->rgValue[i].pbData = nextPtr;
3850 memcpy(nextPtr, ptr, 1 + nextLenBytes +
3852 nextPtr += 1 + nextLenBytes + nextLen;
3854 remainingLen -= 1 + nextLenBytes + nextLen;
3855 ptr += 1 + nextLenBytes + nextLen;
3865 SetLastError(CRYPT_E_ASN1_BADTAG);
3871 SetLastError(STATUS_ACCESS_VIOLATION);
3878 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
3879 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3884 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
3886 DWORD bytesNeeded, dataLen;
3888 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3890 struct AsnArrayDescriptor arrayDesc = {
3891 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
3892 sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3893 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3894 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3900 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3901 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3902 0, NULL, NULL, &nameLen, NULL, NULL);
3903 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen;
3906 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
3908 *pcbDecoded = 1 + lenBytes + dataLen;
3910 *pcbStructInfo = bytesNeeded;
3911 else if (*pcbStructInfo < bytesNeeded)
3913 *pcbStructInfo = bytesNeeded;
3914 SetLastError(ERROR_MORE_DATA);
3919 CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
3923 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3924 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3925 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3926 0, NULL, &name->u.FullName, pcbStructInfo, NULL,
3927 name->u.FullName.rgAltEntry);
3930 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3936 SetLastError(CRYPT_E_ASN1_BADTAG);
3942 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
3943 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3945 struct AsnDecodeSequenceItem items[] = {
3946 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
3947 DistPointName), CRYPT_AsnDecodeDistPointName,
3948 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
3949 DistPointName.u.FullName.rgAltEntry), 0 },
3950 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
3951 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
3952 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
3953 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
3954 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
3955 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
3959 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3960 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3965 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
3966 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3967 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3971 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3972 pDecodePara, pvStructInfo, *pcbStructInfo);
3976 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3977 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
3978 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
3980 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3981 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3985 SetLastError(STATUS_ACCESS_VIOLATION);
3992 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
3993 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3994 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3998 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3999 pDecodePara, pvStructInfo, *pcbStructInfo);
4003 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4004 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4006 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4007 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4011 SetLastError(STATUS_ACCESS_VIOLATION);
4018 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4019 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4020 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4024 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4025 pDecodePara, pvStructInfo, *pcbStructInfo);
4029 struct AsnDecodeSequenceItem items[] = {
4030 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4031 DistPointName), CRYPT_AsnDecodeDistPointName,
4032 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4033 offsetof(CRL_ISSUING_DIST_POINT,
4034 DistPointName.u.FullName.rgAltEntry), 0 },
4035 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4036 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4038 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4039 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4041 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4042 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4043 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4044 OnlySomeReasonFlags.pbData), 0 },
4045 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4046 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4049 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4050 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4051 pcbStructInfo, NULL, NULL);
4055 SetLastError(STATUS_ACCESS_VIOLATION);
4062 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4063 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4068 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4069 pvStructInfo, *pcbStructInfo, pcbDecoded);
4073 SetLastError(CRYPT_E_ASN1_EOD);
4076 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4078 SetLastError(CRYPT_E_ASN1_BADTAG);
4081 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4082 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4083 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4085 if (ret && pvStructInfo)
4086 *(BOOL *)pvStructInfo = TRUE;
4087 TRACE("returning %d\n", ret);
4091 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4092 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4096 struct AsnDecodeSequenceItem items[] = {
4097 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4098 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4099 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4100 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4101 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4102 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4103 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4106 CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)pvStructInfo;
4108 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4109 pvStructInfo, *pcbStructInfo, pcbDecoded);
4111 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4112 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4113 pcbDecoded, subtree ? (BYTE *)subtree->Base.u.pwszURL : NULL);
4116 TRACE("%d\n", *pcbDecoded);
4117 if (*pcbDecoded < cbEncoded)
4118 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4119 *(pbEncoded + *pcbDecoded + 1));
4121 TRACE("returning %d\n", ret);
4125 static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
4126 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4130 struct AsnArrayDescriptor arrayDesc = { 0,
4131 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4132 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4133 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4135 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4136 pvStructInfo, *pcbStructInfo, pcbDecoded);
4138 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4139 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4140 array ? array->rgItems : NULL);
4145 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4146 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4147 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4151 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4152 pDecodePara, pvStructInfo, *pcbStructInfo);
4156 struct AsnDecodeSequenceItem items[] = {
4157 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4158 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4159 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4160 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4161 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4162 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4163 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4164 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4167 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4168 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4169 pcbStructInfo, NULL, NULL);
4173 SetLastError(STATUS_ACCESS_VIOLATION);
4179 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
4180 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4184 struct AsnDecodeSequenceItem items[] = {
4185 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
4186 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
4188 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
4189 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
4190 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
4192 CERT_ISSUER_SERIAL_NUMBER *issuerSerial =
4193 (CERT_ISSUER_SERIAL_NUMBER *)pvStructInfo;
4195 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4196 pvStructInfo, *pcbStructInfo, pcbDecoded);
4198 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4199 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4200 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
4201 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
4203 SetLastError(CRYPT_E_ASN1_CORRUPT);
4206 TRACE("returning %d\n", ret);
4210 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
4211 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4214 CMSG_SIGNER_INFO *info = (CMSG_SIGNER_INFO *)pvStructInfo;
4215 struct AsnDecodeSequenceItem items[] = {
4216 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
4217 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4218 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
4219 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
4220 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
4221 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
4222 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4223 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4224 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4225 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
4226 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4227 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4228 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
4229 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4230 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
4231 HashEncryptionAlgorithm.pszObjId), 0 },
4232 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
4233 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4234 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
4235 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4236 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
4237 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4238 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4242 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4243 pvStructInfo, *pcbStructInfo);
4245 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4246 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4247 pcbDecoded, info ? info->Issuer.pbData : NULL);
4251 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
4252 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4253 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4257 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4258 pDecodePara, pvStructInfo, *pcbStructInfo);
4262 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
4263 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4264 if (ret && pvStructInfo)
4266 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4267 pcbStructInfo, *pcbStructInfo);
4270 CMSG_SIGNER_INFO *info;
4272 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4273 pvStructInfo = *(BYTE **)pvStructInfo;
4274 info = (CMSG_SIGNER_INFO *)pvStructInfo;
4275 info->Issuer.pbData = ((BYTE *)info +
4276 sizeof(CMSG_SIGNER_INFO));
4277 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
4278 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4279 pcbStructInfo, NULL);
4285 SetLastError(STATUS_ACCESS_VIOLATION);
4288 TRACE("returning %d\n", ret);
4292 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
4293 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4296 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
4297 CRYPT_AsnDecodePKCSSignerInfoInternal, sizeof(CMSG_SIGNER_INFO), TRUE,
4298 offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
4299 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4301 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4302 pvStructInfo, *pcbStructInfo, pcbDecoded);
4304 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4305 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4306 array ? array->rgItems : NULL);
4310 BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
4311 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
4312 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
4315 struct AsnDecodeSequenceItem items[] = {
4316 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
4317 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4318 /* Placeholder for the hash algorithms - redundant with those in the
4319 * signers, so just ignore them.
4321 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
4322 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
4323 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
4324 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
4325 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4326 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
4327 CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
4328 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
4329 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4330 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
4331 sizeof(struct GenericArray), TRUE, TRUE,
4332 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
4333 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
4334 CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
4335 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
4338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4339 pDecodePara, signedInfo, *pcbSignedInfo);
4341 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4342 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
4344 TRACE("returning %d\n", ret);
4348 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
4349 LPCSTR lpszStructType)
4351 CryptDecodeObjectExFunc decodeFunc = NULL;
4353 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
4354 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
4356 SetLastError(ERROR_FILE_NOT_FOUND);
4359 if (!HIWORD(lpszStructType))
4361 switch (LOWORD(lpszStructType))
4363 case LOWORD(X509_CERT):
4364 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
4366 case LOWORD(X509_CERT_TO_BE_SIGNED):
4367 decodeFunc = CRYPT_AsnDecodeCert;
4369 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
4370 decodeFunc = CRYPT_AsnDecodeCRL;
4372 case LOWORD(X509_EXTENSIONS):
4373 decodeFunc = CRYPT_AsnDecodeExtensions;
4375 case LOWORD(X509_NAME_VALUE):
4376 decodeFunc = CRYPT_AsnDecodeNameValue;
4378 case LOWORD(X509_NAME):
4379 decodeFunc = CRYPT_AsnDecodeName;
4381 case LOWORD(X509_PUBLIC_KEY_INFO):
4382 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
4384 case LOWORD(X509_AUTHORITY_KEY_ID):
4385 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4387 case LOWORD(X509_ALTERNATE_NAME):
4388 decodeFunc = CRYPT_AsnDecodeAltName;
4390 case LOWORD(X509_BASIC_CONSTRAINTS):
4391 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4393 case LOWORD(X509_BASIC_CONSTRAINTS2):
4394 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4396 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
4397 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
4399 case LOWORD(X509_UNICODE_NAME):
4400 decodeFunc = CRYPT_AsnDecodeUnicodeName;
4402 case LOWORD(PKCS_ATTRIBUTE):
4403 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
4405 case LOWORD(X509_UNICODE_NAME_VALUE):
4406 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
4408 case LOWORD(X509_OCTET_STRING):
4409 decodeFunc = CRYPT_AsnDecodeOctets;
4411 case LOWORD(X509_BITS):
4412 case LOWORD(X509_KEY_USAGE):
4413 decodeFunc = CRYPT_AsnDecodeBits;
4415 case LOWORD(X509_INTEGER):
4416 decodeFunc = CRYPT_AsnDecodeInt;
4418 case LOWORD(X509_MULTI_BYTE_INTEGER):
4419 decodeFunc = CRYPT_AsnDecodeInteger;
4421 case LOWORD(X509_MULTI_BYTE_UINT):
4422 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
4424 case LOWORD(X509_ENUMERATED):
4425 decodeFunc = CRYPT_AsnDecodeEnumerated;
4427 case LOWORD(X509_CHOICE_OF_TIME):
4428 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
4430 case LOWORD(X509_AUTHORITY_KEY_ID2):
4431 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4433 case LOWORD(PKCS_CONTENT_INFO):
4434 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
4436 case LOWORD(X509_SEQUENCE_OF_ANY):
4437 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
4439 case LOWORD(PKCS_UTC_TIME):
4440 decodeFunc = CRYPT_AsnDecodeUtcTime;
4442 case LOWORD(X509_CRL_DIST_POINTS):
4443 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4445 case LOWORD(X509_ENHANCED_KEY_USAGE):
4446 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4448 case LOWORD(PKCS_ATTRIBUTES):
4449 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
4451 case LOWORD(X509_ISSUING_DIST_POINT):
4452 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4454 case LOWORD(X509_NAME_CONSTRAINTS):
4455 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4457 case LOWORD(PKCS7_SIGNER_INFO):
4458 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
4462 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
4463 decodeFunc = CRYPT_AsnDecodeExtensions;
4464 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
4465 decodeFunc = CRYPT_AsnDecodeUtcTime;
4466 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
4467 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4468 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
4469 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4470 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
4471 decodeFunc = CRYPT_AsnDecodeEnumerated;
4472 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
4473 decodeFunc = CRYPT_AsnDecodeBits;
4474 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
4475 decodeFunc = CRYPT_AsnDecodeOctets;
4476 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
4477 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4478 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
4479 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4480 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
4481 decodeFunc = CRYPT_AsnDecodeAltName;
4482 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
4483 decodeFunc = CRYPT_AsnDecodeAltName;
4484 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
4485 decodeFunc = CRYPT_AsnDecodeAltName;
4486 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
4487 decodeFunc = CRYPT_AsnDecodeAltName;
4488 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
4489 decodeFunc = CRYPT_AsnDecodeAltName;
4490 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
4491 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4492 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
4493 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4494 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
4495 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4496 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
4497 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4501 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
4502 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4504 static HCRYPTOIDFUNCSET set = NULL;
4505 CryptDecodeObjectFunc decodeFunc = NULL;
4508 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
4509 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4510 (void **)&decodeFunc, hFunc);
4514 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
4515 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4517 static HCRYPTOIDFUNCSET set = NULL;
4518 CryptDecodeObjectExFunc decodeFunc = NULL;
4521 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
4522 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4523 (void **)&decodeFunc, hFunc);
4527 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4528 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
4529 DWORD *pcbStructInfo)
4532 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
4533 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
4534 HCRYPTOIDFUNCADDR hFunc = NULL;
4536 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
4537 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
4538 pvStructInfo, pcbStructInfo);
4540 if (!pvStructInfo && !pcbStructInfo)
4542 SetLastError(ERROR_INVALID_PARAMETER);
4547 SetLastError(CRYPT_E_ASN1_EOD);
4550 if (cbEncoded > MAX_ENCODED_LEN)
4552 SetLastError(CRYPT_E_ASN1_LARGE);
4556 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
4559 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4560 debugstr_a(lpszStructType));
4561 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
4562 lpszStructType, &hFunc);
4563 if (!pCryptDecodeObject)
4564 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
4565 lpszStructType, &hFunc);
4567 if (pCryptDecodeObject)
4568 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4569 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4570 else if (pCryptDecodeObjectEx)
4571 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
4572 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
4573 pvStructInfo, pcbStructInfo);
4575 CryptFreeOIDFunctionAddress(hFunc, 0);
4576 TRACE_(crypt)("returning %d\n", ret);
4580 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4581 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4582 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4585 CryptDecodeObjectExFunc decodeFunc;
4586 HCRYPTOIDFUNCADDR hFunc = NULL;
4588 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4589 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
4590 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4592 if (!pvStructInfo && !pcbStructInfo)
4594 SetLastError(ERROR_INVALID_PARAMETER);
4599 SetLastError(CRYPT_E_ASN1_EOD);
4602 if (cbEncoded > MAX_ENCODED_LEN)
4604 SetLastError(CRYPT_E_ASN1_LARGE);
4608 SetLastError(NOERROR);
4609 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
4610 *(BYTE **)pvStructInfo = NULL;
4611 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
4614 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4615 debugstr_a(lpszStructType));
4616 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
4620 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
4621 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4624 CryptDecodeObjectFunc pCryptDecodeObject =
4625 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
4627 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4628 * directly, as that could cause an infinite loop.
4630 if (pCryptDecodeObject)
4632 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4634 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4635 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
4636 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4637 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
4638 ret = pCryptDecodeObject(dwCertEncodingType,
4639 lpszStructType, pbEncoded, cbEncoded, dwFlags,
4640 *(BYTE **)pvStructInfo, pcbStructInfo);
4643 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4644 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4648 CryptFreeOIDFunctionAddress(hFunc, 0);
4649 TRACE_(crypt)("returning %d\n", ret);