2 * Copyright 2005-2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt);
67 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
68 DWORD, DWORD, void *, DWORD *);
69 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
70 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
76 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
78 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
79 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
81 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
82 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
88 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
92 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
93 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
94 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
97 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
99 /* Doesn't check the tag, assumes the caller does so */
100 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
101 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
102 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
103 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
104 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
105 * member has been initialized, doesn't do exception handling, and doesn't do
106 * memory allocation. Also doesn't check tag, assumes the caller has checked
109 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
110 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
112 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
113 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
114 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
116 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
117 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
120 /* Gets the number of length bytes from the given (leading) length byte */
121 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
123 /* Helper function to get the encoded length of the data starting at pbEncoded,
124 * where pbEncoded[0] is the tag. If the data are too short to contain a
125 * length or if the length is too large for cbEncoded, sets an appropriate
126 * error code and returns FALSE. If the encoded length is unknown due to
127 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
129 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
136 SetLastError(CRYPT_E_ASN1_CORRUPT);
139 else if (pbEncoded[1] <= 0x7f)
141 if (pbEncoded[1] + 1 > cbEncoded)
143 SetLastError(CRYPT_E_ASN1_EOD);
152 else if (pbEncoded[1] == 0x80)
154 *len = CMSG_INDEFINITE_LENGTH;
159 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
161 if (lenLen > sizeof(DWORD) + 1)
163 SetLastError(CRYPT_E_ASN1_LARGE);
166 else if (lenLen + 2 > cbEncoded)
168 SetLastError(CRYPT_E_ASN1_CORRUPT);
181 if (out + lenLen + 1 > cbEncoded)
183 SetLastError(CRYPT_E_ASN1_EOD);
196 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
197 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
201 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
202 *len == CMSG_INDEFINITE_LENGTH)
204 SetLastError(CRYPT_E_ASN1_CORRUPT);
210 /* Helper function to check *pcbStructInfo, set it to the required size, and
211 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
212 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
213 * pointer to the newly allocated memory.
215 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
216 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
221 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
223 if (pDecodePara && pDecodePara->pfnAlloc)
224 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
226 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
227 if (!*(BYTE **)pvStructInfo)
230 *pcbStructInfo = bytesNeeded;
232 else if (*pcbStructInfo < bytesNeeded)
234 *pcbStructInfo = bytesNeeded;
235 SetLastError(ERROR_MORE_DATA);
239 *pcbStructInfo = bytesNeeded;
243 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
245 if (pDecodePara && pDecodePara->pfnFree)
246 pDecodePara->pfnFree(pv);
251 /* Helper function to check *pcbStructInfo and set it to the required size.
252 * Assumes pvStructInfo is not NULL.
254 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
258 if (*pcbStructInfo < bytesNeeded)
260 *pcbStructInfo = bytesNeeded;
261 SetLastError(ERROR_MORE_DATA);
266 *pcbStructInfo = bytesNeeded;
273 * The expected tag of the item. If tag is 0, decodeFunc is called
274 * regardless of the tag value seen.
276 * A sequence is decoded into a struct. The offset member is the
277 * offset of this item within that struct.
279 * The decoder function to use. If this is NULL, then the member isn't
280 * decoded, but minSize space is reserved for it.
282 * The minimum amount of space occupied after decoding. You must set this.
284 * If true, and the tag doesn't match the expected tag for this item,
285 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
286 * filled with 0 for this member.
287 * hasPointer, pointerOffset:
288 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
289 * the offset within the struct of the data pointer (or to the
290 * first data pointer, if more than one exist).
292 * Used by CRYPT_AsnDecodeSequence, not for your use.
294 struct AsnDecodeSequenceItem
298 InternalDecodeFunc decodeFunc;
306 /* Decodes the items in a sequence, where the items are described in items,
307 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
308 * pvStructInfo. nextData is a pointer to the memory location at which the
309 * first decoded item with a dynamic pointer should point.
310 * Upon decoding, *cbDecoded is the total number of bytes decoded.
311 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
313 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
314 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
315 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
318 DWORD i, decoded = 0;
319 const BYTE *ptr = pbEncoded;
321 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
322 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
324 for (i = 0, ret = TRUE; ret && i < cItem; i++)
326 if (cbEncoded - (ptr - pbEncoded) != 0)
330 if ((ret = CRYPT_GetLengthIndefinite(ptr,
331 cbEncoded - (ptr - pbEncoded), &itemLen)))
333 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
335 if (ptr[0] == items[i].tag || !items[i].tag)
337 DWORD itemEncodedLen;
339 if (itemLen == CMSG_INDEFINITE_LENGTH)
340 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
342 itemEncodedLen = 1 + itemLenBytes + itemLen;
343 if (nextData && pvStructInfo && items[i].hasPointer)
345 TRACE("Setting next pointer to %p\n",
347 *(BYTE **)((BYTE *)pvStructInfo +
348 items[i].pointerOffset) = nextData;
350 if (items[i].decodeFunc)
355 TRACE("decoding item %d\n", i);
357 TRACE("sizing item %d\n", i);
358 ret = items[i].decodeFunc(ptr, itemEncodedLen,
359 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
360 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
361 : NULL, &items[i].size, &itemDecoded);
364 /* Account for alignment padding */
365 items[i].size = ALIGN_DWORD_PTR(items[i].size);
366 TRACE("item %d size: %d\n", i, items[i].size);
367 if (nextData && items[i].hasPointer &&
368 items[i].size > items[i].minSize)
369 nextData += items[i].size - items[i].minSize;
370 if (itemDecoded > itemEncodedLen)
372 WARN("decoded length %d exceeds encoded %d\n",
373 itemDecoded, itemEncodedLen);
374 SetLastError(CRYPT_E_ASN1_CORRUPT);
379 if (itemLen == CMSG_INDEFINITE_LENGTH)
381 if (itemDecoded > itemEncodedLen - 2 ||
382 *(ptr + itemDecoded) != 0 ||
383 *(ptr + itemDecoded + 1) != 0)
385 TRACE("expected 0 TLV\n");
386 SetLastError(CRYPT_E_ASN1_CORRUPT);
395 decoded += itemDecoded;
396 TRACE("item %d: decoded %d bytes\n", i,
401 else if (items[i].optional &&
402 GetLastError() == CRYPT_E_ASN1_BADTAG)
404 TRACE("skipping optional item %d\n", i);
405 items[i].size = items[i].minSize;
406 SetLastError(NOERROR);
410 TRACE("item %d failed: %08x\n", i,
413 else if (itemLen == CMSG_INDEFINITE_LENGTH)
415 ERR("can't use indefinite length encoding without a decoder\n");
416 SetLastError(CRYPT_E_ASN1_CORRUPT);
421 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
422 ptr += itemEncodedLen;
423 decoded += itemEncodedLen;
424 items[i].size = items[i].minSize;
427 else if (items[i].optional)
429 TRACE("skipping optional item %d\n", i);
430 items[i].size = items[i].minSize;
434 TRACE("item %d: tag %02x doesn't match expected %02x\n",
435 i, ptr[0], items[i].tag);
436 SetLastError(CRYPT_E_ASN1_BADTAG);
441 else if (items[i].optional)
443 TRACE("missing optional item %d, skipping\n", i);
444 items[i].size = items[i].minSize;
448 TRACE("not enough bytes for item %d, failing\n", i);
449 SetLastError(CRYPT_E_ASN1_CORRUPT);
454 *cbDecoded = decoded;
455 TRACE("returning %d\n", ret);
459 /* This decodes an arbitrary sequence into a contiguous block of memory
460 * (basically, a struct.) Each element being decoded is described by a struct
461 * AsnDecodeSequenceItem, see above.
462 * startingPointer is an optional pointer to the first place where dynamic
463 * data will be stored. If you know the starting offset, you may pass it
464 * here. Otherwise, pass NULL, and one will be inferred from the items.
466 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
467 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
468 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
469 DWORD *pcbDecoded, void *startingPointer)
473 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
474 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
479 SetLastError(CRYPT_E_ASN1_EOD);
482 if (pbEncoded[0] == ASN_SEQUENCE)
486 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
488 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
489 const BYTE *ptr = pbEncoded + 1 + lenBytes;
490 BOOL indefinite = FALSE;
492 cbEncoded -= 1 + lenBytes;
493 if (dataLen == CMSG_INDEFINITE_LENGTH)
498 else if (cbEncoded < dataLen)
500 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
502 SetLastError(CRYPT_E_ASN1_CORRUPT);
507 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
508 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
509 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
511 if (cbDecoded > cbEncoded - 2)
513 /* Not enough space for 0 TLV */
514 SetLastError(CRYPT_E_ASN1_CORRUPT);
517 else if (*(ptr + cbDecoded) != 0 ||
518 *(ptr + cbDecoded + 1) != 0)
520 TRACE("expected 0 TLV\n");
521 SetLastError(CRYPT_E_ASN1_CORRUPT);
528 if (ret && !indefinite && cbDecoded != dataLen)
530 TRACE("expected %d decoded, got %d, failing\n", dataLen,
532 SetLastError(CRYPT_E_ASN1_CORRUPT);
537 DWORD i, bytesNeeded = 0, structSize = 0;
539 for (i = 0; i < cItem; i++)
541 bytesNeeded += items[i].size;
542 structSize += items[i].minSize;
545 *pcbDecoded = 1 + lenBytes + cbDecoded;
547 *pcbStructInfo = bytesNeeded;
548 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
549 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
553 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
554 pvStructInfo = *(BYTE **)pvStructInfo;
556 nextData = (BYTE *)startingPointer;
558 nextData = (BYTE *)pvStructInfo + structSize;
559 memset(pvStructInfo, 0, structSize);
560 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
561 ptr, dataLen, dwFlags, pvStructInfo, nextData,
563 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
564 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
571 SetLastError(CRYPT_E_ASN1_BADTAG);
574 TRACE("returning %d (%08x)\n", ret, GetLastError());
579 * The expected tag of the entire encoded array (usually a variant
580 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
581 * regardless of the tag seen.
583 * used to decode each item in the array
585 * is the minimum size of each decoded item
587 * indicates whether each item has a dynamic pointer
589 * indicates the offset within itemSize at which the pointer exists
591 struct AsnArrayDescriptor
594 InternalDecodeFunc decodeFunc;
600 struct AsnArrayItemSize
606 /* Decodes an array of like types into a struct GenericArray.
607 * The layout and decoding of the array are described by a struct
608 * AsnArrayDescriptor.
610 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
611 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
612 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
613 DWORD *pcbDecoded, void *startingPointer)
617 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
618 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
621 if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
625 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
627 DWORD bytesNeeded, cItems = 0, decoded;
628 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
629 /* There can be arbitrarily many items, but there is often only one.
631 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
633 decoded = 1 + lenBytes;
634 bytesNeeded = sizeof(struct GenericArray);
638 BOOL doneDecoding = FALSE;
640 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
642 if (dataLen == CMSG_INDEFINITE_LENGTH)
649 SetLastError(CRYPT_E_ASN1_CORRUPT);
656 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
660 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
662 /* Each item decoded may not tolerate extraneous bytes,
663 * so get the length of the next element if known.
665 if ((ret = CRYPT_GetLengthIndefinite(ptr,
666 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
668 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
669 itemEncoded = cbEncoded - (ptr - pbEncoded);
671 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
675 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
676 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
681 if (itemSizes != &itemSize)
682 itemSizes = CryptMemRealloc(itemSizes,
683 cItems * sizeof(struct AsnArrayItemSize));
688 cItems * sizeof(struct AsnArrayItemSize));
690 memcpy(itemSizes, &itemSize,
695 decoded += itemDecoded;
696 itemSizes[cItems - 1].encodedLen = itemEncoded;
697 itemSizes[cItems - 1].size = size;
710 *pcbDecoded = decoded;
712 *pcbStructInfo = bytesNeeded;
713 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
714 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
719 struct GenericArray *array;
721 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
722 pvStructInfo = *(BYTE **)pvStructInfo;
723 array = (struct GenericArray *)pvStructInfo;
724 array->cItems = cItems;
726 array->rgItems = startingPointer;
728 array->rgItems = (BYTE *)array +
729 sizeof(struct GenericArray);
730 nextData = array->rgItems +
731 array->cItems * arrayDesc->itemSize;
732 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
733 i < cItems && ptr - pbEncoded - 1 - lenBytes <
738 if (arrayDesc->hasPointer)
739 *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
740 + arrayDesc->pointerOffset) = nextData;
741 ret = arrayDesc->decodeFunc(ptr,
742 itemSizes[i].encodedLen,
743 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
744 array->rgItems + i * arrayDesc->itemSize,
745 &itemSizes[i].size, &itemDecoded);
748 nextData += itemSizes[i].size - arrayDesc->itemSize;
752 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
753 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
756 if (itemSizes != &itemSize)
757 CryptMemFree(itemSizes);
762 SetLastError(CRYPT_E_ASN1_BADTAG);
768 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
769 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
770 * to CRYPT_E_ASN1_CORRUPT.
771 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
774 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
775 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
780 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
782 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
783 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
785 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
786 bytesNeeded += 1 + lenBytes + dataLen;
789 *pcbDecoded = 1 + lenBytes + dataLen;
791 *pcbStructInfo = bytesNeeded;
792 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
794 CRYPT_DER_BLOB *blob;
796 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
797 pvStructInfo = *(BYTE **)pvStructInfo;
798 blob = (CRYPT_DER_BLOB *)pvStructInfo;
799 blob->cbData = 1 + lenBytes + dataLen;
802 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
803 blob->pbData = (BYTE *)pbEncoded;
806 assert(blob->pbData);
807 memcpy(blob->pbData, pbEncoded, blob->cbData);
812 SetLastError(CRYPT_E_ASN1_CORRUPT);
820 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
821 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
822 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
827 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
828 pvStructInfo, *pcbStructInfo, pcbDecoded);
830 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
833 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
834 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
836 if (ret && pvStructInfo)
838 CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
845 for (i = 0; i < blob->cbData / 2; i++)
847 temp = blob->pbData[i];
848 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
849 blob->pbData[blob->cbData - i - 1] = temp;
853 TRACE("returning %d (%08x)\n", ret, GetLastError());
857 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
858 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
859 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
863 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
864 pDecodePara, pvStructInfo, *pcbStructInfo);
868 struct AsnDecodeSequenceItem items[] = {
869 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
870 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
871 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
872 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
873 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
874 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
875 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
876 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
877 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
878 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
881 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
882 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
883 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
884 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
885 pcbStructInfo, NULL, NULL);
889 SetLastError(STATUS_ACCESS_VIOLATION);
894 TRACE("Returning %d (%08x)\n", ret, GetLastError());
898 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
899 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
904 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
906 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
908 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
909 dwFlags, pvStructInfo, pcbStructInfo, NULL);
911 *pcbDecoded = 1 + lenBytes + dataLen;
916 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
917 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
921 struct AsnDecodeSequenceItem items[] = {
922 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
923 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
924 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
925 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
928 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
929 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
934 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
935 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
941 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
943 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
945 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
946 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
947 if (ret && pcbDecoded)
948 *pcbDecoded = 1 + lenBytes + dataLen;
953 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
954 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
955 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
958 struct AsnDecodeSequenceItem items[] = {
959 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
960 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
961 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
962 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
963 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
964 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
965 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
966 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
967 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
968 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
970 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
971 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
973 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
974 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
976 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
977 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
978 FALSE, TRUE, offsetof(CERT_INFO,
979 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
980 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
981 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
982 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
983 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
984 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
985 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
986 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
987 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
988 offsetof(CERT_INFO, rgExtension), 0 },
991 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
992 pDecodePara, pvStructInfo, *pcbStructInfo);
994 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
995 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
997 if (ret && pvStructInfo)
1001 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1002 info = *(CERT_INFO **)pvStructInfo;
1004 info = (CERT_INFO *)pvStructInfo;
1005 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1006 !info->Subject.cbData)
1008 SetLastError(CRYPT_E_ASN1_CORRUPT);
1009 /* Don't need to deallocate, because it should have failed on the
1010 * first pass (and no memory was allocated.)
1016 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1020 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1021 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1022 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1026 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1027 pDecodePara, pvStructInfo, *pcbStructInfo);
1033 /* Unless told not to, first try to decode it as a signed cert. */
1034 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1036 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1038 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1039 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1040 (BYTE *)&signedCert, &size);
1044 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1045 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1046 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1047 pvStructInfo, pcbStructInfo);
1048 LocalFree(signedCert);
1051 /* Failing that, try it as an unsigned cert */
1055 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1056 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1057 pDecodePara, pvStructInfo, pcbStructInfo);
1062 SetLastError(STATUS_ACCESS_VIOLATION);
1066 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1070 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1071 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1074 struct AsnDecodeSequenceItem items[] = {
1075 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1076 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1077 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1078 { 0, offsetof(CRL_ENTRY, RevocationDate),
1079 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1080 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1081 CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1082 offsetof(CRL_ENTRY, rgExtension), 0 },
1084 PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1086 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1089 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1090 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1091 entry ? entry->SerialNumber.pbData : NULL);
1092 if (ret && entry && !entry->SerialNumber.cbData)
1094 WARN("empty CRL entry serial number\n");
1095 SetLastError(CRYPT_E_ASN1_CORRUPT);
1101 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1102 * been set prior to calling.
1104 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1105 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1108 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1109 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1110 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1111 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1113 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1114 pvStructInfo, *pcbStructInfo, pcbDecoded);
1116 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1117 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1118 entries ? entries->rgItems : NULL);
1119 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1123 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1124 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1125 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1127 struct AsnDecodeSequenceItem items[] = {
1128 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1129 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1130 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1131 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1132 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1133 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1134 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1136 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1137 sizeof(FILETIME), FALSE, FALSE, 0 },
1138 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1139 sizeof(FILETIME), TRUE, FALSE, 0 },
1140 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1141 CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1142 offsetof(CRL_INFO, rgCRLEntry), 0 },
1143 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1144 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1145 offsetof(CRL_INFO, rgExtension), 0 },
1149 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1150 pDecodePara, pvStructInfo, *pcbStructInfo);
1152 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1153 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1156 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1160 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1161 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1162 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1166 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1167 pDecodePara, pvStructInfo, *pcbStructInfo);
1173 /* Unless told not to, first try to decode it as a signed crl. */
1174 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1176 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1178 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1179 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1180 (BYTE *)&signedCrl, &size);
1184 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1185 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1186 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1187 pvStructInfo, pcbStructInfo);
1188 LocalFree(signedCrl);
1191 /* Failing that, try it as an unsigned crl */
1195 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1196 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1197 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1202 SetLastError(STATUS_ACCESS_VIOLATION);
1206 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1210 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1211 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1216 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1217 pvStructInfo, *pcbStructInfo);
1219 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1221 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1222 DWORD bytesNeeded = sizeof(LPSTR);
1226 /* The largest possible string for the first two components
1227 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1232 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1233 pbEncoded[1 + lenBytes] / 40,
1234 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1236 bytesNeeded += strlen(firstTwo) + 1;
1237 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1238 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1240 /* large enough for ".4000000" */
1244 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1251 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1254 SetLastError(CRYPT_E_ASN1_CORRUPT);
1261 snprintf(str, sizeof(str), ".%d", val);
1262 bytesNeeded += strlen(str);
1267 *pcbDecoded = 1 + lenBytes + dataLen;
1269 *pcbStructInfo = bytesNeeded;
1270 else if (*pcbStructInfo < bytesNeeded)
1272 *pcbStructInfo = bytesNeeded;
1273 SetLastError(ERROR_MORE_DATA);
1281 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1284 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1285 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1287 pszObjId += strlen(pszObjId);
1288 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1289 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1293 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1302 sprintf(pszObjId, ".%d", val);
1303 pszObjId += strlen(pszObjId);
1307 *(LPSTR *)pvStructInfo = NULL;
1308 *pcbStructInfo = bytesNeeded;
1314 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1315 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1319 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1320 pvStructInfo, *pcbStructInfo);
1322 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1323 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1324 pvStructInfo, pcbStructInfo, pcbDecoded);
1327 SetLastError(CRYPT_E_ASN1_BADTAG);
1333 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1336 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1337 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1339 struct AsnDecodeSequenceItem items[] = {
1340 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1341 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1342 offsetof(CERT_EXTENSION, pszObjId), 0 },
1343 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1344 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1345 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1346 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1347 offsetof(CERT_EXTENSION, Value.pbData) },
1350 PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1352 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1356 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1357 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1358 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1359 pcbDecoded, ext ? ext->pszObjId : NULL);
1361 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1362 debugstr_a(ext->pszObjId));
1363 TRACE("returning %d (%08x)\n", ret, GetLastError());
1367 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1368 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1372 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1373 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1374 offsetof(CERT_EXTENSION, pszObjId) };
1375 PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1377 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1378 pvStructInfo, *pcbStructInfo, pcbDecoded);
1380 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1381 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1382 exts ? exts->rgExtension : NULL);
1386 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1387 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1388 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1394 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1395 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1396 if (ret && pvStructInfo)
1398 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1399 pcbStructInfo, *pcbStructInfo);
1402 CERT_EXTENSIONS *exts;
1404 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1405 pvStructInfo = *(BYTE **)pvStructInfo;
1406 exts = (CERT_EXTENSIONS *)pvStructInfo;
1407 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1408 sizeof(CERT_EXTENSIONS));
1409 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1410 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1411 pcbStructInfo, NULL);
1417 SetLastError(STATUS_ACCESS_VIOLATION);
1424 /* Warning: this assumes the address of value->Value.pbData is already set, in
1425 * order to avoid overwriting memory. (In some cases, it may change it, if it
1426 * doesn't copy anything to memory.) Be sure to set it correctly!
1428 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1429 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1434 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1436 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1438 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1439 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1441 switch (pbEncoded[0])
1443 case ASN_OCTETSTRING:
1444 valueType = CERT_RDN_OCTET_STRING;
1445 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1446 bytesNeeded += dataLen;
1448 case ASN_NUMERICSTRING:
1449 valueType = CERT_RDN_NUMERIC_STRING;
1450 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1451 bytesNeeded += dataLen;
1453 case ASN_PRINTABLESTRING:
1454 valueType = CERT_RDN_PRINTABLE_STRING;
1455 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1456 bytesNeeded += dataLen;
1459 valueType = CERT_RDN_IA5_STRING;
1460 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1461 bytesNeeded += dataLen;
1464 valueType = CERT_RDN_T61_STRING;
1465 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1466 bytesNeeded += dataLen;
1468 case ASN_VIDEOTEXSTRING:
1469 valueType = CERT_RDN_VIDEOTEX_STRING;
1470 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1471 bytesNeeded += dataLen;
1473 case ASN_GRAPHICSTRING:
1474 valueType = CERT_RDN_GRAPHIC_STRING;
1475 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1476 bytesNeeded += dataLen;
1478 case ASN_VISIBLESTRING:
1479 valueType = CERT_RDN_VISIBLE_STRING;
1480 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1481 bytesNeeded += dataLen;
1483 case ASN_GENERALSTRING:
1484 valueType = CERT_RDN_GENERAL_STRING;
1485 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1486 bytesNeeded += dataLen;
1488 case ASN_UNIVERSALSTRING:
1489 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1490 SetLastError(CRYPT_E_ASN1_BADTAG);
1493 valueType = CERT_RDN_BMP_STRING;
1494 bytesNeeded += dataLen;
1496 case ASN_UTF8STRING:
1497 valueType = CERT_RDN_UTF8_STRING;
1498 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1499 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1502 SetLastError(CRYPT_E_ASN1_BADTAG);
1507 *pcbDecoded = 1 + lenBytes + dataLen;
1509 *pcbStructInfo = bytesNeeded;
1510 else if (*pcbStructInfo < bytesNeeded)
1512 *pcbStructInfo = bytesNeeded;
1513 SetLastError(ERROR_MORE_DATA);
1518 *pcbStructInfo = bytesNeeded;
1519 value->dwValueType = valueType;
1524 assert(value->Value.pbData);
1525 switch (pbEncoded[0])
1527 case ASN_OCTETSTRING:
1528 case ASN_NUMERICSTRING:
1529 case ASN_PRINTABLESTRING:
1532 case ASN_VIDEOTEXSTRING:
1533 case ASN_GRAPHICSTRING:
1534 case ASN_VISIBLESTRING:
1535 case ASN_GENERALSTRING:
1536 value->Value.cbData = dataLen;
1539 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1540 memcpy(value->Value.pbData,
1541 pbEncoded + 1 + lenBytes, dataLen);
1543 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1549 LPWSTR str = (LPWSTR)value->Value.pbData;
1551 value->Value.cbData = dataLen;
1552 for (i = 0; i < dataLen / 2; i++)
1553 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1554 pbEncoded[1 + lenBytes + 2 * i + 1];
1557 case ASN_UTF8STRING:
1559 LPWSTR str = (LPWSTR)value->Value.pbData;
1561 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1562 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1563 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1570 value->Value.cbData = 0;
1571 value->Value.pbData = NULL;
1578 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1579 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1580 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1586 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1587 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1588 if (ret && pvStructInfo)
1590 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1591 pcbStructInfo, *pcbStructInfo);
1594 CERT_NAME_VALUE *value;
1596 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1597 pvStructInfo = *(BYTE **)pvStructInfo;
1598 value = (CERT_NAME_VALUE *)pvStructInfo;
1599 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1600 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1601 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1602 pcbStructInfo, NULL);
1608 SetLastError(STATUS_ACCESS_VIOLATION);
1615 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1616 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1621 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1623 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1625 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1626 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1628 switch (pbEncoded[0])
1630 case ASN_NUMERICSTRING:
1631 valueType = CERT_RDN_NUMERIC_STRING;
1633 bytesNeeded += (dataLen + 1) * 2;
1635 case ASN_PRINTABLESTRING:
1636 valueType = CERT_RDN_PRINTABLE_STRING;
1638 bytesNeeded += (dataLen + 1) * 2;
1641 valueType = CERT_RDN_IA5_STRING;
1643 bytesNeeded += (dataLen + 1) * 2;
1646 valueType = CERT_RDN_T61_STRING;
1648 bytesNeeded += (dataLen + 1) * 2;
1650 case ASN_VIDEOTEXSTRING:
1651 valueType = CERT_RDN_VIDEOTEX_STRING;
1653 bytesNeeded += (dataLen + 1) * 2;
1655 case ASN_GRAPHICSTRING:
1656 valueType = CERT_RDN_GRAPHIC_STRING;
1658 bytesNeeded += (dataLen + 1) * 2;
1660 case ASN_VISIBLESTRING:
1661 valueType = CERT_RDN_VISIBLE_STRING;
1663 bytesNeeded += (dataLen + 1) * 2;
1665 case ASN_GENERALSTRING:
1666 valueType = CERT_RDN_GENERAL_STRING;
1668 bytesNeeded += (dataLen + 1) * 2;
1670 case ASN_UNIVERSALSTRING:
1671 valueType = CERT_RDN_UNIVERSAL_STRING;
1673 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1676 valueType = CERT_RDN_BMP_STRING;
1678 bytesNeeded += dataLen + sizeof(WCHAR);
1680 case ASN_UTF8STRING:
1681 valueType = CERT_RDN_UTF8_STRING;
1683 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1684 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1687 SetLastError(CRYPT_E_ASN1_BADTAG);
1692 *pcbDecoded = 1 + lenBytes + dataLen;
1694 *pcbStructInfo = bytesNeeded;
1695 else if (*pcbStructInfo < bytesNeeded)
1697 *pcbStructInfo = bytesNeeded;
1698 SetLastError(ERROR_MORE_DATA);
1703 *pcbStructInfo = bytesNeeded;
1704 value->dwValueType = valueType;
1708 LPWSTR str = (LPWSTR)value->Value.pbData;
1710 assert(value->Value.pbData);
1711 switch (pbEncoded[0])
1713 case ASN_NUMERICSTRING:
1714 case ASN_PRINTABLESTRING:
1717 case ASN_VIDEOTEXSTRING:
1718 case ASN_GRAPHICSTRING:
1719 case ASN_VISIBLESTRING:
1720 case ASN_GENERALSTRING:
1721 value->Value.cbData = dataLen * 2;
1722 for (i = 0; i < dataLen; i++)
1723 str[i] = pbEncoded[1 + lenBytes + i];
1726 case ASN_UNIVERSALSTRING:
1727 value->Value.cbData = dataLen / 2;
1728 for (i = 0; i < dataLen / 4; i++)
1729 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1730 | pbEncoded[1 + lenBytes + 2 * i + 3];
1734 value->Value.cbData = dataLen;
1735 for (i = 0; i < dataLen / 2; i++)
1736 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1737 pbEncoded[1 + lenBytes + 2 * i + 1];
1740 case ASN_UTF8STRING:
1741 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1742 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1743 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1744 value->Value.pbData[value->Value.cbData / sizeof(WCHAR)]
1746 value->Value.cbData += sizeof(WCHAR);
1752 value->Value.cbData = 0;
1753 value->Value.pbData = NULL;
1760 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1761 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1762 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1768 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1769 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1770 if (ret && pvStructInfo)
1772 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1773 pcbStructInfo, *pcbStructInfo);
1776 CERT_NAME_VALUE *value;
1778 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1779 pvStructInfo = *(BYTE **)pvStructInfo;
1780 value = (CERT_NAME_VALUE *)pvStructInfo;
1781 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1782 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1783 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1784 pcbStructInfo, NULL);
1790 SetLastError(STATUS_ACCESS_VIOLATION);
1797 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1798 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1801 struct AsnDecodeSequenceItem items[] = {
1802 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1803 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1804 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1805 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1806 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1807 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1809 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1811 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1812 pvStructInfo, *pcbStructInfo);
1815 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1816 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1817 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1818 attr ? attr->pszObjId : NULL);
1821 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1822 debugstr_a(attr->pszObjId));
1823 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1825 TRACE("returning %d (%08x)\n", ret, GetLastError());
1829 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1830 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1833 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1834 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1835 offsetof(CERT_RDN_ATTR, pszObjId) };
1836 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1838 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1839 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1840 rdn ? rdn->rgRDNAttr : NULL);
1844 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1845 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1846 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1852 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1853 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1854 offsetof(CERT_RDN, rgRDNAttr) };
1856 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1857 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1861 SetLastError(STATUS_ACCESS_VIOLATION);
1868 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1869 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1873 struct AsnDecodeSequenceItem items[] = {
1874 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1875 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1876 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1877 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1878 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1879 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1881 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1883 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1884 pvStructInfo, *pcbStructInfo);
1887 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1888 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1889 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1890 attr ? attr->pszObjId : NULL);
1893 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1894 debugstr_a(attr->pszObjId));
1895 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1897 TRACE("returning %d (%08x)\n", ret, GetLastError());
1901 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1902 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1905 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1906 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1907 offsetof(CERT_RDN_ATTR, pszObjId) };
1908 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1910 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1911 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1912 rdn ? rdn->rgRDNAttr : NULL);
1916 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1917 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1918 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1924 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1925 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1926 offsetof(CERT_RDN, rgRDNAttr) };
1928 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1929 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1933 SetLastError(STATUS_ACCESS_VIOLATION);
1940 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1943 BOOL ret = TRUE, done = FALSE;
1944 DWORD indefiniteNestingLevels = 0, decoded = 0;
1946 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1953 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1956 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1958 if (dataLen == CMSG_INDEFINITE_LENGTH)
1960 indefiniteNestingLevels++;
1961 pbEncoded += 1 + lenBytes;
1962 cbEncoded -= 1 + lenBytes;
1963 decoded += 1 + lenBytes;
1964 TRACE("indefiniteNestingLevels = %d\n",
1965 indefiniteNestingLevels);
1969 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1970 indefiniteNestingLevels)
1972 indefiniteNestingLevels--;
1973 TRACE("indefiniteNestingLevels = %d\n",
1974 indefiniteNestingLevels);
1976 pbEncoded += 1 + lenBytes + dataLen;
1977 cbEncoded -= 1 + lenBytes + dataLen;
1978 decoded += 1 + lenBytes + dataLen;
1979 if (!indefiniteNestingLevels)
1983 } while (ret && !done);
1984 /* If we haven't found all 0 TLVs, we haven't found the end */
1985 if (ret && indefiniteNestingLevels)
1987 SetLastError(CRYPT_E_ASN1_EOD);
1991 *pcbDecoded = decoded;
1992 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1996 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1997 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2001 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2003 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2004 pvStructInfo, *pcbStructInfo);
2006 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2008 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2009 bytesNeeded += encodedLen;
2011 *pcbStructInfo = bytesNeeded;
2012 else if (*pcbStructInfo < bytesNeeded)
2014 SetLastError(ERROR_MORE_DATA);
2015 *pcbStructInfo = bytesNeeded;
2020 PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
2022 *pcbStructInfo = bytesNeeded;
2023 blob->cbData = encodedLen;
2026 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2027 blob->pbData = (LPBYTE)pbEncoded;
2030 assert(blob->pbData);
2031 memcpy(blob->pbData, pbEncoded, blob->cbData);
2035 blob->pbData = NULL;
2038 *pcbDecoded = encodedLen;
2043 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
2044 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2047 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2048 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2049 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
2051 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2052 pvStructInfo, *pcbStructInfo, pcbDecoded);
2054 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2055 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2056 array ? array->rgItems : NULL);
2060 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2061 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2064 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2065 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2066 CTL_USAGE *usage = (CTL_USAGE *)pvStructInfo;
2068 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2069 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2070 usage ? usage->rgpszUsageIdentifier : NULL);
2074 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2075 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2077 struct AsnDecodeSequenceItem items[] = {
2078 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2079 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2080 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2081 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2082 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE,
2083 TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 },
2086 CTL_ENTRY *entry = (CTL_ENTRY *)pvStructInfo;
2088 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2091 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2092 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2093 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2097 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2098 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2101 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2102 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2103 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2104 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2106 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2107 pvStructInfo, *pcbStructInfo, pcbDecoded);
2109 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2110 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2111 entries ? entries->rgItems : NULL);
2115 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2116 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2117 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2121 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2122 pDecodePara, pvStructInfo, *pcbStructInfo);
2126 struct AsnDecodeSequenceItem items[] = {
2127 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2128 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2129 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2130 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2131 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2132 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2133 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2134 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2135 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2136 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2137 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2138 { 0, offsetof(CTL_INFO, ThisUpdate),
2139 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2141 { 0, offsetof(CTL_INFO, NextUpdate),
2142 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2144 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2145 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2146 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2147 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2148 CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray),
2149 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2150 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2151 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
2152 offsetof(CTL_INFO, rgExtension), 0 },
2155 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2156 pDecodePara, pvStructInfo, *pcbStructInfo);
2158 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2159 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2160 pcbStructInfo, NULL, NULL);
2164 SetLastError(STATUS_ACCESS_VIOLATION);
2170 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2171 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2175 struct AsnDecodeSequenceItem items[] = {
2176 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2177 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2178 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2179 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2180 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2181 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2183 PCRYPT_SMIME_CAPABILITY capability = (PCRYPT_SMIME_CAPABILITY)pvStructInfo;
2185 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2186 pvStructInfo, *pcbStructInfo);
2188 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2189 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2190 pcbDecoded, capability ? capability->pszObjId : NULL);
2191 TRACE("returning %d\n", ret);
2195 static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded,
2196 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2199 struct AsnArrayDescriptor arrayDesc = { 0,
2200 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2201 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2202 PCRYPT_SMIME_CAPABILITIES capabilities =
2203 (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2206 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2207 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2208 capabilities ? capabilities->rgCapability : NULL);
2212 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2213 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2214 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2218 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2219 pDecodePara, pvStructInfo, *pcbStructInfo);
2226 SetLastError(CRYPT_E_ASN1_EOD);
2227 else if (pbEncoded[0] != ASN_SEQUENCEOF)
2228 SetLastError(CRYPT_E_ASN1_CORRUPT);
2229 else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2230 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2234 *pcbStructInfo = bytesNeeded;
2235 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2236 pvStructInfo, pcbStructInfo, bytesNeeded)))
2238 PCRYPT_SMIME_CAPABILITIES capabilities;
2240 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2241 pvStructInfo = *(BYTE **)pvStructInfo;
2242 capabilities = (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2243 capabilities->rgCapability =
2244 (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2245 sizeof(CRYPT_SMIME_CAPABILITIES));
2246 ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2247 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2248 &bytesNeeded, NULL);
2254 SetLastError(STATUS_ACCESS_VIOLATION);
2257 TRACE("returning %d\n", ret);
2261 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2262 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2267 LPSTR *pStr = pvStructInfo;
2269 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2271 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2272 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2274 if (pbEncoded[0] != ASN_IA5STRING)
2276 SetLastError(CRYPT_E_ASN1_CORRUPT);
2281 bytesNeeded += dataLen;
2283 *pcbDecoded = 1 + lenBytes + dataLen;
2285 *pcbStructInfo = bytesNeeded;
2286 else if (*pcbStructInfo < bytesNeeded)
2288 *pcbStructInfo = bytesNeeded;
2289 SetLastError(ERROR_MORE_DATA);
2294 *pcbStructInfo = bytesNeeded;
2300 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2311 static BOOL CRYPT_AsnDecodeIntArray(const BYTE *pbEncoded,
2312 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2315 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2316 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2317 struct GenericArray *array = pvStructInfo;
2320 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2321 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2323 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2324 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2325 array ? array->rgItems : NULL);
2326 TRACE("returning %d\n", ret);
2330 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2331 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2335 struct AsnDecodeSequenceItem items[] = {
2336 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2337 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2338 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2339 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2340 cNoticeNumbers), CRYPT_AsnDecodeIntArray, sizeof(struct GenericArray),
2341 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2342 rgNoticeNumbers), 0 },
2346 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2347 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2349 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2350 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2354 /* The caller is expecting a pointer to a
2355 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2356 * CRYPT_AsnDecodeSequence is decoding a
2357 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2358 * needed, and decode again if the requisite space is available.
2360 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2362 *pcbStructInfo = bytesNeeded;
2363 else if (*pcbStructInfo < bytesNeeded)
2365 *pcbStructInfo = bytesNeeded;
2366 SetLastError(ERROR_MORE_DATA);
2371 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2373 *pcbStructInfo = bytesNeeded;
2374 /* The pointer (pvStructInfo) passed in points to the first dynamic
2375 * pointer, so use it as the pointer to the
2376 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2377 * appropriate offset for the first dynamic pointer within the
2378 * notice reference by pointing to the first memory location past
2379 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2382 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2383 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2384 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2385 ret = CRYPT_AsnDecodeSequence(items,
2386 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2387 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2388 noticeRef->pszOrganization);
2391 TRACE("returning %d\n", ret);
2395 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2396 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2402 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2404 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2405 DWORD bytesNeeded = sizeof(LPWSTR);
2407 switch (pbEncoded[0])
2409 case ASN_NUMERICSTRING:
2411 bytesNeeded += (dataLen + 1) * 2;
2413 case ASN_PRINTABLESTRING:
2415 bytesNeeded += (dataLen + 1) * 2;
2419 bytesNeeded += (dataLen + 1) * 2;
2423 bytesNeeded += (dataLen + 1) * 2;
2425 case ASN_VIDEOTEXSTRING:
2427 bytesNeeded += (dataLen + 1) * 2;
2429 case ASN_GRAPHICSTRING:
2431 bytesNeeded += (dataLen + 1) * 2;
2433 case ASN_VISIBLESTRING:
2435 bytesNeeded += (dataLen + 1) * 2;
2437 case ASN_GENERALSTRING:
2439 bytesNeeded += (dataLen + 1) * 2;
2441 case ASN_UNIVERSALSTRING:
2443 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2447 bytesNeeded += dataLen + sizeof(WCHAR);
2449 case ASN_UTF8STRING:
2451 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2452 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2455 SetLastError(CRYPT_E_ASN1_BADTAG);
2460 *pcbDecoded = 1 + lenBytes + dataLen;
2462 *pcbStructInfo = bytesNeeded;
2463 else if (*pcbStructInfo < bytesNeeded)
2465 *pcbStructInfo = bytesNeeded;
2466 SetLastError(ERROR_MORE_DATA);
2471 LPWSTR *pStr = pvStructInfo;
2473 *pcbStructInfo = bytesNeeded;
2477 LPWSTR str = *(LPWSTR *)pStr;
2480 switch (pbEncoded[0])
2482 case ASN_NUMERICSTRING:
2483 case ASN_PRINTABLESTRING:
2486 case ASN_VIDEOTEXSTRING:
2487 case ASN_GRAPHICSTRING:
2488 case ASN_VISIBLESTRING:
2489 case ASN_GENERALSTRING:
2490 for (i = 0; i < dataLen; i++)
2491 str[i] = pbEncoded[1 + lenBytes + i];
2494 case ASN_UNIVERSALSTRING:
2495 for (i = 0; i < dataLen / 4; i++)
2496 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2497 | pbEncoded[1 + lenBytes + 2 * i + 3];
2501 for (i = 0; i < dataLen / 2; i++)
2502 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2503 pbEncoded[1 + lenBytes + 2 * i + 1];
2506 case ASN_UTF8STRING:
2508 int len = MultiByteToWideChar(CP_UTF8, 0,
2509 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2510 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2523 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2524 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2525 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2528 struct AsnDecodeSequenceItem items[] = {
2529 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2530 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2531 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2532 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2533 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2534 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2535 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2537 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2539 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2540 pvStructInfo, *pcbStructInfo);
2542 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2543 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2544 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2545 TRACE("returning %d\n", ret);
2549 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2550 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2551 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2552 void *pvStructInfo, DWORD *pcbStructInfo)
2556 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2557 pDecodePara, pvStructInfo, *pcbStructInfo);
2563 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2564 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2569 *pcbStructInfo = bytesNeeded;
2570 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2571 pvStructInfo, pcbStructInfo, bytesNeeded)))
2573 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2575 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2576 pvStructInfo = *(BYTE **)pvStructInfo;
2577 notice = pvStructInfo;
2578 notice->pNoticeReference =
2579 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2580 ((BYTE *)pvStructInfo +
2581 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2582 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2583 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2584 pvStructInfo, &bytesNeeded, NULL);
2590 SetLastError(STATUS_ACCESS_VIOLATION);
2593 TRACE("returning %d\n", ret);
2597 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2598 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2602 struct AsnDecodeSequenceItem items[] = {
2603 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2604 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2605 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2606 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2607 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2608 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2610 PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2612 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2613 pvStructInfo, *pcbStructInfo);
2615 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2616 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2617 pcbDecoded, attr ? attr->pszObjId : NULL);
2618 TRACE("returning %d\n", ret);
2622 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2623 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2624 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2628 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2629 pDecodePara, pvStructInfo, *pcbStructInfo);
2635 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2636 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2640 *pcbStructInfo = bytesNeeded;
2641 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2642 pvStructInfo, pcbStructInfo, bytesNeeded)))
2644 PCRYPT_ATTRIBUTE attr;
2646 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2647 pvStructInfo = *(BYTE **)pvStructInfo;
2648 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2649 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2650 sizeof(CRYPT_ATTRIBUTE));
2651 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2652 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2659 SetLastError(STATUS_ACCESS_VIOLATION);
2662 TRACE("returning %d\n", ret);
2666 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2667 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2670 struct AsnArrayDescriptor arrayDesc = { 0,
2671 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2672 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2673 PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2676 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2677 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2682 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2683 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2684 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2688 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2689 pDecodePara, pvStructInfo, *pcbStructInfo);
2696 SetLastError(CRYPT_E_ASN1_EOD);
2697 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2698 SetLastError(CRYPT_E_ASN1_CORRUPT);
2699 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2700 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2704 *pcbStructInfo = bytesNeeded;
2705 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2706 pvStructInfo, pcbStructInfo, bytesNeeded)))
2708 PCRYPT_ATTRIBUTES attrs;
2710 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2711 pvStructInfo = *(BYTE **)pvStructInfo;
2712 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2713 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2714 sizeof(CRYPT_ATTRIBUTES));
2715 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2716 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2717 &bytesNeeded, NULL);
2723 SetLastError(STATUS_ACCESS_VIOLATION);
2726 TRACE("returning %d\n", ret);
2730 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2731 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2733 CRYPT_ALGORITHM_IDENTIFIER *algo =
2734 (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2736 struct AsnDecodeSequenceItem items[] = {
2737 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2738 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2739 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2740 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2741 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2742 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2745 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2746 pvStructInfo, *pcbStructInfo, pcbDecoded);
2748 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2749 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2750 pcbDecoded, algo ? algo->pszObjId : NULL);
2751 if (ret && pvStructInfo)
2753 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2754 debugstr_a(algo->pszObjId));
2759 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2760 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2764 struct AsnDecodeSequenceItem items[] = {
2765 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2766 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2767 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2768 Algorithm.pszObjId) },
2769 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2770 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2771 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2773 PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2775 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2776 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2777 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2781 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2782 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2783 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2791 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2792 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2795 *pcbStructInfo = bytesNeeded;
2796 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2797 pvStructInfo, pcbStructInfo, bytesNeeded)))
2799 PCERT_PUBLIC_KEY_INFO info;
2801 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2802 pvStructInfo = *(BYTE **)pvStructInfo;
2803 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2804 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2805 sizeof(CERT_PUBLIC_KEY_INFO);
2806 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2807 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2808 &bytesNeeded, NULL);
2814 SetLastError(STATUS_ACCESS_VIOLATION);
2821 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2822 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2828 SetLastError(CRYPT_E_ASN1_CORRUPT);
2831 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2833 SetLastError(CRYPT_E_ASN1_CORRUPT);
2836 if (pbEncoded[1] > 1)
2838 SetLastError(CRYPT_E_ASN1_CORRUPT);
2845 *pcbStructInfo = sizeof(BOOL);
2848 else if (*pcbStructInfo < sizeof(BOOL))
2850 *pcbStructInfo = sizeof(BOOL);
2851 SetLastError(ERROR_MORE_DATA);
2856 *pcbStructInfo = sizeof(BOOL);
2857 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2860 TRACE("returning %d (%08x)\n", ret, GetLastError());
2864 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2865 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2867 PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2868 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2871 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2872 pvStructInfo, *pcbStructInfo);
2876 SetLastError(CRYPT_E_ASN1_CORRUPT);
2879 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2880 if (1 + lenBytes > cbEncoded)
2882 SetLastError(CRYPT_E_ASN1_CORRUPT);
2885 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2887 switch (pbEncoded[0] & ASN_TYPE_MASK)
2889 case 1: /* rfc822Name */
2890 case 2: /* dNSName */
2891 case 6: /* uniformResourceIdentifier */
2892 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2894 case 4: /* directoryName */
2895 case 7: /* iPAddress */
2896 bytesNeeded += dataLen;
2898 case 8: /* registeredID */
2899 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2903 /* FIXME: ugly, shouldn't need to know internals of OID decode
2904 * function to use it.
2906 bytesNeeded += dataLen - sizeof(LPSTR);
2909 case 0: /* otherName */
2910 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2911 SetLastError(CRYPT_E_ASN1_BADTAG);
2914 case 3: /* x400Address, unimplemented */
2915 case 5: /* ediPartyName, unimplemented */
2916 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2917 SetLastError(CRYPT_E_ASN1_BADTAG);
2921 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2922 SetLastError(CRYPT_E_ASN1_CORRUPT);
2928 *pcbDecoded = 1 + lenBytes + dataLen;
2930 *pcbStructInfo = bytesNeeded;
2931 else if (*pcbStructInfo < bytesNeeded)
2933 *pcbStructInfo = bytesNeeded;
2934 SetLastError(ERROR_MORE_DATA);
2939 *pcbStructInfo = bytesNeeded;
2940 /* MS used values one greater than the asn1 ones.. sigh */
2941 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
2942 switch (pbEncoded[0] & ASN_TYPE_MASK)
2944 case 1: /* rfc822Name */
2945 case 2: /* dNSName */
2946 case 6: /* uniformResourceIdentifier */
2950 for (i = 0; i < dataLen; i++)
2951 entry->u.pwszURL[i] =
2952 (WCHAR)pbEncoded[1 + lenBytes + i];
2953 entry->u.pwszURL[i] = 0;
2954 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2955 debugstr_w(entry->u.pwszURL));
2958 case 4: /* directoryName */
2959 /* The data are memory-equivalent with the IPAddress case,
2962 case 7: /* iPAddress */
2963 /* The next data pointer is in the pwszURL spot, that is,
2964 * the first 4 bytes. Need to move it to the next spot.
2966 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2967 entry->u.IPAddress.cbData = dataLen;
2968 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2971 case 8: /* registeredID */
2972 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2973 &entry->u.pszRegisteredID, &dataLen, NULL);
2982 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2983 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2987 struct AsnArrayDescriptor arrayDesc = { 0,
2988 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2989 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2990 PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2992 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2993 pvStructInfo, *pcbStructInfo, pcbDecoded);
2996 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2997 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2998 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2999 info ? info->rgAltEntry : NULL);
3003 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3004 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
3005 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3010 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3011 pvStructInfo, *pcbStructInfo, pcbDecoded);
3013 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3016 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3017 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
3019 if (ret && pvStructInfo)
3021 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3028 for (i = 0; i < blob->cbData / 2; i++)
3030 temp = blob->pbData[i];
3031 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
3032 blob->pbData[blob->cbData - i - 1] = temp;
3036 TRACE("returning %d (%08x)\n", ret, GetLastError());
3040 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3041 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3042 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3048 struct AsnDecodeSequenceItem items[] = {
3049 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3050 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3051 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3052 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3053 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3054 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3055 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3056 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3057 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3058 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3059 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3062 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3063 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3064 pcbStructInfo, NULL, NULL);
3068 SetLastError(STATUS_ACCESS_VIOLATION);
3075 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3076 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3077 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3083 struct AsnDecodeSequenceItem items[] = {
3084 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3085 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3086 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3087 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3088 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3089 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3090 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3091 AuthorityCertIssuer.rgAltEntry), 0 },
3092 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3093 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3094 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3095 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3096 AuthorityCertSerialNumber.pbData), 0 },
3099 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3100 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3101 pcbStructInfo, NULL, NULL);
3105 SetLastError(STATUS_ACCESS_VIOLATION);
3112 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3113 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3116 struct AsnDecodeSequenceItem items[] = {
3117 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3118 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3119 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3120 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3121 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3122 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3124 CERT_ACCESS_DESCRIPTION *descr = (CERT_ACCESS_DESCRIPTION *)pvStructInfo;
3126 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3127 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3128 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3131 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3132 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3133 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3137 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3138 pDecodePara, pvStructInfo, *pcbStructInfo);
3142 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3143 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3144 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3146 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3147 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3151 SetLastError(STATUS_ACCESS_VIOLATION);
3158 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3159 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3164 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3165 pvStructInfo, *pcbStructInfo, pcbDecoded);
3167 /* The caller has already checked the tag, no need to check it again.
3168 * Check the outer length is valid:
3170 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3172 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3175 pbEncoded += 1 + lenBytes;
3176 cbEncoded -= 1 + lenBytes;
3177 if (dataLen == CMSG_INDEFINITE_LENGTH)
3178 cbEncoded -= 2; /* space for 0 TLV */
3179 /* Check the inner length is valid: */
3180 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3184 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3185 pvStructInfo, pcbStructInfo, &decodedLen);
3186 if (dataLen == CMSG_INDEFINITE_LENGTH)
3188 if (*(pbEncoded + decodedLen) != 0 ||
3189 *(pbEncoded + decodedLen + 1) != 0)
3191 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3192 *(pbEncoded + decodedLen),
3193 *(pbEncoded + decodedLen + 1));
3194 SetLastError(CRYPT_E_ASN1_CORRUPT);
3200 if (ret && pcbDecoded)
3202 *pcbDecoded = 1 + lenBytes + decodedLen;
3203 TRACE("decoded %d bytes\n", *pcbDecoded);
3210 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3211 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3214 CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
3215 struct AsnDecodeSequenceItem items[] = {
3216 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3217 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3218 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3219 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3220 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3221 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3222 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3226 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3227 pvStructInfo, *pcbStructInfo, pcbDecoded);
3229 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3230 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3231 pcbDecoded, info ? info->pszObjId : NULL);
3235 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3236 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3237 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3241 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3242 pDecodePara, pvStructInfo, *pcbStructInfo);
3246 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3247 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3248 if (ret && pvStructInfo)
3250 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3251 pcbStructInfo, *pcbStructInfo);
3254 CRYPT_CONTENT_INFO *info;
3256 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3257 pvStructInfo = *(BYTE **)pvStructInfo;
3258 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
3259 info->pszObjId = (LPSTR)((BYTE *)info +
3260 sizeof(CRYPT_CONTENT_INFO));
3261 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3262 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3263 pcbStructInfo, NULL);
3269 SetLastError(STATUS_ACCESS_VIOLATION);
3275 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3276 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3277 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3280 struct AsnDecodeSequenceItem items[] = {
3281 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3282 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3283 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3284 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3285 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3287 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3288 CRYPT_AsnDecodePKCSContentInfoInternal,
3289 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3290 ContentInfo.pszObjId), 0 },
3291 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3292 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3293 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3296 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3297 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3302 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3303 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3304 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3308 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3309 pDecodePara, pvStructInfo, *pcbStructInfo);
3315 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3316 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3319 *pcbStructInfo = bytesNeeded;
3320 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3321 pvStructInfo, pcbStructInfo, bytesNeeded)))
3323 CERT_ALT_NAME_INFO *name;
3325 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3326 pvStructInfo = *(BYTE **)pvStructInfo;
3327 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
3328 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3329 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3330 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3331 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3332 &bytesNeeded, NULL);
3338 SetLastError(STATUS_ACCESS_VIOLATION);
3345 struct PATH_LEN_CONSTRAINT
3347 BOOL fPathLenConstraint;
3348 DWORD dwPathLenConstraint;
3351 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3352 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3356 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3358 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3359 pvStructInfo, *pcbStructInfo, pcbDecoded);
3363 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3365 *pcbStructInfo = bytesNeeded;
3367 else if (*pcbStructInfo < bytesNeeded)
3369 SetLastError(ERROR_MORE_DATA);
3370 *pcbStructInfo = bytesNeeded;
3375 struct PATH_LEN_CONSTRAINT *constraint =
3376 (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
3378 *pcbStructInfo = bytesNeeded;
3379 size = sizeof(constraint->dwPathLenConstraint);
3380 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3381 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3383 constraint->fPathLenConstraint = TRUE;
3384 TRACE("got an int, dwPathLenConstraint is %d\n",
3385 constraint->dwPathLenConstraint);
3387 TRACE("returning %d (%08x)\n", ret, GetLastError());
3391 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3392 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3396 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3397 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3398 offsetof(CERT_NAME_BLOB, pbData) };
3399 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
3401 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3402 pvStructInfo, *pcbStructInfo, pcbDecoded);
3404 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3405 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3406 entries ? entries->rgItems : NULL);
3407 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3411 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3412 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3413 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3419 struct AsnDecodeSequenceItem items[] = {
3420 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3421 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3422 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3423 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3424 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3425 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3426 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3427 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3428 sizeof(struct GenericArray), TRUE, TRUE,
3429 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3432 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3433 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3434 pcbStructInfo, NULL, NULL);
3438 SetLastError(STATUS_ACCESS_VIOLATION);
3445 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3446 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3447 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3453 struct AsnDecodeSequenceItem items[] = {
3454 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3455 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3456 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3457 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3458 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3461 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3462 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3463 pcbStructInfo, NULL, NULL);
3467 SetLastError(STATUS_ACCESS_VIOLATION);
3474 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3475 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3478 struct AsnDecodeSequenceItem items[] = {
3479 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3480 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3481 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3483 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3484 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3485 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3488 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3490 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3491 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3493 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3494 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3495 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3499 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3500 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3504 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3505 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3506 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3507 struct GenericArray *entries = pvStructInfo;
3509 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3510 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3512 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3513 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3514 entries ? entries->rgItems : NULL);
3515 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3519 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3520 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3522 struct AsnDecodeSequenceItem items[] = {
3523 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3524 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3525 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3526 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3527 CRYPT_AsnDecodePolicyQualifiers, sizeof(struct GenericArray), TRUE,
3528 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3530 CERT_POLICY_INFO *info = pvStructInfo;
3533 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3534 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3536 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3537 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3538 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3542 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3543 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3544 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3548 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3549 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3553 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3554 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3555 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3557 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3558 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3562 SetLastError(STATUS_ACCESS_VIOLATION);
3568 #define RSA1_MAGIC 0x31415352
3570 struct DECODED_RSA_PUB_KEY
3573 CRYPT_INTEGER_BLOB modulus;
3576 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3577 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3578 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3584 struct AsnDecodeSequenceItem items[] = {
3585 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3586 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3587 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3589 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3590 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3592 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3595 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3596 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3600 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3601 decodedKey->modulus.cbData;
3605 *pcbStructInfo = bytesNeeded;
3608 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3609 pvStructInfo, pcbStructInfo, bytesNeeded)))
3612 RSAPUBKEY *rsaPubKey;
3614 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3615 pvStructInfo = *(BYTE **)pvStructInfo;
3616 hdr = (BLOBHEADER *)pvStructInfo;
3617 hdr->bType = PUBLICKEYBLOB;
3618 hdr->bVersion = CUR_BLOB_VERSION;
3620 hdr->aiKeyAlg = CALG_RSA_KEYX;
3621 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3622 sizeof(BLOBHEADER));
3623 rsaPubKey->magic = RSA1_MAGIC;
3624 rsaPubKey->pubexp = decodedKey->pubexp;
3625 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3626 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3627 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3628 decodedKey->modulus.cbData);
3630 LocalFree(decodedKey);
3635 SetLastError(STATUS_ACCESS_VIOLATION);
3642 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3643 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3647 DWORD bytesNeeded, dataLen;
3649 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3650 pvStructInfo, *pcbStructInfo, pcbDecoded);
3652 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3654 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3656 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3657 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3659 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3661 *pcbDecoded = 1 + lenBytes + dataLen;
3663 *pcbStructInfo = bytesNeeded;
3664 else if (*pcbStructInfo < bytesNeeded)
3666 SetLastError(ERROR_MORE_DATA);
3667 *pcbStructInfo = bytesNeeded;
3672 CRYPT_DATA_BLOB *blob;
3674 *pcbStructInfo = bytesNeeded;
3675 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3676 blob->cbData = dataLen;
3677 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3678 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3681 assert(blob->pbData);
3683 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3691 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3692 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3693 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3697 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3698 pDecodePara, pvStructInfo, *pcbStructInfo);
3706 SetLastError(CRYPT_E_ASN1_CORRUPT);
3709 else if (pbEncoded[0] != ASN_OCTETSTRING)
3711 SetLastError(CRYPT_E_ASN1_BADTAG);
3714 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3715 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3718 *pcbStructInfo = bytesNeeded;
3719 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3720 pvStructInfo, pcbStructInfo, bytesNeeded)))
3722 CRYPT_DATA_BLOB *blob;
3724 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3725 pvStructInfo = *(BYTE **)pvStructInfo;
3726 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3727 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3728 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3729 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3730 &bytesNeeded, NULL);
3736 SetLastError(STATUS_ACCESS_VIOLATION);
3743 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3744 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3747 DWORD bytesNeeded, dataLen;
3748 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3750 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3751 pvStructInfo, *pcbStructInfo, pcbDecoded);
3753 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3755 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3756 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3758 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3760 *pcbDecoded = 1 + lenBytes + dataLen;
3762 *pcbStructInfo = bytesNeeded;
3763 else if (*pcbStructInfo < bytesNeeded)
3765 *pcbStructInfo = bytesNeeded;
3766 SetLastError(ERROR_MORE_DATA);
3771 CRYPT_BIT_BLOB *blob;
3773 *pcbStructInfo = bytesNeeded;
3774 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3775 blob->cbData = dataLen - 1;
3776 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3777 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3779 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3783 assert(blob->pbData);
3786 BYTE mask = 0xff << blob->cUnusedBits;
3788 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3790 blob->pbData[blob->cbData - 1] &= mask;
3798 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3799 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3800 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3804 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3805 pDecodePara, pvStructInfo, pcbStructInfo);
3813 SetLastError(CRYPT_E_ASN1_CORRUPT);
3816 else if (pbEncoded[0] != ASN_BITSTRING)
3818 SetLastError(CRYPT_E_ASN1_BADTAG);
3821 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3822 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3825 *pcbStructInfo = bytesNeeded;
3826 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3827 pvStructInfo, pcbStructInfo, bytesNeeded)))
3829 CRYPT_BIT_BLOB *blob;
3831 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3832 pvStructInfo = *(BYTE **)pvStructInfo;
3833 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3834 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3835 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3836 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3837 &bytesNeeded, NULL);
3843 SetLastError(STATUS_ACCESS_VIOLATION);
3847 TRACE("returning %d (%08x)\n", ret, GetLastError());
3851 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3852 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3853 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3856 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3857 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3858 DWORD size = sizeof(buf);
3860 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3861 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
3866 *pcbStructInfo = sizeof(int);
3867 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3871 if (blob->pbData[blob->cbData - 1] & 0x80)
3873 /* initialize to a negative value to sign-extend */
3878 for (i = 0; i < blob->cbData; i++)
3881 val |= blob->pbData[blob->cbData - i - 1];
3883 memcpy(pvStructInfo, &val, sizeof(int));
3886 else if (GetLastError() == ERROR_MORE_DATA)
3887 SetLastError(CRYPT_E_ASN1_LARGE);
3891 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3892 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3893 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3903 SetLastError(CRYPT_E_ASN1_EOD);
3906 else if (pbEncoded[0] != ASN_INTEGER)
3908 SetLastError(CRYPT_E_ASN1_BADTAG);
3912 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3913 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3917 *pcbStructInfo = bytesNeeded;
3918 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3919 pvStructInfo, pcbStructInfo, bytesNeeded)))
3921 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3922 pvStructInfo = *(BYTE **)pvStructInfo;
3923 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3924 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3925 &bytesNeeded, NULL);
3931 SetLastError(STATUS_ACCESS_VIOLATION);
3938 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3939 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3943 DWORD bytesNeeded, dataLen;
3945 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3947 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3949 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3951 *pcbDecoded = 1 + lenBytes + dataLen;
3953 *pcbStructInfo = bytesNeeded;
3954 else if (*pcbStructInfo < bytesNeeded)
3956 *pcbStructInfo = bytesNeeded;
3957 SetLastError(ERROR_MORE_DATA);
3962 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3964 *pcbStructInfo = bytesNeeded;
3965 blob->cbData = dataLen;
3966 assert(blob->pbData);
3971 for (i = 0; i < blob->cbData; i++)
3973 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3982 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
3983 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3984 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3992 if (pbEncoded[0] != ASN_INTEGER)
3994 SetLastError(CRYPT_E_ASN1_BADTAG);
3998 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3999 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4003 *pcbStructInfo = bytesNeeded;
4004 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4005 pvStructInfo, pcbStructInfo, bytesNeeded)))
4007 CRYPT_INTEGER_BLOB *blob;
4009 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4010 pvStructInfo = *(BYTE **)pvStructInfo;
4011 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
4012 blob->pbData = (BYTE *)pvStructInfo +
4013 sizeof(CRYPT_INTEGER_BLOB);
4014 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4015 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4016 &bytesNeeded, NULL);
4022 SetLastError(STATUS_ACCESS_VIOLATION);
4029 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4030 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4035 if (pbEncoded[0] == ASN_INTEGER)
4037 DWORD bytesNeeded, dataLen;
4039 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4041 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4044 *pcbDecoded = 1 + lenBytes + dataLen;
4045 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4047 *pcbStructInfo = bytesNeeded;
4048 else if (*pcbStructInfo < bytesNeeded)
4050 *pcbStructInfo = bytesNeeded;
4051 SetLastError(ERROR_MORE_DATA);
4056 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
4058 *pcbStructInfo = bytesNeeded;
4059 blob->cbData = dataLen;
4060 assert(blob->pbData);
4061 /* remove leading zero byte if it exists */
4062 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4071 for (i = 0; i < blob->cbData; i++)
4073 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4082 SetLastError(CRYPT_E_ASN1_BADTAG);
4088 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4089 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4090 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4098 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4099 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4102 *pcbStructInfo = bytesNeeded;
4103 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4104 pvStructInfo, pcbStructInfo, bytesNeeded)))
4106 CRYPT_INTEGER_BLOB *blob;
4108 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4109 pvStructInfo = *(BYTE **)pvStructInfo;
4110 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
4111 blob->pbData = (BYTE *)pvStructInfo +
4112 sizeof(CRYPT_INTEGER_BLOB);
4113 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4114 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4115 &bytesNeeded, NULL);
4121 SetLastError(STATUS_ACCESS_VIOLATION);
4128 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4129 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4130 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4136 *pcbStructInfo = sizeof(int);
4141 if (pbEncoded[0] == ASN_ENUMERATED)
4143 unsigned int val = 0, i;
4147 SetLastError(CRYPT_E_ASN1_EOD);
4150 else if (pbEncoded[1] == 0)
4152 SetLastError(CRYPT_E_ASN1_CORRUPT);
4157 /* A little strange looking, but we have to accept a sign byte:
4158 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4159 * assuming a small length is okay here, it has to be in short
4162 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4164 SetLastError(CRYPT_E_ASN1_LARGE);
4167 for (i = 0; i < pbEncoded[1]; i++)
4170 val |= pbEncoded[2 + i];
4172 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4173 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4175 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4176 pvStructInfo = *(BYTE **)pvStructInfo;
4177 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4183 SetLastError(CRYPT_E_ASN1_BADTAG);
4189 SetLastError(STATUS_ACCESS_VIOLATION);
4196 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4199 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4204 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4206 if (!isdigit(*(pbEncoded))) \
4208 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4214 (word) += *(pbEncoded)++ - '0'; \
4219 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4220 SYSTEMTIME *sysTime)
4224 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4226 WORD hours, minutes = 0;
4227 BYTE sign = *pbEncoded++;
4230 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4231 if (ret && hours >= 24)
4233 SetLastError(CRYPT_E_ASN1_CORRUPT);
4238 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4239 if (ret && minutes >= 60)
4241 SetLastError(CRYPT_E_ASN1_CORRUPT);
4249 sysTime->wHour += hours;
4250 sysTime->wMinute += minutes;
4254 if (hours > sysTime->wHour)
4257 sysTime->wHour = 24 - (hours - sysTime->wHour);
4260 sysTime->wHour -= hours;
4261 if (minutes > sysTime->wMinute)
4264 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4267 sysTime->wMinute -= minutes;
4274 #define MIN_ENCODED_TIME_LENGTH 10
4276 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4277 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4282 if (pbEncoded[0] == ASN_UTCTIME)
4285 SetLastError(CRYPT_E_ASN1_EOD);
4286 else if (pbEncoded[1] > 0x7f)
4288 /* long-form date strings really can't be valid */
4289 SetLastError(CRYPT_E_ASN1_CORRUPT);
4293 SYSTEMTIME sysTime = { 0 };
4294 BYTE len = pbEncoded[1];
4296 if (len < MIN_ENCODED_TIME_LENGTH)
4297 SetLastError(CRYPT_E_ASN1_CORRUPT);
4302 *pcbDecoded = 2 + len;
4304 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4305 if (sysTime.wYear >= 50)
4306 sysTime.wYear += 1900;
4308 sysTime.wYear += 2000;
4309 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4310 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4311 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4312 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4315 if (len >= 2 && isdigit(*pbEncoded) &&
4316 isdigit(*(pbEncoded + 1)))
4317 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4319 else if (isdigit(*pbEncoded))
4320 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4323 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4329 *pcbStructInfo = sizeof(FILETIME);
4330 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4332 ret = SystemTimeToFileTime(&sysTime,
4333 (FILETIME *)pvStructInfo);
4339 SetLastError(CRYPT_E_ASN1_BADTAG);
4343 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4344 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4345 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4353 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4354 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4358 *pcbStructInfo = bytesNeeded;
4359 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4360 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4362 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4363 pvStructInfo = *(BYTE **)pvStructInfo;
4364 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4365 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4366 &bytesNeeded, NULL);
4372 SetLastError(STATUS_ACCESS_VIOLATION);
4378 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4379 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4384 if (pbEncoded[0] == ASN_GENERALTIME)
4387 SetLastError(CRYPT_E_ASN1_EOD);
4388 else if (pbEncoded[1] > 0x7f)
4390 /* long-form date strings really can't be valid */
4391 SetLastError(CRYPT_E_ASN1_CORRUPT);
4395 BYTE len = pbEncoded[1];
4397 if (len < MIN_ENCODED_TIME_LENGTH)
4398 SetLastError(CRYPT_E_ASN1_CORRUPT);
4401 SYSTEMTIME sysTime = { 0 };
4405 *pcbDecoded = 2 + len;
4407 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4408 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4409 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4410 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4413 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4416 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4418 if (ret && len > 0 && (*pbEncoded == '.' ||
4425 /* workaround macro weirdness */
4426 digits = min(len, 3);
4427 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4428 sysTime.wMilliseconds);
4431 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4437 *pcbStructInfo = sizeof(FILETIME);
4438 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4440 ret = SystemTimeToFileTime(&sysTime,
4441 (FILETIME *)pvStructInfo);
4447 SetLastError(CRYPT_E_ASN1_BADTAG);
4451 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4452 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4456 InternalDecodeFunc decode = NULL;
4458 if (pbEncoded[0] == ASN_UTCTIME)
4459 decode = CRYPT_AsnDecodeUtcTimeInternal;
4460 else if (pbEncoded[0] == ASN_GENERALTIME)
4461 decode = CRYPT_AsnDecodeGeneralizedTime;
4463 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4464 pcbStructInfo, pcbDecoded);
4467 SetLastError(CRYPT_E_ASN1_BADTAG);
4473 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4474 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4475 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4483 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4484 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4488 *pcbStructInfo = bytesNeeded;
4489 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4490 pvStructInfo, pcbStructInfo, bytesNeeded)))
4492 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4493 pvStructInfo = *(BYTE **)pvStructInfo;
4494 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4495 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4496 &bytesNeeded, NULL);
4502 SetLastError(STATUS_ACCESS_VIOLATION);
4509 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4510 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4511 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4517 if (pbEncoded[0] == ASN_SEQUENCEOF)
4519 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4521 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4526 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4527 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4529 ptr = pbEncoded + 1 + lenBytes;
4530 remainingLen = dataLen;
4531 while (ret && remainingLen)
4535 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4538 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4540 remainingLen -= 1 + nextLenBytes + nextLen;
4541 ptr += 1 + nextLenBytes + nextLen;
4542 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4543 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4544 bytesNeeded += 1 + nextLenBytes + nextLen;
4550 CRYPT_SEQUENCE_OF_ANY *seq;
4555 *pcbStructInfo = bytesNeeded;
4556 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4557 pvStructInfo, pcbStructInfo, bytesNeeded)))
4559 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4560 pvStructInfo = *(BYTE **)pvStructInfo;
4561 seq = (CRYPT_SEQUENCE_OF_ANY *)pvStructInfo;
4562 seq->cValue = cValue;
4563 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4565 nextPtr = (BYTE *)seq->rgValue +
4566 cValue * sizeof(CRYPT_DER_BLOB);
4567 ptr = pbEncoded + 1 + lenBytes;
4568 remainingLen = dataLen;
4570 while (ret && remainingLen)
4574 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4577 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4579 seq->rgValue[i].cbData = 1 + nextLenBytes +
4581 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4582 seq->rgValue[i].pbData = (BYTE *)ptr;
4585 seq->rgValue[i].pbData = nextPtr;
4586 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4588 nextPtr += 1 + nextLenBytes + nextLen;
4590 remainingLen -= 1 + nextLenBytes + nextLen;
4591 ptr += 1 + nextLenBytes + nextLen;
4601 SetLastError(CRYPT_E_ASN1_BADTAG);
4607 SetLastError(STATUS_ACCESS_VIOLATION);
4614 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4615 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4620 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4622 DWORD bytesNeeded, dataLen;
4624 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4626 struct AsnArrayDescriptor arrayDesc = {
4627 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
4628 sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4629 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4630 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4635 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4636 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4637 0, NULL, NULL, &nameLen, NULL, NULL);
4638 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4639 * as the sizeof(struct GenericArray), so don't include it in the
4640 * total bytes needed.
4642 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4643 sizeof(CERT_ALT_NAME_INFO);
4646 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4648 *pcbDecoded = 1 + lenBytes + dataLen;
4650 *pcbStructInfo = bytesNeeded;
4651 else if (*pcbStructInfo < bytesNeeded)
4653 *pcbStructInfo = bytesNeeded;
4654 SetLastError(ERROR_MORE_DATA);
4659 CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
4661 *pcbStructInfo = bytesNeeded;
4664 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4665 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4666 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4667 0, NULL, &name->u.FullName, &nameLen, NULL,
4668 name->u.FullName.rgAltEntry);
4671 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4677 SetLastError(CRYPT_E_ASN1_BADTAG);
4683 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4684 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4686 struct AsnDecodeSequenceItem items[] = {
4687 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
4688 DistPointName), CRYPT_AsnDecodeDistPointName,
4689 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
4690 DistPointName.u.FullName.rgAltEntry), 0 },
4691 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
4692 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
4693 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
4694 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
4695 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
4696 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
4698 CRL_DIST_POINT *point = (CRL_DIST_POINT *)pvStructInfo;
4701 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4702 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4703 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
4707 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
4708 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4709 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4713 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4714 pDecodePara, pvStructInfo, *pcbStructInfo);
4718 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4719 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4720 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4722 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4723 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4727 SetLastError(STATUS_ACCESS_VIOLATION);
4734 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4735 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4736 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4740 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4741 pDecodePara, pvStructInfo, *pcbStructInfo);
4745 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4746 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4748 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4749 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4753 SetLastError(STATUS_ACCESS_VIOLATION);
4760 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4761 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4762 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4766 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4767 pDecodePara, pvStructInfo, *pcbStructInfo);
4771 struct AsnDecodeSequenceItem items[] = {
4772 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4773 DistPointName), CRYPT_AsnDecodeDistPointName,
4774 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4775 offsetof(CRL_ISSUING_DIST_POINT,
4776 DistPointName.u.FullName.rgAltEntry), 0 },
4777 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4778 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4780 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4781 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4783 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4784 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4785 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4786 OnlySomeReasonFlags.pbData), 0 },
4787 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4788 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4791 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4792 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4793 pcbStructInfo, NULL, NULL);
4797 SetLastError(STATUS_ACCESS_VIOLATION);
4804 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4805 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4810 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4811 pvStructInfo, *pcbStructInfo, pcbDecoded);
4815 SetLastError(CRYPT_E_ASN1_EOD);
4818 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4820 SetLastError(CRYPT_E_ASN1_BADTAG);
4823 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4824 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4825 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4827 if (ret && pvStructInfo)
4828 *(BOOL *)pvStructInfo = TRUE;
4829 TRACE("returning %d\n", ret);
4833 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4834 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4838 struct AsnDecodeSequenceItem items[] = {
4839 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4840 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4841 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4842 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4843 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4844 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4845 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4848 CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)pvStructInfo;
4850 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4851 pvStructInfo, *pcbStructInfo, pcbDecoded);
4853 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4854 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4855 pcbDecoded, subtree ? (BYTE *)subtree->Base.u.pwszURL : NULL);
4858 TRACE("%d\n", *pcbDecoded);
4859 if (*pcbDecoded < cbEncoded)
4860 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4861 *(pbEncoded + *pcbDecoded + 1));
4863 TRACE("returning %d\n", ret);
4867 static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
4868 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4872 struct AsnArrayDescriptor arrayDesc = { 0,
4873 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4874 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4875 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4877 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4878 pvStructInfo, *pcbStructInfo, pcbDecoded);
4880 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4881 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4882 array ? array->rgItems : NULL);
4887 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4888 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4889 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4893 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4894 pDecodePara, pvStructInfo, *pcbStructInfo);
4898 struct AsnDecodeSequenceItem items[] = {
4899 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4900 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4901 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4902 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4903 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4904 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4905 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4906 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4909 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4910 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4911 pcbStructInfo, NULL, NULL);
4915 SetLastError(STATUS_ACCESS_VIOLATION);
4921 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
4922 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4926 struct AsnDecodeSequenceItem items[] = {
4927 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
4928 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
4930 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
4931 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
4932 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
4934 CERT_ISSUER_SERIAL_NUMBER *issuerSerial =
4935 (CERT_ISSUER_SERIAL_NUMBER *)pvStructInfo;
4937 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4938 pvStructInfo, *pcbStructInfo, pcbDecoded);
4940 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4941 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4942 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
4943 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
4945 SetLastError(CRYPT_E_ASN1_CORRUPT);
4948 TRACE("returning %d\n", ret);
4952 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
4953 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4956 CMSG_SIGNER_INFO *info = (CMSG_SIGNER_INFO *)pvStructInfo;
4957 struct AsnDecodeSequenceItem items[] = {
4958 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
4959 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4960 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
4961 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
4962 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
4963 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
4964 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4965 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4966 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4967 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
4968 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4969 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4970 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
4971 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4972 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
4973 HashEncryptionAlgorithm.pszObjId), 0 },
4974 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
4975 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4976 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
4977 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4978 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
4979 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4980 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4984 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4985 pvStructInfo, *pcbStructInfo);
4987 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4988 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4989 pcbDecoded, info ? info->Issuer.pbData : NULL);
4993 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
4994 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4995 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4999 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5000 pDecodePara, pvStructInfo, *pcbStructInfo);
5004 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5005 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5006 if (ret && pvStructInfo)
5008 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5009 pcbStructInfo, *pcbStructInfo);
5012 CMSG_SIGNER_INFO *info;
5014 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5015 pvStructInfo = *(BYTE **)pvStructInfo;
5016 info = (CMSG_SIGNER_INFO *)pvStructInfo;
5017 info->Issuer.pbData = ((BYTE *)info +
5018 sizeof(CMSG_SIGNER_INFO));
5019 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5020 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5021 pcbStructInfo, NULL);
5027 SetLastError(STATUS_ACCESS_VIOLATION);
5030 TRACE("returning %d\n", ret);
5034 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5035 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5038 CERT_ID *id = (CERT_ID *)pvStructInfo;
5041 if (*pbEncoded == ASN_SEQUENCEOF)
5043 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5044 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5048 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5049 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5050 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5051 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5053 *pcbStructInfo = sizeof(CERT_ID);
5056 else if (*pbEncoded == (ASN_CONTEXT | 0))
5058 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5059 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5063 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5064 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5065 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5066 sizeof(CRYPT_DATA_BLOB);
5068 *pcbStructInfo = sizeof(CERT_ID);
5072 SetLastError(CRYPT_E_ASN1_BADTAG);
5076 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5077 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5080 CMSG_CMS_SIGNER_INFO *info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
5081 struct AsnDecodeSequenceItem items[] = {
5082 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5083 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5084 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5085 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5086 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5087 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5088 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5089 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5090 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5091 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5092 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5093 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5094 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5095 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5096 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5097 HashEncryptionAlgorithm.pszObjId), 0 },
5098 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5099 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5100 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5101 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5102 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5103 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5104 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5108 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5109 pvStructInfo, *pcbStructInfo);
5111 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5112 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5113 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5117 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5118 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5119 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5123 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5124 pDecodePara, pvStructInfo, *pcbStructInfo);
5128 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5129 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5130 if (ret && pvStructInfo)
5132 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5133 pcbStructInfo, *pcbStructInfo);
5136 CMSG_CMS_SIGNER_INFO *info;
5138 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5139 pvStructInfo = *(BYTE **)pvStructInfo;
5140 info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
5141 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5142 sizeof(CMSG_CMS_SIGNER_INFO));
5143 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5144 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5145 pcbStructInfo, NULL);
5151 SetLastError(STATUS_ACCESS_VIOLATION);
5154 TRACE("returning %d\n", ret);
5158 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5159 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5162 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5163 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5164 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5165 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
5167 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5168 pvStructInfo, *pcbStructInfo, pcbDecoded);
5170 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
5171 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
5172 array ? array->rgItems : NULL);
5176 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5177 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5178 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5181 struct AsnDecodeSequenceItem items[] = {
5182 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5183 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5184 /* Placeholder for the hash algorithms - redundant with those in the
5185 * signers, so just ignore them.
5187 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5188 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5189 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5190 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5191 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5192 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5193 CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
5194 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5195 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5196 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
5197 sizeof(struct GenericArray), TRUE, TRUE,
5198 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5199 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5200 CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
5201 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5204 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5205 pDecodePara, signedInfo, *pcbSignedInfo);
5207 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5208 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5210 TRACE("returning %d\n", ret);
5214 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5215 LPCSTR lpszStructType)
5217 CryptDecodeObjectExFunc decodeFunc = NULL;
5219 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5220 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5222 SetLastError(ERROR_FILE_NOT_FOUND);
5225 if (!HIWORD(lpszStructType))
5227 switch (LOWORD(lpszStructType))
5229 case LOWORD(X509_CERT):
5230 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5232 case LOWORD(X509_CERT_TO_BE_SIGNED):
5233 decodeFunc = CRYPT_AsnDecodeCert;
5235 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5236 decodeFunc = CRYPT_AsnDecodeCRL;
5238 case LOWORD(X509_EXTENSIONS):
5239 decodeFunc = CRYPT_AsnDecodeExtensions;
5241 case LOWORD(X509_NAME_VALUE):
5242 decodeFunc = CRYPT_AsnDecodeNameValue;
5244 case LOWORD(X509_NAME):
5245 decodeFunc = CRYPT_AsnDecodeName;
5247 case LOWORD(X509_PUBLIC_KEY_INFO):
5248 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5250 case LOWORD(X509_AUTHORITY_KEY_ID):
5251 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5253 case LOWORD(X509_ALTERNATE_NAME):
5254 decodeFunc = CRYPT_AsnDecodeAltName;
5256 case LOWORD(X509_BASIC_CONSTRAINTS):
5257 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5259 case LOWORD(X509_BASIC_CONSTRAINTS2):
5260 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5262 case LOWORD(X509_CERT_POLICIES):
5263 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5265 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5266 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5268 case LOWORD(X509_UNICODE_NAME):
5269 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5271 case LOWORD(PKCS_ATTRIBUTE):
5272 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5274 case LOWORD(X509_UNICODE_NAME_VALUE):
5275 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5277 case LOWORD(X509_OCTET_STRING):
5278 decodeFunc = CRYPT_AsnDecodeOctets;
5280 case LOWORD(X509_BITS):
5281 case LOWORD(X509_KEY_USAGE):
5282 decodeFunc = CRYPT_AsnDecodeBits;
5284 case LOWORD(X509_INTEGER):
5285 decodeFunc = CRYPT_AsnDecodeInt;
5287 case LOWORD(X509_MULTI_BYTE_INTEGER):
5288 decodeFunc = CRYPT_AsnDecodeInteger;
5290 case LOWORD(X509_MULTI_BYTE_UINT):
5291 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5293 case LOWORD(X509_ENUMERATED):
5294 decodeFunc = CRYPT_AsnDecodeEnumerated;
5296 case LOWORD(X509_CHOICE_OF_TIME):
5297 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5299 case LOWORD(X509_AUTHORITY_KEY_ID2):
5300 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5302 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5303 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5305 case LOWORD(PKCS_CONTENT_INFO):
5306 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5308 case LOWORD(X509_SEQUENCE_OF_ANY):
5309 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5311 case LOWORD(PKCS_UTC_TIME):
5312 decodeFunc = CRYPT_AsnDecodeUtcTime;
5314 case LOWORD(X509_CRL_DIST_POINTS):
5315 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5317 case LOWORD(X509_ENHANCED_KEY_USAGE):
5318 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5320 case LOWORD(PKCS_CTL):
5321 decodeFunc = CRYPT_AsnDecodeCTL;
5323 case LOWORD(PKCS_SMIME_CAPABILITIES):
5324 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5326 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5327 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5329 case LOWORD(PKCS_ATTRIBUTES):
5330 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5332 case LOWORD(X509_ISSUING_DIST_POINT):
5333 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5335 case LOWORD(X509_NAME_CONSTRAINTS):
5336 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5338 case LOWORD(PKCS7_SIGNER_INFO):
5339 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5341 case LOWORD(CMS_SIGNER_INFO):
5342 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5346 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5347 decodeFunc = CRYPT_AsnDecodeExtensions;
5348 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5349 decodeFunc = CRYPT_AsnDecodeUtcTime;
5350 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5351 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5352 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5353 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5354 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5355 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5356 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5357 decodeFunc = CRYPT_AsnDecodeEnumerated;
5358 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5359 decodeFunc = CRYPT_AsnDecodeBits;
5360 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5361 decodeFunc = CRYPT_AsnDecodeOctets;
5362 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5363 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5364 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5365 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5366 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5367 decodeFunc = CRYPT_AsnDecodeAltName;
5368 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5369 decodeFunc = CRYPT_AsnDecodeAltName;
5370 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5371 decodeFunc = CRYPT_AsnDecodeAltName;
5372 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5373 decodeFunc = CRYPT_AsnDecodeAltName;
5374 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5375 decodeFunc = CRYPT_AsnDecodeAltName;
5376 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5377 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5378 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5379 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5380 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5381 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5382 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5383 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5384 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5385 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5386 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5387 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5388 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5389 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5390 else if (!strcmp(lpszStructType, szOID_CTL))
5391 decodeFunc = CRYPT_AsnDecodeCTL;
5395 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5396 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5398 static HCRYPTOIDFUNCSET set = NULL;
5399 CryptDecodeObjectFunc decodeFunc = NULL;
5402 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5403 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5404 (void **)&decodeFunc, hFunc);
5408 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5409 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5411 static HCRYPTOIDFUNCSET set = NULL;
5412 CryptDecodeObjectExFunc decodeFunc = NULL;
5415 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5416 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5417 (void **)&decodeFunc, hFunc);
5421 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5422 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5423 DWORD *pcbStructInfo)
5426 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5427 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5428 HCRYPTOIDFUNCADDR hFunc = NULL;
5430 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5431 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5432 pvStructInfo, pcbStructInfo);
5434 if (!pvStructInfo && !pcbStructInfo)
5436 SetLastError(ERROR_INVALID_PARAMETER);
5439 if (cbEncoded > MAX_ENCODED_LEN)
5441 SetLastError(CRYPT_E_ASN1_LARGE);
5445 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5448 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5449 debugstr_a(lpszStructType));
5450 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5451 lpszStructType, &hFunc);
5452 if (!pCryptDecodeObject)
5453 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5454 lpszStructType, &hFunc);
5456 if (pCryptDecodeObject)
5457 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5458 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5459 else if (pCryptDecodeObjectEx)
5460 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
5461 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
5462 pvStructInfo, pcbStructInfo);
5464 CryptFreeOIDFunctionAddress(hFunc, 0);
5465 TRACE_(crypt)("returning %d\n", ret);
5469 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5470 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5471 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5474 CryptDecodeObjectExFunc decodeFunc;
5475 HCRYPTOIDFUNCADDR hFunc = NULL;
5477 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5478 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
5479 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5481 if (!pvStructInfo && !pcbStructInfo)
5483 SetLastError(ERROR_INVALID_PARAMETER);
5486 if (cbEncoded > MAX_ENCODED_LEN)
5488 SetLastError(CRYPT_E_ASN1_LARGE);
5492 SetLastError(NOERROR);
5493 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
5494 *(BYTE **)pvStructInfo = NULL;
5495 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
5498 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5499 debugstr_a(lpszStructType));
5500 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
5504 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
5505 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5508 CryptDecodeObjectFunc pCryptDecodeObject =
5509 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
5511 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5512 * directly, as that could cause an infinite loop.
5514 if (pCryptDecodeObject)
5516 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5518 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5519 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
5520 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5521 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
5522 ret = pCryptDecodeObject(dwCertEncodingType,
5523 lpszStructType, pbEncoded, cbEncoded, dwFlags,
5524 *(BYTE **)pvStructInfo, pcbStructInfo);
5527 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5528 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5532 CryptFreeOIDFunctionAddress(hFunc, 0);
5533 TRACE_(crypt)("returning %d\n", ret);