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 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
86 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
87 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
88 /* Assumes algo->Parameters.pbData is set ahead of time. */
89 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
90 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
91 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
92 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
93 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
94 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
95 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
97 /* Doesn't check the tag, assumes the caller does so */
98 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
99 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
100 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
101 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
102 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
103 * member has been initialized, doesn't do exception handling, and doesn't do
104 * memory allocation. Also doesn't check tag, assumes the caller has checked
107 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
108 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
111 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
112 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
114 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
115 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
118 /* Gets the number of length bytes from the given (leading) length byte */
119 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
121 /* Helper function to get the encoded length of the data starting at pbEncoded,
122 * where pbEncoded[0] is the tag. If the data are too short to contain a
123 * length or if the length is too large for cbEncoded, sets an appropriate
124 * error code and returns FALSE. If the encoded length is unknown due to
125 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
127 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
134 SetLastError(CRYPT_E_ASN1_CORRUPT);
137 else if (pbEncoded[1] <= 0x7f)
139 if (pbEncoded[1] + 1 > cbEncoded)
141 SetLastError(CRYPT_E_ASN1_EOD);
150 else if (pbEncoded[1] == 0x80)
152 *len = CMSG_INDEFINITE_LENGTH;
157 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
159 if (lenLen > sizeof(DWORD) + 1)
161 SetLastError(CRYPT_E_ASN1_LARGE);
164 else if (lenLen + 2 > cbEncoded)
166 SetLastError(CRYPT_E_ASN1_CORRUPT);
179 if (out + lenLen + 1 > cbEncoded)
181 SetLastError(CRYPT_E_ASN1_EOD);
194 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
195 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
199 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
200 *len == CMSG_INDEFINITE_LENGTH)
202 SetLastError(CRYPT_E_ASN1_CORRUPT);
208 /* Helper function to check *pcbStructInfo, set it to the required size, and
209 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
210 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
211 * pointer to the newly allocated memory.
213 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
214 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
219 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
221 if (pDecodePara && pDecodePara->pfnAlloc)
222 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
224 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
225 if (!*(BYTE **)pvStructInfo)
228 *pcbStructInfo = bytesNeeded;
230 else if (*pcbStructInfo < bytesNeeded)
232 *pcbStructInfo = bytesNeeded;
233 SetLastError(ERROR_MORE_DATA);
237 *pcbStructInfo = bytesNeeded;
241 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
243 if (pDecodePara && pDecodePara->pfnFree)
244 pDecodePara->pfnFree(pv);
249 /* Helper function to check *pcbStructInfo and set it to the required size.
250 * Assumes pvStructInfo is not NULL.
252 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
256 if (*pcbStructInfo < bytesNeeded)
258 *pcbStructInfo = bytesNeeded;
259 SetLastError(ERROR_MORE_DATA);
264 *pcbStructInfo = bytesNeeded;
271 * The expected tag of the item. If tag is 0, decodeFunc is called
272 * regardless of the tag value seen.
274 * A sequence is decoded into a struct. The offset member is the
275 * offset of this item within that struct.
277 * The decoder function to use. If this is NULL, then the member isn't
278 * decoded, but minSize space is reserved for it.
280 * The minimum amount of space occupied after decoding. You must set this.
282 * If true, and the tag doesn't match the expected tag for this item,
283 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
284 * filled with 0 for this member.
285 * hasPointer, pointerOffset:
286 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
287 * the offset within the struct of the data pointer (or to the
288 * first data pointer, if more than one exist).
290 * Used by CRYPT_AsnDecodeSequence, not for your use.
292 struct AsnDecodeSequenceItem
296 InternalDecodeFunc decodeFunc;
304 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
305 #define MEMBERSIZE(s, member, nextmember) \
306 (offsetof(s, nextmember) - offsetof(s, member))
308 /* Decodes the items in a sequence, where the items are described in items,
309 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
310 * pvStructInfo. nextData is a pointer to the memory location at which the
311 * first decoded item with a dynamic pointer should point.
312 * Upon decoding, *cbDecoded is the total number of bytes decoded.
313 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
315 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
316 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
317 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
320 DWORD i, decoded = 0;
321 const BYTE *ptr = pbEncoded;
323 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
324 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
326 for (i = 0, ret = TRUE; ret && i < cItem; i++)
328 if (cbEncoded - (ptr - pbEncoded) != 0)
332 if ((ret = CRYPT_GetLengthIndefinite(ptr,
333 cbEncoded - (ptr - pbEncoded), &itemLen)))
335 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
337 if (ptr[0] == items[i].tag || !items[i].tag)
339 DWORD itemEncodedLen;
341 if (itemLen == CMSG_INDEFINITE_LENGTH)
342 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
344 itemEncodedLen = 1 + itemLenBytes + itemLen;
345 if (nextData && pvStructInfo && items[i].hasPointer)
347 TRACE("Setting next pointer to %p\n",
349 *(BYTE **)((BYTE *)pvStructInfo +
350 items[i].pointerOffset) = nextData;
352 if (items[i].decodeFunc)
357 TRACE("decoding item %d\n", i);
359 TRACE("sizing item %d\n", i);
360 ret = items[i].decodeFunc(ptr, itemEncodedLen,
361 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
362 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
363 : NULL, &items[i].size, &itemDecoded);
366 /* Account for alignment padding */
367 items[i].size = ALIGN_DWORD_PTR(items[i].size);
368 TRACE("item %d size: %d\n", i, items[i].size);
369 if (nextData && items[i].hasPointer &&
370 items[i].size > items[i].minSize)
371 nextData += items[i].size - items[i].minSize;
372 if (itemDecoded > itemEncodedLen)
374 WARN("decoded length %d exceeds encoded %d\n",
375 itemDecoded, itemEncodedLen);
376 SetLastError(CRYPT_E_ASN1_CORRUPT);
382 decoded += itemDecoded;
383 TRACE("item %d: decoded %d bytes\n", i,
387 else if (items[i].optional &&
388 GetLastError() == CRYPT_E_ASN1_BADTAG)
390 TRACE("skipping optional item %d\n", i);
391 items[i].size = items[i].minSize;
392 SetLastError(NOERROR);
396 TRACE("item %d failed: %08x\n", i,
399 else if (itemLen == CMSG_INDEFINITE_LENGTH)
401 ERR("can't use indefinite length encoding without a decoder\n");
402 SetLastError(CRYPT_E_ASN1_CORRUPT);
407 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
408 ptr += itemEncodedLen;
409 decoded += itemEncodedLen;
410 items[i].size = items[i].minSize;
413 else if (items[i].optional)
415 TRACE("skipping optional item %d\n", i);
416 items[i].size = items[i].minSize;
420 TRACE("item %d: tag %02x doesn't match expected %02x\n",
421 i, ptr[0], items[i].tag);
422 SetLastError(CRYPT_E_ASN1_BADTAG);
427 else if (items[i].optional)
429 TRACE("missing optional item %d, skipping\n", i);
430 items[i].size = items[i].minSize;
434 TRACE("not enough bytes for item %d, failing\n", i);
435 SetLastError(CRYPT_E_ASN1_CORRUPT);
440 *cbDecoded = decoded;
441 TRACE("returning %d\n", ret);
445 /* This decodes an arbitrary sequence into a contiguous block of memory
446 * (basically, a struct.) Each element being decoded is described by a struct
447 * AsnDecodeSequenceItem, see above.
448 * startingPointer is an optional pointer to the first place where dynamic
449 * data will be stored. If you know the starting offset, you may pass it
450 * here. Otherwise, pass NULL, and one will be inferred from the items.
452 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
453 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
454 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
455 DWORD *pcbDecoded, void *startingPointer)
459 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
460 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
465 SetLastError(CRYPT_E_ASN1_EOD);
468 if (pbEncoded[0] == ASN_SEQUENCE)
472 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
474 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
475 const BYTE *ptr = pbEncoded + 1 + lenBytes;
476 BOOL indefinite = FALSE;
478 cbEncoded -= 1 + lenBytes;
479 if (dataLen == CMSG_INDEFINITE_LENGTH)
484 else if (cbEncoded < dataLen)
486 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
488 SetLastError(CRYPT_E_ASN1_CORRUPT);
493 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
494 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
495 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
497 if (cbDecoded > cbEncoded - 2)
499 /* Not enough space for 0 TLV */
500 SetLastError(CRYPT_E_ASN1_CORRUPT);
503 else if (*(ptr + cbDecoded) != 0 ||
504 *(ptr + cbDecoded + 1) != 0)
506 TRACE("expected 0 TLV\n");
507 SetLastError(CRYPT_E_ASN1_CORRUPT);
514 if (ret && !indefinite && cbDecoded != dataLen)
516 TRACE("expected %d decoded, got %d, failing\n", dataLen,
518 SetLastError(CRYPT_E_ASN1_CORRUPT);
523 DWORD i, bytesNeeded = 0, structSize = 0;
525 for (i = 0; i < cItem; i++)
527 bytesNeeded += items[i].size;
528 structSize = max( structSize, items[i].offset + items[i].minSize );
531 *pcbDecoded = 1 + lenBytes + cbDecoded;
533 *pcbStructInfo = bytesNeeded;
534 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
535 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
539 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
540 pvStructInfo = *(BYTE **)pvStructInfo;
542 nextData = startingPointer;
544 nextData = (BYTE *)pvStructInfo + structSize;
545 memset(pvStructInfo, 0, structSize);
546 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
547 ptr, dataLen, dwFlags, pvStructInfo, nextData,
549 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
550 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
557 SetLastError(CRYPT_E_ASN1_BADTAG);
560 TRACE("returning %d (%08x)\n", ret, GetLastError());
565 * The expected tag of the entire encoded array (usually a variant
566 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
567 * regardless of the tag seen.
569 * The offset within the outer structure at which the count exists.
570 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
571 * while CRYPT_ATTRIBUTE has countOffset ==
572 * offsetof(CRYPT_ATTRIBUTE, cValue).
574 * The offset within the outer structure at which the array pointer exists.
575 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
576 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
578 * The minimum size of the decoded array. On WIN32, this is always 8:
579 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
582 * used to decode each item in the array
584 * is the minimum size of each decoded item
586 * indicates whether each item has a dynamic pointer
588 * indicates the offset within itemSize at which the pointer exists
590 struct AsnArrayDescriptor
596 InternalDecodeFunc decodeFunc;
602 struct AsnArrayItemSize
608 /* Decodes an array of like types into a struct GenericArray.
609 * The layout and decoding of the array are described by a struct
610 * AsnArrayDescriptor.
612 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
613 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
614 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
615 DWORD *pcbDecoded, void *startingPointer)
619 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
620 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
625 SetLastError(CRYPT_E_ASN1_EOD);
628 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
632 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
634 DWORD bytesNeeded, cItems = 0, decoded;
635 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
636 /* There can be arbitrarily many items, but there is often only one.
638 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
640 decoded = 1 + lenBytes;
641 bytesNeeded = sizeof(struct GenericArray);
645 BOOL doneDecoding = FALSE;
647 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
649 if (dataLen == CMSG_INDEFINITE_LENGTH)
656 SetLastError(CRYPT_E_ASN1_CORRUPT);
663 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
667 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
669 /* Each item decoded may not tolerate extraneous bytes,
670 * so get the length of the next element if known.
672 if ((ret = CRYPT_GetLengthIndefinite(ptr,
673 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
675 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
676 itemEncoded = cbEncoded - (ptr - pbEncoded);
678 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
682 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
683 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
688 if (itemSizes != &itemSize)
689 itemSizes = CryptMemRealloc(itemSizes,
690 cItems * sizeof(struct AsnArrayItemSize));
695 cItems * sizeof(struct AsnArrayItemSize));
697 memcpy(itemSizes, &itemSize,
702 decoded += itemDecoded;
703 itemSizes[cItems - 1].encodedLen = itemEncoded;
704 itemSizes[cItems - 1].size = size;
717 *pcbDecoded = decoded;
719 *pcbStructInfo = bytesNeeded;
720 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
721 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
726 struct GenericArray *array;
728 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
729 pvStructInfo = *(BYTE **)pvStructInfo;
730 array = pvStructInfo;
731 array->cItems = cItems;
733 array->rgItems = startingPointer;
735 array->rgItems = (BYTE *)array +
736 sizeof(struct GenericArray);
737 nextData = array->rgItems +
738 array->cItems * arrayDesc->itemSize;
739 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
740 i < cItems && ptr - pbEncoded - 1 - lenBytes <
745 if (arrayDesc->hasPointer)
746 *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
747 + arrayDesc->pointerOffset) = nextData;
748 ret = arrayDesc->decodeFunc(ptr,
749 itemSizes[i].encodedLen,
750 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
751 array->rgItems + i * arrayDesc->itemSize,
752 &itemSizes[i].size, &itemDecoded);
755 nextData += itemSizes[i].size - arrayDesc->itemSize;
759 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
760 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
763 if (itemSizes != &itemSize)
764 CryptMemFree(itemSizes);
769 SetLastError(CRYPT_E_ASN1_BADTAG);
775 /* Decodes an array of like types into a structure described by a struct
776 * AsnArrayDescriptor. Doesn't allocate memory for the decoded items,
777 * leaves that up to the caller.
779 static BOOL CRYPT_AsnDecodeArrayNoAlloc(const struct AsnArrayDescriptor *arrayDesc,
780 const BYTE *pbEncoded, DWORD cbEncoded, void *pvStructInfo,
781 DWORD *pcbStructInfo, DWORD *pcbDecoded)
785 TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
786 cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
790 SetLastError(CRYPT_E_ASN1_EOD);
793 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
797 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
799 DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
800 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
801 /* There can be arbitrarily many items, but there is often only one.
803 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
805 decoded = 1 + lenBytes;
809 BOOL doneDecoding = FALSE;
811 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
813 if (dataLen == CMSG_INDEFINITE_LENGTH)
820 SetLastError(CRYPT_E_ASN1_CORRUPT);
827 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
831 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
833 /* Each item decoded may not tolerate extraneous bytes,
834 * so get the length of the next element if known.
836 if ((ret = CRYPT_GetLengthIndefinite(ptr,
837 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
839 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
840 itemEncoded = cbEncoded - (ptr - pbEncoded);
842 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
846 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
847 0, NULL, &size, &itemDecoded);
851 if (itemSizes != &itemSize)
852 itemSizes = CryptMemRealloc(itemSizes,
853 cItems * sizeof(struct AsnArrayItemSize));
858 cItems * sizeof(struct AsnArrayItemSize));
860 memcpy(itemSizes, &itemSize,
865 decoded += itemDecoded;
866 itemSizes[cItems - 1].encodedLen = itemEncoded;
867 itemSizes[cItems - 1].size = size;
880 *pcbDecoded = decoded;
882 *pcbStructInfo = bytesNeeded;
883 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
884 pcbStructInfo, bytesNeeded)))
891 pcItems = pvStructInfo;
893 rgItems = *(void **)((BYTE *)pcItems -
894 arrayDesc->countOffset + arrayDesc->arrayOffset);
895 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
896 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
897 i < cItems && ptr - pbEncoded - 1 - lenBytes <
902 if (arrayDesc->hasPointer)
903 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
904 + arrayDesc->pointerOffset) = nextData;
905 ret = arrayDesc->decodeFunc(ptr,
906 itemSizes[i].encodedLen, 0,
907 (BYTE *)rgItems + i * arrayDesc->itemSize,
908 &itemSizes[i].size, &itemDecoded);
911 nextData += itemSizes[i].size - arrayDesc->itemSize;
917 if (itemSizes != &itemSize)
918 CryptMemFree(itemSizes);
923 SetLastError(CRYPT_E_ASN1_BADTAG);
929 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
930 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
931 * to CRYPT_E_ASN1_CORRUPT.
932 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
935 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
936 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
941 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
943 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
944 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
946 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
947 bytesNeeded += 1 + lenBytes + dataLen;
950 *pcbDecoded = 1 + lenBytes + dataLen;
952 *pcbStructInfo = bytesNeeded;
953 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
955 CRYPT_DER_BLOB *blob;
957 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
958 pvStructInfo = *(BYTE **)pvStructInfo;
960 blob->cbData = 1 + lenBytes + dataLen;
963 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
964 blob->pbData = (BYTE *)pbEncoded;
967 assert(blob->pbData);
968 memcpy(blob->pbData, pbEncoded, blob->cbData);
973 SetLastError(CRYPT_E_ASN1_CORRUPT);
981 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
982 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
983 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
988 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
989 pvStructInfo, *pcbStructInfo, pcbDecoded);
991 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
994 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
995 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
997 if (ret && pvStructInfo)
999 CRYPT_BIT_BLOB *blob = pvStructInfo;
1006 for (i = 0; i < blob->cbData / 2; i++)
1008 temp = blob->pbData[i];
1009 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
1010 blob->pbData[blob->cbData - i - 1] = temp;
1014 TRACE("returning %d (%08x)\n", ret, GetLastError());
1018 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
1019 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1020 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1024 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1025 pDecodePara, pvStructInfo, *pcbStructInfo);
1029 struct AsnDecodeSequenceItem items[] = {
1030 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
1031 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
1032 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
1033 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
1034 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
1035 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
1036 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
1037 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
1038 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
1039 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
1042 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
1043 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
1044 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1045 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
1046 pcbStructInfo, NULL, NULL);
1050 SetLastError(STATUS_ACCESS_VIOLATION);
1055 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1059 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
1060 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1065 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1067 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1069 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
1070 dwFlags, pvStructInfo, pcbStructInfo, NULL);
1072 *pcbDecoded = 1 + lenBytes + dataLen;
1077 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
1078 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1082 struct AsnDecodeSequenceItem items[] = {
1083 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
1084 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1085 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
1086 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1089 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1090 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
1095 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
1096 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1100 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1101 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
1102 FINALMEMBERSIZE(CERT_INFO, cExtension),
1103 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1104 offsetof(CERT_EXTENSION, pszObjId) };
1107 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1108 pvStructInfo, *pcbStructInfo, pcbDecoded);
1110 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1111 NULL, &bytesNeeded, pcbDecoded);
1115 *pcbStructInfo = bytesNeeded;
1116 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1117 pcbStructInfo, bytesNeeded)))
1121 info = (CERT_INFO *)((BYTE *)pvStructInfo -
1122 offsetof(CERT_INFO, cExtension));
1123 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1124 cbEncoded, &info->cExtension, &bytesNeeded, pcbDecoded);
1130 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
1131 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1137 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1139 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1141 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
1142 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1143 if (ret && pcbDecoded)
1144 *pcbDecoded = 1 + lenBytes + dataLen;
1149 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
1150 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1151 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1154 struct AsnDecodeSequenceItem items[] = {
1155 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
1156 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1157 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
1158 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
1159 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
1160 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
1161 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1162 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
1163 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1164 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1166 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
1167 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
1169 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1170 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1172 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1173 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
1174 FALSE, TRUE, offsetof(CERT_INFO,
1175 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1176 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
1177 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1178 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1179 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
1180 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1181 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1182 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1183 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1184 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1187 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1188 pDecodePara, pvStructInfo, *pcbStructInfo);
1190 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1191 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1193 if (ret && pvStructInfo)
1197 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1198 info = *(CERT_INFO **)pvStructInfo;
1200 info = pvStructInfo;
1201 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1202 !info->Subject.cbData)
1204 SetLastError(CRYPT_E_ASN1_CORRUPT);
1205 /* Don't need to deallocate, because it should have failed on the
1206 * first pass (and no memory was allocated.)
1212 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1216 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1217 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1218 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1222 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1223 pDecodePara, pvStructInfo, *pcbStructInfo);
1229 /* Unless told not to, first try to decode it as a signed cert. */
1230 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1232 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1234 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1235 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1236 &signedCert, &size);
1240 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1241 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1242 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1243 pvStructInfo, pcbStructInfo);
1244 LocalFree(signedCert);
1247 /* Failing that, try it as an unsigned cert */
1251 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1252 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1253 pDecodePara, pvStructInfo, pcbStructInfo);
1258 SetLastError(STATUS_ACCESS_VIOLATION);
1262 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1266 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1267 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1271 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1272 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1273 FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1274 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1275 offsetof(CERT_EXTENSION, pszObjId) };
1278 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1279 pvStructInfo, *pcbStructInfo, pcbDecoded);
1281 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1282 NULL, &bytesNeeded, pcbDecoded);
1286 *pcbStructInfo = bytesNeeded;
1287 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1288 pcbStructInfo, bytesNeeded)))
1292 entry = (CRL_ENTRY *)((BYTE *)pvStructInfo -
1293 offsetof(CRL_ENTRY, cExtension));
1294 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1295 cbEncoded, &entry->cExtension, &bytesNeeded, pcbDecoded);
1301 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1302 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1305 struct AsnDecodeSequenceItem items[] = {
1306 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1307 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1308 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1309 { 0, offsetof(CRL_ENTRY, RevocationDate),
1310 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1311 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1312 CRYPT_AsnDecodeCRLEntryExtensions,
1313 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1314 offsetof(CRL_ENTRY, rgExtension), 0 },
1316 PCRL_ENTRY entry = pvStructInfo;
1318 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1321 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1322 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1323 entry ? entry->SerialNumber.pbData : NULL);
1324 if (ret && entry && !entry->SerialNumber.cbData)
1326 WARN("empty CRL entry serial number\n");
1327 SetLastError(CRYPT_E_ASN1_CORRUPT);
1333 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1334 * whose rgCRLEntry member has been set prior to calling.
1336 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1337 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1340 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1341 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1342 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1343 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1344 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1347 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1348 pvStructInfo, *pcbStructInfo, pcbDecoded);
1350 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1351 NULL, &bytesNeeded, pcbDecoded);
1355 *pcbStructInfo = bytesNeeded;
1356 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1357 pcbStructInfo, bytesNeeded)))
1361 info = (CRL_INFO *)((BYTE *)pvStructInfo -
1362 offsetof(CRL_INFO, cCRLEntry));
1363 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1364 cbEncoded, &info->cCRLEntry, &bytesNeeded, pcbDecoded);
1367 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1371 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1372 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1376 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1377 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1378 FINALMEMBERSIZE(CRL_INFO, cExtension),
1379 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1380 offsetof(CERT_EXTENSION, pszObjId) };
1383 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1384 pvStructInfo, *pcbStructInfo, pcbDecoded);
1386 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1387 NULL, &bytesNeeded, pcbDecoded);
1391 *pcbStructInfo = bytesNeeded;
1392 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1393 pcbStructInfo, bytesNeeded)))
1397 info = (CRL_INFO *)((BYTE *)pvStructInfo -
1398 offsetof(CRL_INFO, cExtension));
1399 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1400 cbEncoded, &info->cExtension, &bytesNeeded, pcbDecoded);
1406 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1407 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1413 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1415 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1417 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1418 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1419 if (ret && pcbDecoded)
1420 *pcbDecoded = 1 + lenBytes + dataLen;
1425 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1426 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1427 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1429 struct AsnDecodeSequenceItem items[] = {
1430 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1431 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1432 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1433 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1434 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1435 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1436 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1438 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1439 sizeof(FILETIME), FALSE, FALSE, 0 },
1440 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1441 sizeof(FILETIME), TRUE, FALSE, 0 },
1442 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1443 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1444 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1445 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1446 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1447 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1451 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1452 pDecodePara, pvStructInfo, *pcbStructInfo);
1454 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1455 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1458 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1462 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1463 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1464 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1468 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1469 pDecodePara, pvStructInfo, *pcbStructInfo);
1475 /* Unless told not to, first try to decode it as a signed crl. */
1476 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1478 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1480 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1481 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1486 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1487 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1488 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1489 pvStructInfo, pcbStructInfo);
1490 LocalFree(signedCrl);
1493 /* Failing that, try it as an unsigned crl */
1497 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1498 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1499 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1504 SetLastError(STATUS_ACCESS_VIOLATION);
1508 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1512 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1513 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1518 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1519 pvStructInfo, *pcbStructInfo);
1521 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1523 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1524 DWORD bytesNeeded = sizeof(LPSTR);
1528 /* The largest possible string for the first two components
1529 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1534 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1535 pbEncoded[1 + lenBytes] / 40,
1536 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1538 bytesNeeded += strlen(firstTwo) + 1;
1539 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1540 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1542 /* large enough for ".4000000" */
1546 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1553 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1556 SetLastError(CRYPT_E_ASN1_CORRUPT);
1563 snprintf(str, sizeof(str), ".%d", val);
1564 bytesNeeded += strlen(str);
1569 *pcbDecoded = 1 + lenBytes + dataLen;
1571 *pcbStructInfo = bytesNeeded;
1572 else if (*pcbStructInfo < bytesNeeded)
1574 *pcbStructInfo = bytesNeeded;
1575 SetLastError(ERROR_MORE_DATA);
1583 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1586 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1587 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1589 pszObjId += strlen(pszObjId);
1590 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1591 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1595 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1604 sprintf(pszObjId, ".%d", val);
1605 pszObjId += strlen(pszObjId);
1609 *(LPSTR *)pvStructInfo = NULL;
1610 *pcbStructInfo = bytesNeeded;
1616 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1617 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1621 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1622 pvStructInfo, *pcbStructInfo);
1624 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1625 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1626 pvStructInfo, pcbStructInfo, pcbDecoded);
1629 SetLastError(CRYPT_E_ASN1_BADTAG);
1635 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1636 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1638 struct AsnDecodeSequenceItem items[] = {
1639 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1640 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1641 offsetof(CERT_EXTENSION, pszObjId), 0 },
1642 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1643 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1644 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1645 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1646 offsetof(CERT_EXTENSION, Value.pbData) },
1649 PCERT_EXTENSION ext = pvStructInfo;
1651 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1655 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1656 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1657 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1658 pcbDecoded, ext ? ext->pszObjId : NULL);
1660 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1661 debugstr_a(ext->pszObjId));
1662 TRACE("returning %d (%08x)\n", ret, GetLastError());
1666 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1667 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1668 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1672 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1673 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1677 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1678 offsetof(CERT_EXTENSIONS, cExtension),
1679 offsetof(CERT_EXTENSIONS, rgExtension),
1680 sizeof(CERT_EXTENSIONS),
1681 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1682 offsetof(CERT_EXTENSION, pszObjId) };
1685 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1686 NULL, &bytesNeeded, NULL);
1690 *pcbStructInfo = bytesNeeded;
1691 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1692 pvStructInfo, pcbStructInfo, bytesNeeded)))
1694 CERT_EXTENSIONS *exts;
1696 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1697 pvStructInfo = *(BYTE **)pvStructInfo;
1698 exts = (CERT_EXTENSIONS *)pvStructInfo;
1699 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1700 sizeof(CERT_EXTENSIONS));
1701 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1702 cbEncoded, &exts->cExtension, &bytesNeeded, NULL);
1708 SetLastError(STATUS_ACCESS_VIOLATION);
1715 /* Warning: this assumes the address of value->Value.pbData is already set, in
1716 * order to avoid overwriting memory. (In some cases, it may change it, if it
1717 * doesn't copy anything to memory.) Be sure to set it correctly!
1719 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1720 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1725 CERT_NAME_VALUE *value = pvStructInfo;
1727 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1729 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1730 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1732 switch (pbEncoded[0])
1734 case ASN_OCTETSTRING:
1735 valueType = CERT_RDN_OCTET_STRING;
1736 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1737 bytesNeeded += dataLen;
1739 case ASN_NUMERICSTRING:
1740 valueType = CERT_RDN_NUMERIC_STRING;
1741 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1742 bytesNeeded += dataLen;
1744 case ASN_PRINTABLESTRING:
1745 valueType = CERT_RDN_PRINTABLE_STRING;
1746 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1747 bytesNeeded += dataLen;
1750 valueType = CERT_RDN_IA5_STRING;
1751 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1752 bytesNeeded += dataLen;
1755 valueType = CERT_RDN_T61_STRING;
1756 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1757 bytesNeeded += dataLen;
1759 case ASN_VIDEOTEXSTRING:
1760 valueType = CERT_RDN_VIDEOTEX_STRING;
1761 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1762 bytesNeeded += dataLen;
1764 case ASN_GRAPHICSTRING:
1765 valueType = CERT_RDN_GRAPHIC_STRING;
1766 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1767 bytesNeeded += dataLen;
1769 case ASN_VISIBLESTRING:
1770 valueType = CERT_RDN_VISIBLE_STRING;
1771 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1772 bytesNeeded += dataLen;
1774 case ASN_GENERALSTRING:
1775 valueType = CERT_RDN_GENERAL_STRING;
1776 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1777 bytesNeeded += dataLen;
1779 case ASN_UNIVERSALSTRING:
1780 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1781 SetLastError(CRYPT_E_ASN1_BADTAG);
1784 valueType = CERT_RDN_BMP_STRING;
1785 bytesNeeded += dataLen;
1787 case ASN_UTF8STRING:
1788 valueType = CERT_RDN_UTF8_STRING;
1789 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1790 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1793 SetLastError(CRYPT_E_ASN1_BADTAG);
1798 *pcbDecoded = 1 + lenBytes + dataLen;
1800 *pcbStructInfo = bytesNeeded;
1801 else if (*pcbStructInfo < bytesNeeded)
1803 *pcbStructInfo = bytesNeeded;
1804 SetLastError(ERROR_MORE_DATA);
1809 *pcbStructInfo = bytesNeeded;
1810 value->dwValueType = valueType;
1815 assert(value->Value.pbData);
1816 switch (pbEncoded[0])
1818 case ASN_OCTETSTRING:
1819 case ASN_NUMERICSTRING:
1820 case ASN_PRINTABLESTRING:
1823 case ASN_VIDEOTEXSTRING:
1824 case ASN_GRAPHICSTRING:
1825 case ASN_VISIBLESTRING:
1826 case ASN_GENERALSTRING:
1827 value->Value.cbData = dataLen;
1830 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1831 memcpy(value->Value.pbData,
1832 pbEncoded + 1 + lenBytes, dataLen);
1834 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1840 LPWSTR str = (LPWSTR)value->Value.pbData;
1842 value->Value.cbData = dataLen;
1843 for (i = 0; i < dataLen / 2; i++)
1844 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1845 pbEncoded[1 + lenBytes + 2 * i + 1];
1848 case ASN_UTF8STRING:
1850 LPWSTR str = (LPWSTR)value->Value.pbData;
1852 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1853 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1854 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1861 value->Value.cbData = 0;
1862 value->Value.pbData = NULL;
1869 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1870 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1871 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1877 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1878 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1879 if (ret && pvStructInfo)
1881 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1882 pcbStructInfo, *pcbStructInfo);
1885 CERT_NAME_VALUE *value;
1887 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1888 pvStructInfo = *(BYTE **)pvStructInfo;
1889 value = pvStructInfo;
1890 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1891 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1892 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1893 pcbStructInfo, NULL);
1899 SetLastError(STATUS_ACCESS_VIOLATION);
1906 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1907 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1912 CERT_NAME_VALUE *value = pvStructInfo;
1914 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1916 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1917 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1919 switch (pbEncoded[0])
1921 case ASN_NUMERICSTRING:
1922 valueType = CERT_RDN_NUMERIC_STRING;
1924 bytesNeeded += (dataLen + 1) * 2;
1926 case ASN_PRINTABLESTRING:
1927 valueType = CERT_RDN_PRINTABLE_STRING;
1929 bytesNeeded += (dataLen + 1) * 2;
1932 valueType = CERT_RDN_IA5_STRING;
1934 bytesNeeded += (dataLen + 1) * 2;
1937 valueType = CERT_RDN_T61_STRING;
1939 bytesNeeded += (dataLen + 1) * 2;
1941 case ASN_VIDEOTEXSTRING:
1942 valueType = CERT_RDN_VIDEOTEX_STRING;
1944 bytesNeeded += (dataLen + 1) * 2;
1946 case ASN_GRAPHICSTRING:
1947 valueType = CERT_RDN_GRAPHIC_STRING;
1949 bytesNeeded += (dataLen + 1) * 2;
1951 case ASN_VISIBLESTRING:
1952 valueType = CERT_RDN_VISIBLE_STRING;
1954 bytesNeeded += (dataLen + 1) * 2;
1956 case ASN_GENERALSTRING:
1957 valueType = CERT_RDN_GENERAL_STRING;
1959 bytesNeeded += (dataLen + 1) * 2;
1961 case ASN_UNIVERSALSTRING:
1962 valueType = CERT_RDN_UNIVERSAL_STRING;
1964 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1967 valueType = CERT_RDN_BMP_STRING;
1969 bytesNeeded += dataLen + sizeof(WCHAR);
1971 case ASN_UTF8STRING:
1972 valueType = CERT_RDN_UTF8_STRING;
1974 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1975 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1978 SetLastError(CRYPT_E_ASN1_BADTAG);
1983 *pcbDecoded = 1 + lenBytes + dataLen;
1985 *pcbStructInfo = bytesNeeded;
1986 else if (*pcbStructInfo < bytesNeeded)
1988 *pcbStructInfo = bytesNeeded;
1989 SetLastError(ERROR_MORE_DATA);
1994 *pcbStructInfo = bytesNeeded;
1995 value->dwValueType = valueType;
1999 LPWSTR str = (LPWSTR)value->Value.pbData;
2001 assert(value->Value.pbData);
2002 switch (pbEncoded[0])
2004 case ASN_NUMERICSTRING:
2005 case ASN_PRINTABLESTRING:
2008 case ASN_VIDEOTEXSTRING:
2009 case ASN_GRAPHICSTRING:
2010 case ASN_VISIBLESTRING:
2011 case ASN_GENERALSTRING:
2012 value->Value.cbData = dataLen * 2;
2013 for (i = 0; i < dataLen; i++)
2014 str[i] = pbEncoded[1 + lenBytes + i];
2017 case ASN_UNIVERSALSTRING:
2018 value->Value.cbData = dataLen / 2;
2019 for (i = 0; i < dataLen / 4; i++)
2020 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2021 | pbEncoded[1 + lenBytes + 2 * i + 3];
2025 value->Value.cbData = dataLen;
2026 for (i = 0; i < dataLen / 2; i++)
2027 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2028 pbEncoded[1 + lenBytes + 2 * i + 1];
2031 case ASN_UTF8STRING:
2032 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
2033 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2034 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
2035 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
2036 value->Value.cbData += sizeof(WCHAR);
2042 value->Value.cbData = 0;
2043 value->Value.pbData = NULL;
2050 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
2051 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2052 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2058 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
2059 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2060 if (ret && pvStructInfo)
2062 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2063 pcbStructInfo, *pcbStructInfo);
2066 CERT_NAME_VALUE *value;
2068 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2069 pvStructInfo = *(BYTE **)pvStructInfo;
2070 value = pvStructInfo;
2071 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
2072 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
2073 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2074 pcbStructInfo, NULL);
2080 SetLastError(STATUS_ACCESS_VIOLATION);
2087 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
2088 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2091 struct AsnDecodeSequenceItem items[] = {
2092 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
2093 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2094 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
2095 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
2096 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
2097 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
2099 CERT_RDN_ATTR *attr = pvStructInfo;
2101 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2102 pvStructInfo, *pcbStructInfo);
2105 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
2106 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2107 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
2108 attr ? attr->pszObjId : NULL);
2111 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
2112 debugstr_a(attr->pszObjId));
2113 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
2115 TRACE("returning %d (%08x)\n", ret, GetLastError());
2119 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
2120 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2123 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2124 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
2126 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
2127 offsetof(CERT_RDN_ATTR, pszObjId) };
2128 PCERT_RDN rdn = pvStructInfo;
2130 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2131 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2132 rdn ? rdn->rgRDNAttr : NULL);
2136 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
2137 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2138 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2144 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2145 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2146 sizeof(CERT_NAME_INFO),
2147 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
2148 offsetof(CERT_RDN, rgRDNAttr) };
2150 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2151 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
2155 SetLastError(STATUS_ACCESS_VIOLATION);
2162 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
2163 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2167 struct AsnDecodeSequenceItem items[] = {
2168 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
2169 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2170 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
2171 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
2172 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
2173 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
2175 CERT_RDN_ATTR *attr = pvStructInfo;
2177 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2178 pvStructInfo, *pcbStructInfo);
2181 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
2182 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2183 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
2184 attr ? attr->pszObjId : NULL);
2187 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
2188 debugstr_a(attr->pszObjId));
2189 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
2191 TRACE("returning %d (%08x)\n", ret, GetLastError());
2195 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
2196 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2199 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2200 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
2202 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
2203 offsetof(CERT_RDN_ATTR, pszObjId) };
2204 PCERT_RDN rdn = pvStructInfo;
2206 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2207 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2208 rdn ? rdn->rgRDNAttr : NULL);
2212 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
2213 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2214 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2220 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2221 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2222 sizeof(CERT_NAME_INFO),
2223 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2224 offsetof(CERT_RDN, rgRDNAttr) };
2226 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2227 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
2231 SetLastError(STATUS_ACCESS_VIOLATION);
2238 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2241 BOOL ret = TRUE, done = FALSE;
2242 DWORD indefiniteNestingLevels = 0, decoded = 0;
2244 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2251 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2254 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2256 if (dataLen == CMSG_INDEFINITE_LENGTH)
2258 indefiniteNestingLevels++;
2259 pbEncoded += 1 + lenBytes;
2260 cbEncoded -= 1 + lenBytes;
2261 decoded += 1 + lenBytes;
2262 TRACE("indefiniteNestingLevels = %d\n",
2263 indefiniteNestingLevels);
2267 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2268 indefiniteNestingLevels)
2270 indefiniteNestingLevels--;
2271 TRACE("indefiniteNestingLevels = %d\n",
2272 indefiniteNestingLevels);
2274 pbEncoded += 1 + lenBytes + dataLen;
2275 cbEncoded -= 1 + lenBytes + dataLen;
2276 decoded += 1 + lenBytes + dataLen;
2277 if (!indefiniteNestingLevels)
2281 } while (ret && !done);
2282 /* If we haven't found all 0 TLVs, we haven't found the end */
2283 if (ret && indefiniteNestingLevels)
2285 SetLastError(CRYPT_E_ASN1_EOD);
2289 *pcbDecoded = decoded;
2290 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2294 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2295 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2299 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2301 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2302 pvStructInfo, *pcbStructInfo);
2304 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2306 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2307 bytesNeeded += encodedLen;
2309 *pcbStructInfo = bytesNeeded;
2310 else if (*pcbStructInfo < bytesNeeded)
2312 SetLastError(ERROR_MORE_DATA);
2313 *pcbStructInfo = bytesNeeded;
2318 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2320 *pcbStructInfo = bytesNeeded;
2321 blob->cbData = encodedLen;
2324 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2325 blob->pbData = (LPBYTE)pbEncoded;
2328 assert(blob->pbData);
2329 memcpy(blob->pbData, pbEncoded, blob->cbData);
2333 blob->pbData = NULL;
2336 *pcbDecoded = encodedLen;
2341 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2342 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2345 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2346 offsetof(CTL_USAGE, cUsageIdentifier),
2347 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2349 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2350 CTL_USAGE *usage = pvStructInfo;
2352 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2353 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2354 usage ? usage->rgpszUsageIdentifier : NULL);
2358 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2359 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2362 struct AsnArrayDescriptor arrayDesc = { 0,
2363 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2364 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2365 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2366 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2370 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2371 NULL, &bytesNeeded, pcbDecoded);
2375 *pcbStructInfo = bytesNeeded;
2376 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
2377 pcbStructInfo, bytesNeeded)))
2381 entry = (CTL_ENTRY *)((BYTE *)pvStructInfo -
2382 offsetof(CTL_ENTRY, cAttribute));
2383 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
2384 cbEncoded, &entry->cAttribute, &bytesNeeded, pcbDecoded);
2390 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2391 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2393 struct AsnDecodeSequenceItem items[] = {
2394 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2395 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2396 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2397 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2398 CRYPT_AsnDecodeCTLEntryAttributes,
2399 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2400 offsetof(CTL_ENTRY, rgAttribute), 0 },
2403 CTL_ENTRY *entry = pvStructInfo;
2405 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2408 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2409 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2410 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2414 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2415 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2418 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2419 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2420 FINALMEMBERSIZE(CTL_INFO, cExtension),
2421 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2422 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2425 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2426 pvStructInfo, *pcbStructInfo, pcbDecoded);
2428 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2429 NULL, &bytesNeeded, pcbDecoded);
2433 *pcbStructInfo = bytesNeeded;
2434 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
2435 pcbStructInfo, bytesNeeded)))
2439 info = (CTL_INFO *)((BYTE *)pvStructInfo -
2440 offsetof(CTL_INFO, cCTLEntry));
2441 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
2442 cbEncoded, &info->cCTLEntry, &bytesNeeded, pcbDecoded);
2448 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2449 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2453 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2454 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2455 FINALMEMBERSIZE(CTL_INFO, cExtension),
2456 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2457 offsetof(CERT_EXTENSION, pszObjId) };
2460 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2461 pvStructInfo, *pcbStructInfo, pcbDecoded);
2463 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2464 NULL, &bytesNeeded, pcbDecoded);
2468 *pcbStructInfo = bytesNeeded;
2469 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
2470 pcbStructInfo, bytesNeeded)))
2474 info = (CTL_INFO *)((BYTE *)pvStructInfo -
2475 offsetof(CTL_INFO, cExtension));
2476 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
2477 cbEncoded, &info->cExtension, &bytesNeeded, pcbDecoded);
2483 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2484 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2490 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2492 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2494 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2495 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2496 if (ret && pcbDecoded)
2497 *pcbDecoded = 1 + lenBytes + dataLen;
2502 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2503 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2504 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2508 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2509 pDecodePara, pvStructInfo, *pcbStructInfo);
2513 struct AsnDecodeSequenceItem items[] = {
2514 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2515 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2516 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2517 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2518 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2519 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2520 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2521 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2522 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2523 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2524 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2525 { 0, offsetof(CTL_INFO, ThisUpdate),
2526 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2528 { 0, offsetof(CTL_INFO, NextUpdate),
2529 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2531 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2532 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2533 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2534 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2535 CRYPT_AsnDecodeCTLEntries,
2536 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2537 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2538 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2539 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2540 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2543 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2544 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2545 pcbStructInfo, NULL, NULL);
2549 SetLastError(STATUS_ACCESS_VIOLATION);
2555 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2556 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2560 struct AsnDecodeSequenceItem items[] = {
2561 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2562 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2563 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2564 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2565 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2566 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2568 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2570 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2571 pvStructInfo, *pcbStructInfo);
2573 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2574 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2575 pcbDecoded, capability ? capability->pszObjId : NULL);
2576 TRACE("returning %d\n", ret);
2580 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2581 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2582 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2586 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2587 pDecodePara, pvStructInfo, *pcbStructInfo);
2592 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2593 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2594 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2595 sizeof(CRYPT_SMIME_CAPABILITIES),
2596 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2597 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2599 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2600 NULL, &bytesNeeded, NULL)))
2603 *pcbStructInfo = bytesNeeded;
2604 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2605 pvStructInfo, pcbStructInfo, bytesNeeded)))
2607 PCRYPT_SMIME_CAPABILITIES capabilities;
2609 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2610 pvStructInfo = *(BYTE **)pvStructInfo;
2611 capabilities = pvStructInfo;
2612 capabilities->rgCapability =
2613 (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2614 sizeof(CRYPT_SMIME_CAPABILITIES));
2615 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc,
2616 pbEncoded, cbEncoded, &capabilities->cCapability,
2617 pcbStructInfo, NULL);
2623 SetLastError(STATUS_ACCESS_VIOLATION);
2626 TRACE("returning %d\n", ret);
2630 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2631 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2636 LPSTR *pStr = pvStructInfo;
2638 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2640 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2641 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2643 if (pbEncoded[0] != ASN_IA5STRING)
2645 SetLastError(CRYPT_E_ASN1_CORRUPT);
2650 bytesNeeded += dataLen;
2652 *pcbDecoded = 1 + lenBytes + dataLen;
2654 *pcbStructInfo = bytesNeeded;
2655 else if (*pcbStructInfo < bytesNeeded)
2657 *pcbStructInfo = bytesNeeded;
2658 SetLastError(ERROR_MORE_DATA);
2663 *pcbStructInfo = bytesNeeded;
2669 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2680 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2681 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2684 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2685 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2686 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2687 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2688 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2692 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2693 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2695 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2696 NULL, &bytesNeeded, pcbDecoded);
2700 *pcbStructInfo = bytesNeeded;
2701 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
2702 pcbStructInfo, bytesNeeded)))
2704 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE *ref;
2706 ref = (CERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)
2707 ((BYTE *)pvStructInfo -
2708 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers));
2709 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
2710 cbEncoded, &ref->cNoticeNumbers, &bytesNeeded, pcbDecoded);
2713 TRACE("returning %d\n", ret);
2717 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2718 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2722 struct AsnDecodeSequenceItem items[] = {
2723 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2724 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2725 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2726 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2727 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2728 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2729 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2730 rgNoticeNumbers), 0 },
2734 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2735 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2737 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2738 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2742 /* The caller is expecting a pointer to a
2743 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2744 * CRYPT_AsnDecodeSequence is decoding a
2745 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2746 * needed, and decode again if the requisite space is available.
2748 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2750 *pcbStructInfo = bytesNeeded;
2751 else if (*pcbStructInfo < bytesNeeded)
2753 *pcbStructInfo = bytesNeeded;
2754 SetLastError(ERROR_MORE_DATA);
2759 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2761 *pcbStructInfo = bytesNeeded;
2762 /* The pointer (pvStructInfo) passed in points to the first dynamic
2763 * pointer, so use it as the pointer to the
2764 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2765 * appropriate offset for the first dynamic pointer within the
2766 * notice reference by pointing to the first memory location past
2767 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2770 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2771 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2772 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2773 ret = CRYPT_AsnDecodeSequence(items,
2774 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2775 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2776 noticeRef->pszOrganization);
2779 TRACE("returning %d\n", ret);
2783 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2784 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2790 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2792 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2793 DWORD bytesNeeded = sizeof(LPWSTR);
2795 switch (pbEncoded[0])
2797 case ASN_NUMERICSTRING:
2799 bytesNeeded += (dataLen + 1) * 2;
2801 case ASN_PRINTABLESTRING:
2803 bytesNeeded += (dataLen + 1) * 2;
2807 bytesNeeded += (dataLen + 1) * 2;
2811 bytesNeeded += (dataLen + 1) * 2;
2813 case ASN_VIDEOTEXSTRING:
2815 bytesNeeded += (dataLen + 1) * 2;
2817 case ASN_GRAPHICSTRING:
2819 bytesNeeded += (dataLen + 1) * 2;
2821 case ASN_VISIBLESTRING:
2823 bytesNeeded += (dataLen + 1) * 2;
2825 case ASN_GENERALSTRING:
2827 bytesNeeded += (dataLen + 1) * 2;
2829 case ASN_UNIVERSALSTRING:
2831 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2835 bytesNeeded += dataLen + sizeof(WCHAR);
2837 case ASN_UTF8STRING:
2839 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2840 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2843 SetLastError(CRYPT_E_ASN1_BADTAG);
2848 *pcbDecoded = 1 + lenBytes + dataLen;
2850 *pcbStructInfo = bytesNeeded;
2851 else if (*pcbStructInfo < bytesNeeded)
2853 *pcbStructInfo = bytesNeeded;
2854 SetLastError(ERROR_MORE_DATA);
2859 LPWSTR *pStr = pvStructInfo;
2861 *pcbStructInfo = bytesNeeded;
2865 LPWSTR str = *(LPWSTR *)pStr;
2868 switch (pbEncoded[0])
2870 case ASN_NUMERICSTRING:
2871 case ASN_PRINTABLESTRING:
2874 case ASN_VIDEOTEXSTRING:
2875 case ASN_GRAPHICSTRING:
2876 case ASN_VISIBLESTRING:
2877 case ASN_GENERALSTRING:
2878 for (i = 0; i < dataLen; i++)
2879 str[i] = pbEncoded[1 + lenBytes + i];
2882 case ASN_UNIVERSALSTRING:
2883 for (i = 0; i < dataLen / 4; i++)
2884 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2885 | pbEncoded[1 + lenBytes + 2 * i + 3];
2889 for (i = 0; i < dataLen / 2; i++)
2890 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2891 pbEncoded[1 + lenBytes + 2 * i + 1];
2894 case ASN_UTF8STRING:
2896 int len = MultiByteToWideChar(CP_UTF8, 0,
2897 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2898 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2911 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2912 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2913 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2916 struct AsnDecodeSequenceItem items[] = {
2917 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2918 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2919 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2920 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2921 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2922 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2923 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2925 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2927 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2928 pvStructInfo, *pcbStructInfo);
2930 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2931 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2932 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2933 TRACE("returning %d\n", ret);
2937 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2938 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2939 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2940 void *pvStructInfo, DWORD *pcbStructInfo)
2944 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2945 pDecodePara, pvStructInfo, *pcbStructInfo);
2951 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2952 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2957 *pcbStructInfo = bytesNeeded;
2958 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2959 pvStructInfo, pcbStructInfo, bytesNeeded)))
2961 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2963 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2964 pvStructInfo = *(BYTE **)pvStructInfo;
2965 notice = pvStructInfo;
2966 notice->pNoticeReference =
2967 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2968 ((BYTE *)pvStructInfo +
2969 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2970 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2971 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2972 pvStructInfo, &bytesNeeded, NULL);
2978 SetLastError(STATUS_ACCESS_VIOLATION);
2981 TRACE("returning %d\n", ret);
2985 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2986 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2990 struct AsnArrayDescriptor arrayDesc = { 0,
2991 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2992 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2993 CRYPT_AsnDecodeCopyBytes,
2994 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2997 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2998 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
3000 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
3001 NULL, &bytesNeeded, pcbDecoded)))
3004 *pcbStructInfo = bytesNeeded;
3005 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
3006 pcbStructInfo, bytesNeeded)))
3008 CRYPT_ATTRIBUTE *attr = (CRYPT_ATTRIBUTE *)((BYTE *)pvStructInfo -
3009 offsetof(CRYPT_ATTRIBUTE, cValue));
3011 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
3012 &attr->cValue, pcbStructInfo, pcbDecoded);
3018 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
3019 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3023 struct AsnDecodeSequenceItem items[] = {
3024 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
3025 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3026 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
3027 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
3028 CRYPT_AsnDecodePKCSAttributeValue,
3029 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
3030 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
3032 PCRYPT_ATTRIBUTE attr = pvStructInfo;
3034 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3035 pvStructInfo, *pcbStructInfo);
3037 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3038 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3039 pcbDecoded, attr ? attr->pszObjId : NULL);
3040 TRACE("returning %d\n", ret);
3044 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
3045 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3046 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3050 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3051 pDecodePara, pvStructInfo, *pcbStructInfo);
3057 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
3058 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3062 *pcbStructInfo = bytesNeeded;
3063 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3064 pvStructInfo, pcbStructInfo, bytesNeeded)))
3066 PCRYPT_ATTRIBUTE attr;
3068 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3069 pvStructInfo = *(BYTE **)pvStructInfo;
3070 attr = pvStructInfo;
3071 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
3072 sizeof(CRYPT_ATTRIBUTE));
3073 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
3074 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
3081 SetLastError(STATUS_ACCESS_VIOLATION);
3084 TRACE("returning %d\n", ret);
3088 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
3089 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3092 struct AsnArrayDescriptor arrayDesc = { 0,
3093 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
3094 sizeof(CRYPT_ATTRIBUTES),
3095 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
3096 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
3097 PCRYPT_ATTRIBUTES attrs = pvStructInfo;
3100 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3101 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
3106 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
3107 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3108 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3112 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3113 pDecodePara, pvStructInfo, *pcbStructInfo);
3117 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
3118 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
3119 sizeof(CRYPT_ATTRIBUTES),
3120 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
3121 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
3124 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
3125 cbEncoded, NULL, &bytesNeeded, NULL)))
3128 *pcbStructInfo = bytesNeeded;
3129 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3130 pvStructInfo, pcbStructInfo, bytesNeeded)))
3132 PCRYPT_ATTRIBUTES attrs;
3134 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3135 pvStructInfo = *(BYTE **)pvStructInfo;
3136 attrs = pvStructInfo;
3137 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
3138 sizeof(CRYPT_ATTRIBUTES));
3139 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
3140 cbEncoded, &attrs->cAttr, &bytesNeeded, NULL);
3146 SetLastError(STATUS_ACCESS_VIOLATION);
3149 TRACE("returning %d\n", ret);
3153 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
3154 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3156 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
3158 struct AsnDecodeSequenceItem items[] = {
3159 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
3160 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3161 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
3162 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
3163 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3164 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
3167 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3168 pvStructInfo, *pcbStructInfo, pcbDecoded);
3170 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3171 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3172 pcbDecoded, algo ? algo->pszObjId : NULL);
3173 if (ret && pvStructInfo)
3175 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
3176 debugstr_a(algo->pszObjId));
3181 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
3182 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3186 struct AsnDecodeSequenceItem items[] = {
3187 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
3188 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3189 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
3190 Algorithm.pszObjId) },
3191 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
3192 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3193 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
3195 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
3197 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3198 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3199 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
3203 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
3204 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3205 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3213 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
3214 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3217 *pcbStructInfo = bytesNeeded;
3218 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3219 pvStructInfo, pcbStructInfo, bytesNeeded)))
3221 PCERT_PUBLIC_KEY_INFO info;
3223 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3224 pvStructInfo = *(BYTE **)pvStructInfo;
3225 info = pvStructInfo;
3226 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
3227 sizeof(CERT_PUBLIC_KEY_INFO);
3228 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
3229 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3230 &bytesNeeded, NULL);
3236 SetLastError(STATUS_ACCESS_VIOLATION);
3243 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
3244 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3250 SetLastError(CRYPT_E_ASN1_CORRUPT);
3253 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
3255 SetLastError(CRYPT_E_ASN1_CORRUPT);
3258 if (pbEncoded[1] > 1)
3260 SetLastError(CRYPT_E_ASN1_CORRUPT);
3267 *pcbStructInfo = sizeof(BOOL);
3270 else if (*pcbStructInfo < sizeof(BOOL))
3272 *pcbStructInfo = sizeof(BOOL);
3273 SetLastError(ERROR_MORE_DATA);
3278 *pcbStructInfo = sizeof(BOOL);
3279 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
3282 TRACE("returning %d (%08x)\n", ret, GetLastError());
3286 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
3287 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3289 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
3290 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
3293 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3294 pvStructInfo, *pcbStructInfo);
3298 SetLastError(CRYPT_E_ASN1_CORRUPT);
3301 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3302 if (1 + lenBytes > cbEncoded)
3304 SetLastError(CRYPT_E_ASN1_CORRUPT);
3307 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3309 switch (pbEncoded[0] & ASN_TYPE_MASK)
3311 case 1: /* rfc822Name */
3312 case 2: /* dNSName */
3313 case 6: /* uniformResourceIdentifier */
3314 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3316 case 4: /* directoryName */
3317 case 7: /* iPAddress */
3318 bytesNeeded += dataLen;
3320 case 8: /* registeredID */
3321 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3325 /* FIXME: ugly, shouldn't need to know internals of OID decode
3326 * function to use it.
3328 bytesNeeded += dataLen - sizeof(LPSTR);
3331 case 0: /* otherName */
3332 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3333 SetLastError(CRYPT_E_ASN1_BADTAG);
3336 case 3: /* x400Address, unimplemented */
3337 case 5: /* ediPartyName, unimplemented */
3338 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3339 SetLastError(CRYPT_E_ASN1_BADTAG);
3343 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3344 SetLastError(CRYPT_E_ASN1_CORRUPT);
3350 *pcbDecoded = 1 + lenBytes + dataLen;
3352 *pcbStructInfo = bytesNeeded;
3353 else if (*pcbStructInfo < bytesNeeded)
3355 *pcbStructInfo = bytesNeeded;
3356 SetLastError(ERROR_MORE_DATA);
3361 *pcbStructInfo = bytesNeeded;
3362 /* MS used values one greater than the asn1 ones.. sigh */
3363 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3364 switch (pbEncoded[0] & ASN_TYPE_MASK)
3366 case 1: /* rfc822Name */
3367 case 2: /* dNSName */
3368 case 6: /* uniformResourceIdentifier */
3372 for (i = 0; i < dataLen; i++)
3373 entry->u.pwszURL[i] =
3374 (WCHAR)pbEncoded[1 + lenBytes + i];
3375 entry->u.pwszURL[i] = 0;
3376 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3377 debugstr_w(entry->u.pwszURL));
3380 case 4: /* directoryName */
3381 /* The data are memory-equivalent with the IPAddress case,
3384 case 7: /* iPAddress */
3385 /* The next data pointer is in the pwszURL spot, that is,
3386 * the first 4 bytes. Need to move it to the next spot.
3388 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3389 entry->u.IPAddress.cbData = dataLen;
3390 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3393 case 8: /* registeredID */
3394 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3395 &entry->u.pszRegisteredID, &dataLen, NULL);
3404 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3405 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3409 struct AsnArrayDescriptor arrayDesc = { 0,
3410 offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3411 offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3412 sizeof(CERT_ALT_NAME_INFO),
3413 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3414 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3415 PCERT_ALT_NAME_INFO info = pvStructInfo;
3417 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3418 pvStructInfo, *pcbStructInfo, pcbDecoded);
3421 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
3422 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3423 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3424 info ? info->rgAltEntry : NULL);
3428 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3429 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
3430 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3435 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3436 pvStructInfo, *pcbStructInfo, pcbDecoded);
3438 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3441 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3442 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
3444 if (ret && pvStructInfo)
3446 CRYPT_DATA_BLOB *blob = pvStructInfo;
3453 for (i = 0; i < blob->cbData / 2; i++)
3455 temp = blob->pbData[i];
3456 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
3457 blob->pbData[blob->cbData - i - 1] = temp;
3461 TRACE("returning %d (%08x)\n", ret, GetLastError());
3465 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3466 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3467 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3473 struct AsnDecodeSequenceItem items[] = {
3474 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3475 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3476 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3477 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3478 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3479 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3480 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3481 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3482 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3483 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3484 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3487 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3488 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3489 pcbStructInfo, NULL, NULL);
3493 SetLastError(STATUS_ACCESS_VIOLATION);
3500 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3501 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3502 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3508 struct AsnDecodeSequenceItem items[] = {
3509 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3510 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3511 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3512 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3513 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3514 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3515 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3516 AuthorityCertIssuer.rgAltEntry), 0 },
3517 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3518 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3519 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3520 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3521 AuthorityCertSerialNumber.pbData), 0 },
3524 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3525 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3526 pcbStructInfo, NULL, NULL);
3530 SetLastError(STATUS_ACCESS_VIOLATION);
3537 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3538 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3541 struct AsnDecodeSequenceItem items[] = {
3542 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3543 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3544 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3545 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3546 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3547 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3549 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3551 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3552 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3553 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3556 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3557 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3558 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3562 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3563 pDecodePara, pvStructInfo, *pcbStructInfo);
3567 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3568 offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3569 offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3570 sizeof(CERT_AUTHORITY_INFO_ACCESS),
3571 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3572 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3574 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3575 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3579 SetLastError(STATUS_ACCESS_VIOLATION);
3586 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3587 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3592 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3593 pvStructInfo, *pcbStructInfo, pcbDecoded);
3595 /* The caller has already checked the tag, no need to check it again.
3596 * Check the outer length is valid:
3598 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3600 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3603 pbEncoded += 1 + lenBytes;
3604 cbEncoded -= 1 + lenBytes;
3605 if (dataLen == CMSG_INDEFINITE_LENGTH)
3606 cbEncoded -= 2; /* space for 0 TLV */
3607 /* Check the inner length is valid: */
3608 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3612 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3613 pvStructInfo, pcbStructInfo, &decodedLen);
3614 if (dataLen == CMSG_INDEFINITE_LENGTH)
3616 if (*(pbEncoded + decodedLen) != 0 ||
3617 *(pbEncoded + decodedLen + 1) != 0)
3619 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3620 *(pbEncoded + decodedLen),
3621 *(pbEncoded + decodedLen + 1));
3622 SetLastError(CRYPT_E_ASN1_CORRUPT);
3628 if (ret && pcbDecoded)
3630 *pcbDecoded = 1 + lenBytes + decodedLen;
3631 TRACE("decoded %d bytes\n", *pcbDecoded);
3638 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3639 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3642 CRYPT_CONTENT_INFO *info = pvStructInfo;
3643 struct AsnDecodeSequenceItem items[] = {
3644 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3645 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3646 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3647 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3648 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3649 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3650 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3654 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3655 pvStructInfo, *pcbStructInfo, pcbDecoded);
3657 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3658 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3659 pcbDecoded, info ? info->pszObjId : NULL);
3663 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3664 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3665 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3669 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3670 pDecodePara, pvStructInfo, *pcbStructInfo);
3674 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3675 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3676 if (ret && pvStructInfo)
3678 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3679 pcbStructInfo, *pcbStructInfo);
3682 CRYPT_CONTENT_INFO *info;
3684 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3685 pvStructInfo = *(BYTE **)pvStructInfo;
3686 info = pvStructInfo;
3687 info->pszObjId = (LPSTR)((BYTE *)info +
3688 sizeof(CRYPT_CONTENT_INFO));
3689 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3690 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3691 pcbStructInfo, NULL);
3697 SetLastError(STATUS_ACCESS_VIOLATION);
3703 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3704 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3705 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3708 struct AsnDecodeSequenceItem items[] = {
3709 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3710 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3711 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3712 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3713 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3715 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3716 CRYPT_AsnDecodePKCSContentInfoInternal,
3717 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3718 ContentInfo.pszObjId), 0 },
3719 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3720 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3721 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3724 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3725 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3730 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3731 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3732 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3736 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3737 pDecodePara, pvStructInfo, *pcbStructInfo);
3743 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3744 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3747 *pcbStructInfo = bytesNeeded;
3748 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3749 pvStructInfo, pcbStructInfo, bytesNeeded)))
3751 CERT_ALT_NAME_INFO *name;
3753 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3754 pvStructInfo = *(BYTE **)pvStructInfo;
3755 name = pvStructInfo;
3756 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3757 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3758 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3759 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3760 &bytesNeeded, NULL);
3766 SetLastError(STATUS_ACCESS_VIOLATION);
3773 struct PATH_LEN_CONSTRAINT
3775 BOOL fPathLenConstraint;
3776 DWORD dwPathLenConstraint;
3779 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3780 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3784 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3786 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3787 pvStructInfo, *pcbStructInfo, pcbDecoded);
3791 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3793 *pcbStructInfo = bytesNeeded;
3795 else if (*pcbStructInfo < bytesNeeded)
3797 SetLastError(ERROR_MORE_DATA);
3798 *pcbStructInfo = bytesNeeded;
3803 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3805 *pcbStructInfo = bytesNeeded;
3806 size = sizeof(constraint->dwPathLenConstraint);
3807 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3808 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3810 constraint->fPathLenConstraint = TRUE;
3811 TRACE("got an int, dwPathLenConstraint is %d\n",
3812 constraint->dwPathLenConstraint);
3814 TRACE("returning %d (%08x)\n", ret, GetLastError());
3818 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3819 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3823 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3824 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3825 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3826 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3827 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3828 offsetof(CERT_NAME_BLOB, pbData) };
3831 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3832 pvStructInfo, *pcbStructInfo, pcbDecoded);
3834 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
3835 NULL, &bytesNeeded, pcbDecoded);
3839 *pcbStructInfo = bytesNeeded;
3840 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
3841 pcbStructInfo, bytesNeeded)))
3843 CERT_BASIC_CONSTRAINTS_INFO *constraint;
3845 constraint = (CERT_BASIC_CONSTRAINTS_INFO *)
3846 ((BYTE *)pvStructInfo -
3847 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint));
3848 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
3849 cbEncoded, &constraint->cSubtreesConstraint, &bytesNeeded,
3853 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3857 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3858 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3859 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3865 struct AsnDecodeSequenceItem items[] = {
3866 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3867 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3868 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3869 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3870 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3871 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3872 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3873 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3874 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3876 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3879 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3880 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3881 pcbStructInfo, NULL, NULL);
3885 SetLastError(STATUS_ACCESS_VIOLATION);
3892 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3893 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3894 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3900 struct AsnDecodeSequenceItem items[] = {
3901 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3902 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3903 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3904 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3905 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3908 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3909 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3910 pcbStructInfo, NULL, NULL);
3914 SetLastError(STATUS_ACCESS_VIOLATION);
3921 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3922 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3925 struct AsnDecodeSequenceItem items[] = {
3926 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3927 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3928 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3930 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3931 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3932 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3935 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3937 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3938 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3940 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3941 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3942 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3946 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3947 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3951 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3952 offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3953 offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3954 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3955 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3956 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3959 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3960 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3962 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
3963 NULL, &bytesNeeded, pcbDecoded);
3967 *pcbStructInfo = bytesNeeded;
3968 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
3969 pcbStructInfo, bytesNeeded)))
3971 CERT_POLICY_INFO *info;
3973 info = (CERT_POLICY_INFO *)((BYTE *)pvStructInfo -
3974 offsetof(CERT_POLICY_INFO, cPolicyQualifier));
3975 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
3976 &info->cPolicyQualifier, &bytesNeeded, pcbDecoded);
3979 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3983 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3984 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3986 struct AsnDecodeSequenceItem items[] = {
3987 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3988 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3989 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3990 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3991 CRYPT_AsnDecodePolicyQualifiers, sizeof(struct GenericArray), TRUE,
3992 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3994 CERT_POLICY_INFO *info = pvStructInfo;
3997 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3998 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
4000 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4001 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4002 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
4006 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
4007 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4008 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4012 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4013 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
4017 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4018 offsetof(CERT_POLICIES_INFO, cPolicyInfo),
4019 offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
4020 sizeof(CERT_POLICIES_INFO),
4021 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
4022 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
4024 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4025 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4029 SetLastError(STATUS_ACCESS_VIOLATION);
4035 #define RSA1_MAGIC 0x31415352
4037 struct DECODED_RSA_PUB_KEY
4040 CRYPT_INTEGER_BLOB modulus;
4043 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
4044 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4045 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4051 struct AsnDecodeSequenceItem items[] = {
4052 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
4053 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
4054 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
4056 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
4057 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4059 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
4062 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4063 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
4067 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
4068 decodedKey->modulus.cbData;
4072 *pcbStructInfo = bytesNeeded;
4075 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4076 pvStructInfo, pcbStructInfo, bytesNeeded)))
4079 RSAPUBKEY *rsaPubKey;
4081 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4082 pvStructInfo = *(BYTE **)pvStructInfo;
4084 hdr->bType = PUBLICKEYBLOB;
4085 hdr->bVersion = CUR_BLOB_VERSION;
4087 hdr->aiKeyAlg = CALG_RSA_KEYX;
4088 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
4089 sizeof(BLOBHEADER));
4090 rsaPubKey->magic = RSA1_MAGIC;
4091 rsaPubKey->pubexp = decodedKey->pubexp;
4092 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
4093 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
4094 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
4095 decodedKey->modulus.cbData);
4097 LocalFree(decodedKey);
4102 SetLastError(STATUS_ACCESS_VIOLATION);
4109 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
4110 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4114 DWORD bytesNeeded, dataLen;
4116 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4117 pvStructInfo, *pcbStructInfo, pcbDecoded);
4119 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4121 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4123 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4124 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
4126 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
4128 *pcbDecoded = 1 + lenBytes + dataLen;
4130 *pcbStructInfo = bytesNeeded;
4131 else if (*pcbStructInfo < bytesNeeded)
4133 SetLastError(ERROR_MORE_DATA);
4134 *pcbStructInfo = bytesNeeded;
4139 CRYPT_DATA_BLOB *blob;
4141 *pcbStructInfo = bytesNeeded;
4142 blob = pvStructInfo;
4143 blob->cbData = dataLen;
4144 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4145 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
4148 assert(blob->pbData);
4150 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
4158 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
4159 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4160 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4164 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4165 pDecodePara, pvStructInfo, *pcbStructInfo);
4173 SetLastError(CRYPT_E_ASN1_CORRUPT);
4176 else if (pbEncoded[0] != ASN_OCTETSTRING)
4178 SetLastError(CRYPT_E_ASN1_BADTAG);
4181 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4182 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4185 *pcbStructInfo = bytesNeeded;
4186 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4187 pvStructInfo, pcbStructInfo, bytesNeeded)))
4189 CRYPT_DATA_BLOB *blob;
4191 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4192 pvStructInfo = *(BYTE **)pvStructInfo;
4193 blob = pvStructInfo;
4194 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
4195 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4196 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4197 &bytesNeeded, NULL);
4203 SetLastError(STATUS_ACCESS_VIOLATION);
4210 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4211 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4214 DWORD bytesNeeded, dataLen;
4215 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4217 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
4218 pvStructInfo, *pcbStructInfo, pcbDecoded);
4220 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4222 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4223 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
4225 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
4227 *pcbDecoded = 1 + lenBytes + dataLen;
4229 *pcbStructInfo = bytesNeeded;
4230 else if (*pcbStructInfo < bytesNeeded)
4232 *pcbStructInfo = bytesNeeded;
4233 SetLastError(ERROR_MORE_DATA);
4238 CRYPT_BIT_BLOB *blob;
4240 *pcbStructInfo = bytesNeeded;
4241 blob = pvStructInfo;
4242 blob->cbData = dataLen - 1;
4243 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
4244 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4246 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
4250 assert(blob->pbData);
4253 BYTE mask = 0xff << blob->cUnusedBits;
4255 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
4257 blob->pbData[blob->cbData - 1] &= mask;
4265 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
4266 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4267 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4271 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
4272 pDecodePara, pvStructInfo, pcbStructInfo);
4280 SetLastError(CRYPT_E_ASN1_CORRUPT);
4283 else if (pbEncoded[0] != ASN_BITSTRING)
4285 SetLastError(CRYPT_E_ASN1_BADTAG);
4288 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4289 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4292 *pcbStructInfo = bytesNeeded;
4293 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4294 pvStructInfo, pcbStructInfo, bytesNeeded)))
4296 CRYPT_BIT_BLOB *blob;
4298 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4299 pvStructInfo = *(BYTE **)pvStructInfo;
4300 blob = pvStructInfo;
4301 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
4302 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4303 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4304 &bytesNeeded, NULL);
4310 SetLastError(STATUS_ACCESS_VIOLATION);
4314 TRACE("returning %d (%08x)\n", ret, GetLastError());
4318 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4319 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4320 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4323 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
4324 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
4325 DWORD size = sizeof(buf);
4327 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
4328 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
4333 *pcbStructInfo = sizeof(int);
4334 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
4338 if (blob->pbData[blob->cbData - 1] & 0x80)
4340 /* initialize to a negative value to sign-extend */
4345 for (i = 0; i < blob->cbData; i++)
4348 val |= blob->pbData[blob->cbData - i - 1];
4350 memcpy(pvStructInfo, &val, sizeof(int));
4353 else if (GetLastError() == ERROR_MORE_DATA)
4354 SetLastError(CRYPT_E_ASN1_LARGE);
4358 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
4359 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4360 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4370 SetLastError(CRYPT_E_ASN1_EOD);
4373 else if (pbEncoded[0] != ASN_INTEGER)
4375 SetLastError(CRYPT_E_ASN1_BADTAG);
4379 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4380 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4384 *pcbStructInfo = bytesNeeded;
4385 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4386 pvStructInfo, pcbStructInfo, bytesNeeded)))
4388 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4389 pvStructInfo = *(BYTE **)pvStructInfo;
4390 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4391 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4392 &bytesNeeded, NULL);
4398 SetLastError(STATUS_ACCESS_VIOLATION);
4405 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4406 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4410 DWORD bytesNeeded, dataLen;
4412 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4414 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4416 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4418 *pcbDecoded = 1 + lenBytes + dataLen;
4420 *pcbStructInfo = bytesNeeded;
4421 else if (*pcbStructInfo < bytesNeeded)
4423 *pcbStructInfo = bytesNeeded;
4424 SetLastError(ERROR_MORE_DATA);
4429 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4431 *pcbStructInfo = bytesNeeded;
4432 blob->cbData = dataLen;
4433 assert(blob->pbData);
4438 for (i = 0; i < blob->cbData; i++)
4440 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4449 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4450 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4451 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4459 if (pbEncoded[0] != ASN_INTEGER)
4461 SetLastError(CRYPT_E_ASN1_BADTAG);
4465 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4466 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4470 *pcbStructInfo = bytesNeeded;
4471 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4472 pvStructInfo, pcbStructInfo, bytesNeeded)))
4474 CRYPT_INTEGER_BLOB *blob;
4476 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4477 pvStructInfo = *(BYTE **)pvStructInfo;
4478 blob = pvStructInfo;
4479 blob->pbData = (BYTE *)pvStructInfo +
4480 sizeof(CRYPT_INTEGER_BLOB);
4481 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4482 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4483 &bytesNeeded, NULL);
4489 SetLastError(STATUS_ACCESS_VIOLATION);
4496 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4497 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4502 if (pbEncoded[0] == ASN_INTEGER)
4504 DWORD bytesNeeded, dataLen;
4506 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4508 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4511 *pcbDecoded = 1 + lenBytes + dataLen;
4512 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4514 *pcbStructInfo = bytesNeeded;
4515 else if (*pcbStructInfo < bytesNeeded)
4517 *pcbStructInfo = bytesNeeded;
4518 SetLastError(ERROR_MORE_DATA);
4523 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4525 *pcbStructInfo = bytesNeeded;
4526 blob->cbData = dataLen;
4527 assert(blob->pbData);
4528 /* remove leading zero byte if it exists */
4529 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4538 for (i = 0; i < blob->cbData; i++)
4540 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4549 SetLastError(CRYPT_E_ASN1_BADTAG);
4555 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4556 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4557 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4565 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4566 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4569 *pcbStructInfo = bytesNeeded;
4570 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4571 pvStructInfo, pcbStructInfo, bytesNeeded)))
4573 CRYPT_INTEGER_BLOB *blob;
4575 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4576 pvStructInfo = *(BYTE **)pvStructInfo;
4577 blob = pvStructInfo;
4578 blob->pbData = (BYTE *)pvStructInfo +
4579 sizeof(CRYPT_INTEGER_BLOB);
4580 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4581 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4582 &bytesNeeded, NULL);
4588 SetLastError(STATUS_ACCESS_VIOLATION);
4595 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4596 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4597 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4603 *pcbStructInfo = sizeof(int);
4608 if (pbEncoded[0] == ASN_ENUMERATED)
4610 unsigned int val = 0, i;
4614 SetLastError(CRYPT_E_ASN1_EOD);
4617 else if (pbEncoded[1] == 0)
4619 SetLastError(CRYPT_E_ASN1_CORRUPT);
4624 /* A little strange looking, but we have to accept a sign byte:
4625 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4626 * assuming a small length is okay here, it has to be in short
4629 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4631 SetLastError(CRYPT_E_ASN1_LARGE);
4634 for (i = 0; i < pbEncoded[1]; i++)
4637 val |= pbEncoded[2 + i];
4639 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4640 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4642 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4643 pvStructInfo = *(BYTE **)pvStructInfo;
4644 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4650 SetLastError(CRYPT_E_ASN1_BADTAG);
4656 SetLastError(STATUS_ACCESS_VIOLATION);
4663 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4666 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4671 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4673 if (!isdigit(*(pbEncoded))) \
4675 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4681 (word) += *(pbEncoded)++ - '0'; \
4686 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4687 SYSTEMTIME *sysTime)
4691 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4693 WORD hours, minutes = 0;
4694 BYTE sign = *pbEncoded++;
4697 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4698 if (ret && hours >= 24)
4700 SetLastError(CRYPT_E_ASN1_CORRUPT);
4705 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4706 if (ret && minutes >= 60)
4708 SetLastError(CRYPT_E_ASN1_CORRUPT);
4716 sysTime->wHour += hours;
4717 sysTime->wMinute += minutes;
4721 if (hours > sysTime->wHour)
4724 sysTime->wHour = 24 - (hours - sysTime->wHour);
4727 sysTime->wHour -= hours;
4728 if (minutes > sysTime->wMinute)
4731 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4734 sysTime->wMinute -= minutes;
4741 #define MIN_ENCODED_TIME_LENGTH 10
4743 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4744 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4749 if (pbEncoded[0] == ASN_UTCTIME)
4752 SetLastError(CRYPT_E_ASN1_EOD);
4753 else if (pbEncoded[1] > 0x7f)
4755 /* long-form date strings really can't be valid */
4756 SetLastError(CRYPT_E_ASN1_CORRUPT);
4760 SYSTEMTIME sysTime = { 0 };
4761 BYTE len = pbEncoded[1];
4763 if (len < MIN_ENCODED_TIME_LENGTH)
4764 SetLastError(CRYPT_E_ASN1_CORRUPT);
4769 *pcbDecoded = 2 + len;
4771 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4772 if (sysTime.wYear >= 50)
4773 sysTime.wYear += 1900;
4775 sysTime.wYear += 2000;
4776 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4777 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4778 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4779 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4782 if (len >= 2 && isdigit(*pbEncoded) &&
4783 isdigit(*(pbEncoded + 1)))
4784 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4786 else if (isdigit(*pbEncoded))
4787 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4790 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4796 *pcbStructInfo = sizeof(FILETIME);
4797 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4799 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4805 SetLastError(CRYPT_E_ASN1_BADTAG);
4809 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4810 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4811 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4819 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4820 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4824 *pcbStructInfo = bytesNeeded;
4825 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4826 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4828 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4829 pvStructInfo = *(BYTE **)pvStructInfo;
4830 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4831 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4832 &bytesNeeded, NULL);
4838 SetLastError(STATUS_ACCESS_VIOLATION);
4844 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4845 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4850 if (pbEncoded[0] == ASN_GENERALTIME)
4853 SetLastError(CRYPT_E_ASN1_EOD);
4854 else if (pbEncoded[1] > 0x7f)
4856 /* long-form date strings really can't be valid */
4857 SetLastError(CRYPT_E_ASN1_CORRUPT);
4861 BYTE len = pbEncoded[1];
4863 if (len < MIN_ENCODED_TIME_LENGTH)
4864 SetLastError(CRYPT_E_ASN1_CORRUPT);
4867 SYSTEMTIME sysTime = { 0 };
4871 *pcbDecoded = 2 + len;
4873 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4874 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4875 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4876 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4879 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4882 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4884 if (ret && len > 0 && (*pbEncoded == '.' ||
4891 /* workaround macro weirdness */
4892 digits = min(len, 3);
4893 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4894 sysTime.wMilliseconds);
4897 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4903 *pcbStructInfo = sizeof(FILETIME);
4904 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4906 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4912 SetLastError(CRYPT_E_ASN1_BADTAG);
4916 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4917 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4921 InternalDecodeFunc decode = NULL;
4923 if (pbEncoded[0] == ASN_UTCTIME)
4924 decode = CRYPT_AsnDecodeUtcTimeInternal;
4925 else if (pbEncoded[0] == ASN_GENERALTIME)
4926 decode = CRYPT_AsnDecodeGeneralizedTime;
4928 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4929 pcbStructInfo, pcbDecoded);
4932 SetLastError(CRYPT_E_ASN1_BADTAG);
4938 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4939 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4940 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4948 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4949 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4953 *pcbStructInfo = bytesNeeded;
4954 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4955 pvStructInfo, pcbStructInfo, bytesNeeded)))
4957 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4958 pvStructInfo = *(BYTE **)pvStructInfo;
4959 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4960 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4961 &bytesNeeded, NULL);
4967 SetLastError(STATUS_ACCESS_VIOLATION);
4974 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4975 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4976 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4982 if (pbEncoded[0] == ASN_SEQUENCEOF)
4984 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4986 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4991 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4992 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4994 ptr = pbEncoded + 1 + lenBytes;
4995 remainingLen = dataLen;
4996 while (ret && remainingLen)
5000 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
5003 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
5005 remainingLen -= 1 + nextLenBytes + nextLen;
5006 ptr += 1 + nextLenBytes + nextLen;
5007 bytesNeeded += sizeof(CRYPT_DER_BLOB);
5008 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
5009 bytesNeeded += 1 + nextLenBytes + nextLen;
5015 CRYPT_SEQUENCE_OF_ANY *seq;
5020 *pcbStructInfo = bytesNeeded;
5021 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5022 pvStructInfo, pcbStructInfo, bytesNeeded)))
5024 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5025 pvStructInfo = *(BYTE **)pvStructInfo;
5027 seq->cValue = cValue;
5028 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
5030 nextPtr = (BYTE *)seq->rgValue +
5031 cValue * sizeof(CRYPT_DER_BLOB);
5032 ptr = pbEncoded + 1 + lenBytes;
5033 remainingLen = dataLen;
5035 while (ret && remainingLen)
5039 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
5042 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
5044 seq->rgValue[i].cbData = 1 + nextLenBytes +
5046 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
5047 seq->rgValue[i].pbData = (BYTE *)ptr;
5050 seq->rgValue[i].pbData = nextPtr;
5051 memcpy(nextPtr, ptr, 1 + nextLenBytes +
5053 nextPtr += 1 + nextLenBytes + nextLen;
5055 remainingLen -= 1 + nextLenBytes + nextLen;
5056 ptr += 1 + nextLenBytes + nextLen;
5066 SetLastError(CRYPT_E_ASN1_BADTAG);
5072 SetLastError(STATUS_ACCESS_VIOLATION);
5079 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
5080 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5085 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
5087 DWORD bytesNeeded, dataLen;
5089 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
5091 struct AsnArrayDescriptor arrayDesc = {
5092 ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5093 offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
5094 offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
5095 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
5096 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
5097 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
5098 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
5103 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc,
5104 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
5105 NULL, &nameLen, NULL);
5106 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
5107 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
5110 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
5112 *pcbDecoded = 1 + lenBytes + dataLen;
5114 *pcbStructInfo = bytesNeeded;
5115 else if (*pcbStructInfo < bytesNeeded)
5117 *pcbStructInfo = bytesNeeded;
5118 SetLastError(ERROR_MORE_DATA);
5123 CRL_DIST_POINT_NAME *name = pvStructInfo;
5125 *pcbStructInfo = bytesNeeded;
5128 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
5129 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc,
5130 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
5131 &name->u.FullName.cAltEntry, &nameLen, NULL);
5134 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
5140 SetLastError(CRYPT_E_ASN1_BADTAG);
5146 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
5147 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5149 struct AsnDecodeSequenceItem items[] = {
5150 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
5151 DistPointName), CRYPT_AsnDecodeDistPointName,
5152 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
5153 DistPointName.u.FullName.rgAltEntry), 0 },
5154 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
5155 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
5156 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
5157 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
5158 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
5159 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
5161 CRL_DIST_POINT *point = pvStructInfo;
5164 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5165 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5166 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
5170 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
5171 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5172 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5176 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5177 pDecodePara, pvStructInfo, *pcbStructInfo);
5181 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5182 offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
5183 offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
5184 sizeof(CRL_DIST_POINTS_INFO),
5185 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
5186 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
5188 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
5189 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
5193 SetLastError(STATUS_ACCESS_VIOLATION);
5200 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
5201 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5202 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5206 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5207 pDecodePara, pvStructInfo, *pcbStructInfo);
5211 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5212 offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
5213 offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
5214 sizeof(CERT_ENHKEY_USAGE),
5215 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
5217 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
5218 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
5222 SetLastError(STATUS_ACCESS_VIOLATION);
5229 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
5230 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5231 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5235 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5236 pDecodePara, pvStructInfo, *pcbStructInfo);
5240 struct AsnDecodeSequenceItem items[] = {
5241 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
5242 DistPointName), CRYPT_AsnDecodeDistPointName,
5243 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
5244 offsetof(CRL_ISSUING_DIST_POINT,
5245 DistPointName.u.FullName.rgAltEntry), 0 },
5246 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
5247 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5249 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
5250 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5252 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
5253 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
5254 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
5255 OnlySomeReasonFlags.pbData), 0 },
5256 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
5257 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
5260 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5261 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5262 pcbStructInfo, NULL, NULL);
5266 SetLastError(STATUS_ACCESS_VIOLATION);
5273 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
5274 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5279 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5280 pvStructInfo, *pcbStructInfo, pcbDecoded);
5284 SetLastError(CRYPT_E_ASN1_EOD);
5287 if (pbEncoded[0] != (ASN_CONTEXT | 1))
5289 SetLastError(CRYPT_E_ASN1_BADTAG);
5292 /* The BOOL is implicit: if the integer is present, then it's TRUE */
5293 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
5294 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
5296 if (ret && pvStructInfo)
5297 *(BOOL *)pvStructInfo = TRUE;
5298 TRACE("returning %d\n", ret);
5302 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
5303 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5307 struct AsnDecodeSequenceItem items[] = {
5308 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
5309 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
5310 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
5311 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
5312 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
5313 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
5314 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
5317 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
5319 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5320 pvStructInfo, *pcbStructInfo, pcbDecoded);
5322 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5323 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5324 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
5327 TRACE("%d\n", *pcbDecoded);
5328 if (*pcbDecoded < cbEncoded)
5329 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
5330 *(pbEncoded + *pcbDecoded + 1));
5332 TRACE("returning %d\n", ret);
5336 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
5337 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5341 struct AsnArrayDescriptor arrayDesc = { 0,
5342 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5343 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
5344 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5346 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5347 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5350 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5351 pvStructInfo, *pcbStructInfo, pcbDecoded);
5353 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5354 NULL, &bytesNeeded, pcbDecoded)))
5357 *pcbStructInfo = bytesNeeded;
5358 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5359 pcbStructInfo, bytesNeeded)))
5361 CERT_NAME_CONSTRAINTS_INFO *info = (CERT_NAME_CONSTRAINTS_INFO *)
5362 ((BYTE *)pvStructInfo -
5363 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree));
5365 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5366 &info->cPermittedSubtree, &bytesNeeded, pcbDecoded);
5372 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
5373 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5377 struct AsnArrayDescriptor arrayDesc = { 0,
5378 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5379 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
5380 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5381 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5382 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5385 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5386 pvStructInfo, *pcbStructInfo, pcbDecoded);
5388 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5389 NULL, &bytesNeeded, pcbDecoded)))
5392 *pcbStructInfo = bytesNeeded;
5393 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5394 pcbStructInfo, bytesNeeded)))
5396 CERT_NAME_CONSTRAINTS_INFO *info = (CERT_NAME_CONSTRAINTS_INFO *)
5397 ((BYTE *)pvStructInfo -
5398 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree));
5400 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5401 &info->cExcludedSubtree, &bytesNeeded, pcbDecoded);
5407 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
5408 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5409 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5413 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5414 pDecodePara, pvStructInfo, *pcbStructInfo);
5418 struct AsnDecodeSequenceItem items[] = {
5419 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5420 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5421 CRYPT_AsnDecodePermittedSubtree,
5422 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5423 cExcludedSubtree), TRUE, TRUE,
5424 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
5425 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
5426 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5427 CRYPT_AsnDecodeExcludedSubtree,
5428 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5430 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
5433 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5434 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5435 pcbStructInfo, NULL, NULL);
5439 SetLastError(STATUS_ACCESS_VIOLATION);
5445 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5446 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5450 struct AsnDecodeSequenceItem items[] = {
5451 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5452 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5454 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5455 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5456 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5458 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5460 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5461 pvStructInfo, *pcbStructInfo, pcbDecoded);
5463 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5464 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5465 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5466 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5468 SetLastError(CRYPT_E_ASN1_CORRUPT);
5471 TRACE("returning %d\n", ret);
5475 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5476 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5479 CMSG_SIGNER_INFO *info = pvStructInfo;
5480 struct AsnDecodeSequenceItem items[] = {
5481 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5482 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5483 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5484 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5485 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5486 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5487 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5488 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5489 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5490 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5491 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5492 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5493 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5494 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5495 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5496 HashEncryptionAlgorithm.pszObjId), 0 },
5497 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5498 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5499 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5500 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5501 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5502 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5503 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5507 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5508 pvStructInfo, *pcbStructInfo);
5510 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5511 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5512 pcbDecoded, info ? info->Issuer.pbData : NULL);
5516 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5517 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5518 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5522 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5523 pDecodePara, pvStructInfo, *pcbStructInfo);
5527 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5528 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5529 if (ret && pvStructInfo)
5531 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5532 pcbStructInfo, *pcbStructInfo);
5535 CMSG_SIGNER_INFO *info;
5537 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5538 pvStructInfo = *(BYTE **)pvStructInfo;
5539 info = pvStructInfo;
5540 info->Issuer.pbData = ((BYTE *)info +
5541 sizeof(CMSG_SIGNER_INFO));
5542 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5543 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5544 pcbStructInfo, NULL);
5550 SetLastError(STATUS_ACCESS_VIOLATION);
5553 TRACE("returning %d\n", ret);
5557 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5558 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5562 struct AsnArrayDescriptor arrayDesc = { 0,
5563 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5564 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5565 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5566 CRYPT_AsnDecodeCopyBytes,
5567 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5570 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5571 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5573 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5574 NULL, &bytesNeeded, pcbDecoded)))
5577 *pcbStructInfo = bytesNeeded;
5578 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5579 pcbStructInfo, bytesNeeded)))
5581 CRYPT_SIGNED_INFO *info = (CRYPT_SIGNED_INFO *)
5582 ((BYTE *)pvStructInfo - offsetof(CRYPT_SIGNED_INFO, cCertEncoded));
5584 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5585 &info->cCertEncoded, &bytesNeeded, pcbDecoded);
5591 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5592 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5596 struct AsnArrayDescriptor arrayDesc = { 0,
5597 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5598 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5599 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5600 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5601 TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5604 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5605 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5607 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5608 NULL, &bytesNeeded, pcbDecoded)))
5611 *pcbStructInfo = bytesNeeded;
5612 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5613 pcbStructInfo, bytesNeeded)))
5615 CRYPT_SIGNED_INFO *info = (CRYPT_SIGNED_INFO *)
5616 ((BYTE *)pvStructInfo - offsetof(CRYPT_SIGNED_INFO, cCrlEncoded));
5618 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5619 &info->cCrlEncoded, &bytesNeeded, pcbDecoded);
5625 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5626 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5629 CERT_ID *id = pvStructInfo;
5632 if (*pbEncoded == ASN_SEQUENCEOF)
5634 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5635 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5639 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5640 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5641 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5642 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5644 *pcbStructInfo = sizeof(CERT_ID);
5647 else if (*pbEncoded == (ASN_CONTEXT | 0))
5649 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5650 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5654 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5655 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5656 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5657 sizeof(CRYPT_DATA_BLOB);
5659 *pcbStructInfo = sizeof(CERT_ID);
5663 SetLastError(CRYPT_E_ASN1_BADTAG);
5667 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5668 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5671 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5672 struct AsnDecodeSequenceItem items[] = {
5673 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5674 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5675 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5676 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5677 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5678 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5679 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5680 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5681 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5682 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5683 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5684 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5685 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5686 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5687 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5688 HashEncryptionAlgorithm.pszObjId), 0 },
5689 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5690 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5691 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5692 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5693 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5694 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5695 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5699 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5700 pvStructInfo, *pcbStructInfo);
5702 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5703 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5704 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5708 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5709 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5710 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5714 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5715 pDecodePara, pvStructInfo, *pcbStructInfo);
5719 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5720 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5721 if (ret && pvStructInfo)
5723 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5724 pcbStructInfo, *pcbStructInfo);
5727 CMSG_CMS_SIGNER_INFO *info;
5729 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5730 pvStructInfo = *(BYTE **)pvStructInfo;
5731 info = pvStructInfo;
5732 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5733 sizeof(CMSG_CMS_SIGNER_INFO));
5734 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5735 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5736 pcbStructInfo, NULL);
5742 SetLastError(STATUS_ACCESS_VIOLATION);
5745 TRACE("returning %d\n", ret);
5749 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5750 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5753 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5754 offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5755 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5756 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5757 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5758 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5761 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5762 pvStructInfo, *pcbStructInfo, pcbDecoded);
5764 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5765 NULL, &bytesNeeded, pcbDecoded)))
5768 *pcbStructInfo = bytesNeeded;
5769 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5770 pcbStructInfo, bytesNeeded)))
5772 CRYPT_SIGNED_INFO *info = (CRYPT_SIGNED_INFO *)
5773 ((BYTE *)pvStructInfo - offsetof(CRYPT_SIGNED_INFO, cSignerInfo));
5775 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5776 &info->cSignerInfo, &bytesNeeded, pcbDecoded);
5782 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5783 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5784 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5787 struct AsnDecodeSequenceItem items[] = {
5788 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5789 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5790 /* Placeholder for the hash algorithms - redundant with those in the
5791 * signers, so just ignore them.
5793 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5794 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5795 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5796 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5797 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5798 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5799 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5800 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5801 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5802 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5803 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5804 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5805 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5806 CRYPT_DecodeSignerArray,
5807 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5808 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5811 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5812 pDecodePara, signedInfo, *pcbSignedInfo);
5814 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5815 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5817 TRACE("returning %d\n", ret);
5821 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5822 LPCSTR lpszStructType)
5824 CryptDecodeObjectExFunc decodeFunc = NULL;
5826 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5827 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5829 SetLastError(ERROR_FILE_NOT_FOUND);
5832 if (!HIWORD(lpszStructType))
5834 switch (LOWORD(lpszStructType))
5836 case LOWORD(X509_CERT):
5837 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5839 case LOWORD(X509_CERT_TO_BE_SIGNED):
5840 decodeFunc = CRYPT_AsnDecodeCert;
5842 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5843 decodeFunc = CRYPT_AsnDecodeCRL;
5845 case LOWORD(X509_EXTENSIONS):
5846 decodeFunc = CRYPT_AsnDecodeExtensions;
5848 case LOWORD(X509_NAME_VALUE):
5849 decodeFunc = CRYPT_AsnDecodeNameValue;
5851 case LOWORD(X509_NAME):
5852 decodeFunc = CRYPT_AsnDecodeName;
5854 case LOWORD(X509_PUBLIC_KEY_INFO):
5855 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5857 case LOWORD(X509_AUTHORITY_KEY_ID):
5858 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5860 case LOWORD(X509_ALTERNATE_NAME):
5861 decodeFunc = CRYPT_AsnDecodeAltName;
5863 case LOWORD(X509_BASIC_CONSTRAINTS):
5864 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5866 case LOWORD(X509_BASIC_CONSTRAINTS2):
5867 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5869 case LOWORD(X509_CERT_POLICIES):
5870 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5872 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5873 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5875 case LOWORD(X509_UNICODE_NAME):
5876 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5878 case LOWORD(PKCS_ATTRIBUTE):
5879 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5881 case LOWORD(X509_UNICODE_NAME_VALUE):
5882 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5884 case LOWORD(X509_OCTET_STRING):
5885 decodeFunc = CRYPT_AsnDecodeOctets;
5887 case LOWORD(X509_BITS):
5888 case LOWORD(X509_KEY_USAGE):
5889 decodeFunc = CRYPT_AsnDecodeBits;
5891 case LOWORD(X509_INTEGER):
5892 decodeFunc = CRYPT_AsnDecodeInt;
5894 case LOWORD(X509_MULTI_BYTE_INTEGER):
5895 decodeFunc = CRYPT_AsnDecodeInteger;
5897 case LOWORD(X509_MULTI_BYTE_UINT):
5898 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5900 case LOWORD(X509_ENUMERATED):
5901 decodeFunc = CRYPT_AsnDecodeEnumerated;
5903 case LOWORD(X509_CHOICE_OF_TIME):
5904 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5906 case LOWORD(X509_AUTHORITY_KEY_ID2):
5907 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5909 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5910 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5912 case LOWORD(PKCS_CONTENT_INFO):
5913 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5915 case LOWORD(X509_SEQUENCE_OF_ANY):
5916 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5918 case LOWORD(PKCS_UTC_TIME):
5919 decodeFunc = CRYPT_AsnDecodeUtcTime;
5921 case LOWORD(X509_CRL_DIST_POINTS):
5922 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5924 case LOWORD(X509_ENHANCED_KEY_USAGE):
5925 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5927 case LOWORD(PKCS_CTL):
5928 decodeFunc = CRYPT_AsnDecodeCTL;
5930 case LOWORD(PKCS_SMIME_CAPABILITIES):
5931 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5933 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5934 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5936 case LOWORD(PKCS_ATTRIBUTES):
5937 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5939 case LOWORD(X509_ISSUING_DIST_POINT):
5940 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5942 case LOWORD(X509_NAME_CONSTRAINTS):
5943 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5945 case LOWORD(PKCS7_SIGNER_INFO):
5946 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5948 case LOWORD(CMS_SIGNER_INFO):
5949 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5953 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5954 decodeFunc = CRYPT_AsnDecodeExtensions;
5955 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5956 decodeFunc = CRYPT_AsnDecodeUtcTime;
5957 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5958 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5959 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5960 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5961 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5962 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5963 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5964 decodeFunc = CRYPT_AsnDecodeEnumerated;
5965 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5966 decodeFunc = CRYPT_AsnDecodeBits;
5967 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5968 decodeFunc = CRYPT_AsnDecodeOctets;
5969 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5970 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5971 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5972 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5973 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5974 decodeFunc = CRYPT_AsnDecodeAltName;
5975 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5976 decodeFunc = CRYPT_AsnDecodeAltName;
5977 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5978 decodeFunc = CRYPT_AsnDecodeAltName;
5979 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5980 decodeFunc = CRYPT_AsnDecodeAltName;
5981 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5982 decodeFunc = CRYPT_AsnDecodeAltName;
5983 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5984 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5985 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5986 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5987 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5988 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5989 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5990 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5991 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5992 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5993 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5994 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5995 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5996 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5997 else if (!strcmp(lpszStructType, szOID_CTL))
5998 decodeFunc = CRYPT_AsnDecodeCTL;
6002 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
6003 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
6005 static HCRYPTOIDFUNCSET set = NULL;
6006 CryptDecodeObjectFunc decodeFunc = NULL;
6009 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
6010 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
6011 (void **)&decodeFunc, hFunc);
6015 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
6016 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
6018 static HCRYPTOIDFUNCSET set = NULL;
6019 CryptDecodeObjectExFunc decodeFunc = NULL;
6022 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
6023 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
6024 (void **)&decodeFunc, hFunc);
6028 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
6029 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
6030 DWORD *pcbStructInfo)
6033 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
6034 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
6035 HCRYPTOIDFUNCADDR hFunc = NULL;
6037 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
6038 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
6039 pvStructInfo, pcbStructInfo);
6041 if (!pvStructInfo && !pcbStructInfo)
6043 SetLastError(ERROR_INVALID_PARAMETER);
6046 if (cbEncoded > MAX_ENCODED_LEN)
6048 SetLastError(CRYPT_E_ASN1_LARGE);
6052 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
6055 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
6056 debugstr_a(lpszStructType));
6057 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
6058 lpszStructType, &hFunc);
6059 if (!pCryptDecodeObject)
6060 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
6061 lpszStructType, &hFunc);
6063 if (pCryptDecodeObject)
6064 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6065 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6066 else if (pCryptDecodeObjectEx)
6067 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
6068 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
6069 pvStructInfo, pcbStructInfo);
6071 CryptFreeOIDFunctionAddress(hFunc, 0);
6072 TRACE_(crypt)("returning %d\n", ret);
6076 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
6077 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
6078 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
6081 CryptDecodeObjectExFunc decodeFunc;
6082 HCRYPTOIDFUNCADDR hFunc = NULL;
6084 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6085 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
6086 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6088 if (!pvStructInfo && !pcbStructInfo)
6090 SetLastError(ERROR_INVALID_PARAMETER);
6093 if (cbEncoded > MAX_ENCODED_LEN)
6095 SetLastError(CRYPT_E_ASN1_LARGE);
6099 SetLastError(NOERROR);
6100 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
6101 *(BYTE **)pvStructInfo = NULL;
6102 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
6105 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
6106 debugstr_a(lpszStructType));
6107 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
6111 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
6112 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6115 CryptDecodeObjectFunc pCryptDecodeObject =
6116 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
6118 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6119 * directly, as that could cause an infinite loop.
6121 if (pCryptDecodeObject)
6123 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6125 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6126 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
6127 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
6128 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
6129 ret = pCryptDecodeObject(dwCertEncodingType,
6130 lpszStructType, pbEncoded, cbEncoded, dwFlags,
6131 *(BYTE **)pvStructInfo, pcbStructInfo);
6134 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6135 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6139 CryptFreeOIDFunctionAddress(hFunc, 0);
6140 TRACE_(crypt)("returning %d\n", ret);
6144 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
6148 TRACE_(crypt)("(%p)\n", pPFX);
6150 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6151 * version integer of length 1 (3 encoded byes) and at least one other
6152 * datum (two encoded bytes), plus at least two bytes for the outer
6153 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6155 if (pPFX->cbData < 7)
6157 else if (pPFX->pbData[0] == ASN_SEQUENCE)
6161 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
6163 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
6165 /* Need at least three bytes for the integer version */
6166 if (pPFX->cbData < 1 + lenLen + 3)
6168 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
6169 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
6170 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
6179 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6182 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);