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