2 * Copyright 2005-2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
67 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
68 DWORD
, DWORD
, void *, DWORD
*);
69 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
70 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
76 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
78 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
82 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
88 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
92 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
93 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
94 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
97 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
99 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
);
235 *pcbStructInfo
= bytesNeeded
;
239 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
241 if (pDecodePara
&& pDecodePara
->pfnFree
)
242 pDecodePara
->pfnFree(pv
);
247 /* Helper function to check *pcbStructInfo and set it to the required size.
248 * Assumes pvStructInfo is not NULL.
250 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
254 if (*pcbStructInfo
< bytesNeeded
)
256 *pcbStructInfo
= bytesNeeded
;
257 SetLastError(ERROR_MORE_DATA
);
262 *pcbStructInfo
= bytesNeeded
;
269 * The expected tag of the item. If tag is 0, decodeFunc is called
270 * regardless of the tag value seen.
272 * A sequence is decoded into a struct. The offset member is the
273 * offset of this item within that struct.
275 * The decoder function to use. If this is NULL, then the member isn't
276 * decoded, but minSize space is reserved for it.
278 * The minimum amount of space occupied after decoding. You must set this.
280 * If true, and the tag doesn't match the expected tag for this item,
281 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
282 * filled with 0 for this member.
283 * hasPointer, pointerOffset:
284 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
285 * the offset within the struct of the data pointer (or to the
286 * first data pointer, if more than one exist).
288 * Used by CRYPT_AsnDecodeSequence, not for your use.
290 struct AsnDecodeSequenceItem
294 InternalDecodeFunc decodeFunc
;
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
309 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
310 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
311 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
314 DWORD i
, decoded
= 0;
315 const BYTE
*ptr
= pbEncoded
;
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
318 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
320 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
322 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
326 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
327 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
329 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
331 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
333 DWORD itemEncodedLen
;
335 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
336 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
338 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
339 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
341 TRACE("Setting next pointer to %p\n",
343 *(BYTE
**)((BYTE
*)pvStructInfo
+
344 items
[i
].pointerOffset
) = nextData
;
346 if (items
[i
].decodeFunc
)
351 TRACE("decoding item %d\n", i
);
353 TRACE("sizing item %d\n", i
);
354 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
356 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
357 : NULL
, &items
[i
].size
, &itemDecoded
);
360 /* Account for alignment padding */
361 if (items
[i
].size
% sizeof(DWORD_PTR
))
362 items
[i
].size
+= sizeof(DWORD_PTR
) -
363 items
[i
].size
% sizeof(DWORD_PTR
);
364 TRACE("item %d size: %d\n", i
, items
[i
].size
);
365 if (nextData
&& items
[i
].hasPointer
&&
366 items
[i
].size
> items
[i
].minSize
)
367 nextData
+= items
[i
].size
- items
[i
].minSize
;
368 if (itemDecoded
> itemEncodedLen
)
370 WARN("decoded length %d exceeds encoded %d\n",
371 itemDecoded
, itemEncodedLen
);
372 SetLastError(CRYPT_E_ASN1_CORRUPT
);
377 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
379 if (itemDecoded
> itemEncodedLen
- 2 ||
380 *(ptr
+ itemDecoded
) != 0 ||
381 *(ptr
+ itemDecoded
+ 1) != 0)
383 TRACE("expected 0 TLV\n");
384 SetLastError(CRYPT_E_ASN1_CORRUPT
);
393 decoded
+= itemDecoded
;
394 TRACE("item %d: decoded %d bytes\n", i
,
399 else if (items
[i
].optional
&&
400 GetLastError() == CRYPT_E_ASN1_BADTAG
)
402 TRACE("skipping optional item %d\n", i
);
403 items
[i
].size
= items
[i
].minSize
;
404 SetLastError(NOERROR
);
408 TRACE("item %d failed: %08x\n", i
,
411 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
413 ERR("can't use indefinite length encoding without a decoder\n");
414 SetLastError(CRYPT_E_ASN1_CORRUPT
);
419 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
420 ptr
+= itemEncodedLen
;
421 decoded
+= itemEncodedLen
;
422 items
[i
].size
= items
[i
].minSize
;
425 else if (items
[i
].optional
)
427 TRACE("skipping optional item %d\n", i
);
428 items
[i
].size
= items
[i
].minSize
;
432 TRACE("item %d: tag %02x doesn't match expected %02x\n",
433 i
, ptr
[0], items
[i
].tag
);
434 SetLastError(CRYPT_E_ASN1_BADTAG
);
439 else if (items
[i
].optional
)
441 TRACE("missing optional item %d, skipping\n", i
);
442 items
[i
].size
= items
[i
].minSize
;
446 TRACE("not enough bytes for item %d, failing\n", i
);
447 SetLastError(CRYPT_E_ASN1_CORRUPT
);
452 *cbDecoded
= decoded
;
453 TRACE("returning %d\n", ret
);
457 /* This decodes an arbitrary sequence into a contiguous block of memory
458 * (basically, a struct.) Each element being decoded is described by a struct
459 * AsnDecodeSequenceItem, see above.
460 * startingPointer is an optional pointer to the first place where dynamic
461 * data will be stored. If you know the starting offset, you may pass it
462 * here. Otherwise, pass NULL, and one will be inferred from the items.
464 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
465 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
466 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
467 DWORD
*pcbDecoded
, void *startingPointer
)
471 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
472 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
475 if (pbEncoded
[0] == ASN_SEQUENCE
)
479 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
481 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
482 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
483 BOOL indefinite
= FALSE
;
485 cbEncoded
-= 1 + lenBytes
;
486 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
491 else if (cbEncoded
< dataLen
)
493 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
495 SetLastError(CRYPT_E_ASN1_CORRUPT
);
500 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
501 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
502 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
504 if (cbDecoded
> cbEncoded
- 2)
506 /* Not enough space for 0 TLV */
507 SetLastError(CRYPT_E_ASN1_CORRUPT
);
510 else if (*(ptr
+ cbDecoded
) != 0 ||
511 *(ptr
+ cbDecoded
+ 1) != 0)
513 TRACE("expected 0 TLV\n");
514 SetLastError(CRYPT_E_ASN1_CORRUPT
);
521 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
523 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
525 SetLastError(CRYPT_E_ASN1_CORRUPT
);
530 DWORD i
, bytesNeeded
= 0, structSize
= 0;
532 for (i
= 0; i
< cItem
; i
++)
534 bytesNeeded
+= items
[i
].size
;
535 structSize
+= items
[i
].minSize
;
538 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
540 *pcbStructInfo
= bytesNeeded
;
541 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
542 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
546 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
547 pvStructInfo
= *(BYTE
**)pvStructInfo
;
549 nextData
= (BYTE
*)startingPointer
;
551 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
552 memset(pvStructInfo
, 0, structSize
);
553 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
554 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
556 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
557 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
564 SetLastError(CRYPT_E_ASN1_BADTAG
);
567 TRACE("returning %d (%08x)\n", ret
, GetLastError());
572 * The expected tag of the entire encoded array (usually a variant
573 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
574 * regardless of the tag seen.
576 * used to decode each item in the array
578 * is the minimum size of each decoded item
580 * indicates whether each item has a dynamic pointer
582 * indicates the offset within itemSize at which the pointer exists
584 struct AsnArrayDescriptor
587 InternalDecodeFunc decodeFunc
;
593 struct AsnArrayItemSize
599 /* Decodes an array of like types into a struct GenericArray.
600 * The layout and decoding of the array are described by a struct
601 * AsnArrayDescriptor.
603 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
604 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
605 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
606 DWORD
*pcbDecoded
, void *startingPointer
)
610 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
611 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
614 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
618 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
620 DWORD bytesNeeded
, cItems
= 0, decoded
;
621 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
622 /* There can be arbitrarily many items, but there is often only one.
624 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
626 decoded
= 1 + lenBytes
;
627 bytesNeeded
= sizeof(struct GenericArray
);
631 BOOL doneDecoding
= FALSE
;
633 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
635 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
642 SetLastError(CRYPT_E_ASN1_CORRUPT
);
649 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
653 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
655 /* Each item decoded may not tolerate extraneous bytes,
656 * so get the length of the next element if known.
658 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
659 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
661 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
662 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
664 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
668 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
669 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
674 if (itemSizes
!= &itemSize
)
675 itemSizes
= CryptMemRealloc(itemSizes
,
676 cItems
* sizeof(struct AsnArrayItemSize
));
681 cItems
* sizeof(struct AsnArrayItemSize
));
683 memcpy(itemSizes
, &itemSize
,
688 decoded
+= itemDecoded
;
689 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
690 itemSizes
[cItems
- 1].size
= size
;
703 *pcbDecoded
= decoded
;
705 *pcbStructInfo
= bytesNeeded
;
706 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
707 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
712 struct GenericArray
*array
;
714 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
715 pvStructInfo
= *(BYTE
**)pvStructInfo
;
716 array
= (struct GenericArray
*)pvStructInfo
;
717 array
->cItems
= cItems
;
719 array
->rgItems
= startingPointer
;
721 array
->rgItems
= (BYTE
*)array
+
722 sizeof(struct GenericArray
);
723 nextData
= array
->rgItems
+
724 array
->cItems
* arrayDesc
->itemSize
;
725 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
726 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
731 if (arrayDesc
->hasPointer
)
732 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
733 + arrayDesc
->pointerOffset
) = nextData
;
734 ret
= arrayDesc
->decodeFunc(ptr
,
735 itemSizes
[i
].encodedLen
,
736 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
737 array
->rgItems
+ i
* arrayDesc
->itemSize
,
738 &itemSizes
[i
].size
, &itemDecoded
);
741 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
745 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
746 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
749 if (itemSizes
!= &itemSize
)
750 CryptMemFree(itemSizes
);
755 SetLastError(CRYPT_E_ASN1_BADTAG
);
761 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
762 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
763 * to CRYPT_E_ASN1_CORRUPT.
764 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
767 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
768 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
773 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
775 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
776 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
778 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
779 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
782 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
784 *pcbStructInfo
= bytesNeeded
;
785 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
787 CRYPT_DER_BLOB
*blob
;
789 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
790 pvStructInfo
= *(BYTE
**)pvStructInfo
;
791 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
792 blob
->cbData
= 1 + lenBytes
+ dataLen
;
795 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
796 blob
->pbData
= (BYTE
*)pbEncoded
;
799 assert(blob
->pbData
);
800 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
805 SetLastError(CRYPT_E_ASN1_CORRUPT
);
813 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
814 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
815 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
820 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
821 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
823 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
826 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
827 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
829 if (ret
&& pvStructInfo
)
831 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
838 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
840 temp
= blob
->pbData
[i
];
841 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
842 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
846 TRACE("returning %d (%08x)\n", ret
, GetLastError());
850 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
851 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
852 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
856 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
857 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
861 struct AsnDecodeSequenceItem items
[] = {
862 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
863 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
864 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
865 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
866 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
867 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
868 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
869 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
870 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
871 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
874 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
875 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
876 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
877 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
878 pcbStructInfo
, NULL
, NULL
);
882 SetLastError(STATUS_ACCESS_VIOLATION
);
887 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
891 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
892 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
897 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
899 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
901 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
902 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
904 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
909 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
910 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
914 struct AsnDecodeSequenceItem items
[] = {
915 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
916 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
917 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
918 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
921 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
922 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
927 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
928 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
934 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
936 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
938 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
939 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
940 if (ret
&& pcbDecoded
)
941 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
946 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
947 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
948 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
951 struct AsnDecodeSequenceItem items
[] = {
952 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
953 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
954 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
955 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
956 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
957 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
958 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
959 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
960 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
961 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
963 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
964 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
966 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
967 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
969 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
970 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
971 FALSE
, TRUE
, offsetof(CERT_INFO
,
972 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
973 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
974 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
975 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
976 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
977 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
978 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
979 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
980 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
981 offsetof(CERT_INFO
, rgExtension
), 0 },
984 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
985 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
987 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
988 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
990 if (ret
&& pvStructInfo
)
994 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
995 info
= *(CERT_INFO
**)pvStructInfo
;
997 info
= (CERT_INFO
*)pvStructInfo
;
998 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
999 !info
->Subject
.cbData
)
1001 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1002 /* Don't need to deallocate, because it should have failed on the
1003 * first pass (and no memory was allocated.)
1009 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1013 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1014 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1015 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1019 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1020 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1026 /* Unless told not to, first try to decode it as a signed cert. */
1027 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1029 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1031 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1032 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1033 (BYTE
*)&signedCert
, &size
);
1037 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1038 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1039 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1040 pvStructInfo
, pcbStructInfo
);
1041 LocalFree(signedCert
);
1044 /* Failing that, try it as an unsigned cert */
1048 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1049 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1050 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1055 SetLastError(STATUS_ACCESS_VIOLATION
);
1059 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1063 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1064 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1067 struct AsnDecodeSequenceItem items
[] = {
1068 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1069 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1070 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1071 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1072 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1073 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1074 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1075 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1077 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
1079 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1082 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1083 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1084 entry
? entry
->SerialNumber
.pbData
: NULL
);
1085 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1087 WARN("empty CRL entry serial number\n");
1088 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1094 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1095 * been set prior to calling.
1097 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1098 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1101 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1102 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1103 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1104 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1106 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1107 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1109 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1110 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1111 entries
? entries
->rgItems
: NULL
);
1112 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1116 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1117 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1118 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1120 struct AsnDecodeSequenceItem items
[] = {
1121 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1122 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1123 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1124 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1125 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1126 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1127 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1129 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1130 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1131 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1132 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1133 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1134 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1135 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1136 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1137 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1138 offsetof(CRL_INFO
, rgExtension
), 0 },
1142 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1143 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1145 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1146 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1149 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1153 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1154 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1155 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1159 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1160 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1166 /* Unless told not to, first try to decode it as a signed crl. */
1167 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1169 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1171 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1172 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1173 (BYTE
*)&signedCrl
, &size
);
1177 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1178 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1179 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1180 pvStructInfo
, pcbStructInfo
);
1181 LocalFree(signedCrl
);
1184 /* Failing that, try it as an unsigned crl */
1188 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1189 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1190 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1195 SetLastError(STATUS_ACCESS_VIOLATION
);
1199 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1203 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1204 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1209 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1210 pvStructInfo
, *pcbStructInfo
);
1212 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1214 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1215 DWORD bytesNeeded
= sizeof(LPSTR
);
1219 /* The largest possible string for the first two components
1220 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1225 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1226 pbEncoded
[1 + lenBytes
] / 40,
1227 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1229 bytesNeeded
+= strlen(firstTwo
) + 1;
1230 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1231 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1233 /* large enough for ".4000000" */
1237 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1244 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1247 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1254 snprintf(str
, sizeof(str
), ".%d", val
);
1255 bytesNeeded
+= strlen(str
);
1260 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1262 *pcbStructInfo
= bytesNeeded
;
1263 else if (*pcbStructInfo
< bytesNeeded
)
1265 *pcbStructInfo
= bytesNeeded
;
1266 SetLastError(ERROR_MORE_DATA
);
1274 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1277 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1278 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1280 pszObjId
+= strlen(pszObjId
);
1281 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1282 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1286 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1295 sprintf(pszObjId
, ".%d", val
);
1296 pszObjId
+= strlen(pszObjId
);
1300 *(LPSTR
*)pvStructInfo
= NULL
;
1301 *pcbStructInfo
= bytesNeeded
;
1307 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1308 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1312 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1313 pvStructInfo
, *pcbStructInfo
);
1315 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1316 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1317 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1320 SetLastError(CRYPT_E_ASN1_BADTAG
);
1326 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1329 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1330 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1332 struct AsnDecodeSequenceItem items
[] = {
1333 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1334 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1335 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1336 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1337 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1338 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1339 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1340 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1343 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1345 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1349 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1350 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1351 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1352 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1354 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1355 debugstr_a(ext
->pszObjId
));
1356 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1360 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
1361 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1365 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1366 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1367 offsetof(CERT_EXTENSION
, pszObjId
) };
1368 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1370 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1371 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1373 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1374 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1375 exts
? exts
->rgExtension
: NULL
);
1379 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1380 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1381 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1387 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1388 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1389 if (ret
&& pvStructInfo
)
1391 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1392 pcbStructInfo
, *pcbStructInfo
);
1395 CERT_EXTENSIONS
*exts
;
1397 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1398 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1399 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1400 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1401 sizeof(CERT_EXTENSIONS
));
1402 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1403 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1404 pcbStructInfo
, NULL
);
1410 SetLastError(STATUS_ACCESS_VIOLATION
);
1417 /* Warning: this assumes the address of value->Value.pbData is already set, in
1418 * order to avoid overwriting memory. (In some cases, it may change it, if it
1419 * doesn't copy anything to memory.) Be sure to set it correctly!
1421 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1422 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1427 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1429 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1431 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1432 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1434 switch (pbEncoded
[0])
1436 case ASN_OCTETSTRING
:
1437 valueType
= CERT_RDN_OCTET_STRING
;
1438 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1439 bytesNeeded
+= dataLen
;
1441 case ASN_NUMERICSTRING
:
1442 valueType
= CERT_RDN_NUMERIC_STRING
;
1443 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1444 bytesNeeded
+= dataLen
;
1446 case ASN_PRINTABLESTRING
:
1447 valueType
= CERT_RDN_PRINTABLE_STRING
;
1448 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1449 bytesNeeded
+= dataLen
;
1452 valueType
= CERT_RDN_IA5_STRING
;
1453 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1454 bytesNeeded
+= dataLen
;
1457 valueType
= CERT_RDN_T61_STRING
;
1458 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1459 bytesNeeded
+= dataLen
;
1461 case ASN_VIDEOTEXSTRING
:
1462 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1463 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1464 bytesNeeded
+= dataLen
;
1466 case ASN_GRAPHICSTRING
:
1467 valueType
= CERT_RDN_GRAPHIC_STRING
;
1468 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1469 bytesNeeded
+= dataLen
;
1471 case ASN_VISIBLESTRING
:
1472 valueType
= CERT_RDN_VISIBLE_STRING
;
1473 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1474 bytesNeeded
+= dataLen
;
1476 case ASN_GENERALSTRING
:
1477 valueType
= CERT_RDN_GENERAL_STRING
;
1478 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1479 bytesNeeded
+= dataLen
;
1481 case ASN_UNIVERSALSTRING
:
1482 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1483 SetLastError(CRYPT_E_ASN1_BADTAG
);
1486 valueType
= CERT_RDN_BMP_STRING
;
1487 bytesNeeded
+= dataLen
;
1489 case ASN_UTF8STRING
:
1490 valueType
= CERT_RDN_UTF8_STRING
;
1491 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1492 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1495 SetLastError(CRYPT_E_ASN1_BADTAG
);
1500 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1502 *pcbStructInfo
= bytesNeeded
;
1503 else if (*pcbStructInfo
< bytesNeeded
)
1505 *pcbStructInfo
= bytesNeeded
;
1506 SetLastError(ERROR_MORE_DATA
);
1511 *pcbStructInfo
= bytesNeeded
;
1512 value
->dwValueType
= valueType
;
1517 assert(value
->Value
.pbData
);
1518 switch (pbEncoded
[0])
1520 case ASN_OCTETSTRING
:
1521 case ASN_NUMERICSTRING
:
1522 case ASN_PRINTABLESTRING
:
1525 case ASN_VIDEOTEXSTRING
:
1526 case ASN_GRAPHICSTRING
:
1527 case ASN_VISIBLESTRING
:
1528 case ASN_GENERALSTRING
:
1529 value
->Value
.cbData
= dataLen
;
1532 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1533 memcpy(value
->Value
.pbData
,
1534 pbEncoded
+ 1 + lenBytes
, dataLen
);
1536 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1542 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1544 value
->Value
.cbData
= dataLen
;
1545 for (i
= 0; i
< dataLen
/ 2; i
++)
1546 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1547 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1550 case ASN_UTF8STRING
:
1552 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1554 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1555 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1556 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1563 value
->Value
.cbData
= 0;
1564 value
->Value
.pbData
= NULL
;
1571 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1572 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1573 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1579 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1580 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1581 if (ret
&& pvStructInfo
)
1583 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1584 pcbStructInfo
, *pcbStructInfo
);
1587 CERT_NAME_VALUE
*value
;
1589 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1590 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1591 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1592 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1593 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1594 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1595 pcbStructInfo
, NULL
);
1601 SetLastError(STATUS_ACCESS_VIOLATION
);
1608 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1609 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1614 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1616 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1618 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1619 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1621 switch (pbEncoded
[0])
1623 case ASN_NUMERICSTRING
:
1624 valueType
= CERT_RDN_NUMERIC_STRING
;
1625 bytesNeeded
+= dataLen
* 2;
1627 case ASN_PRINTABLESTRING
:
1628 valueType
= CERT_RDN_PRINTABLE_STRING
;
1629 bytesNeeded
+= dataLen
* 2;
1632 valueType
= CERT_RDN_IA5_STRING
;
1633 bytesNeeded
+= dataLen
* 2;
1636 valueType
= CERT_RDN_T61_STRING
;
1637 bytesNeeded
+= dataLen
* 2;
1639 case ASN_VIDEOTEXSTRING
:
1640 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1641 bytesNeeded
+= dataLen
* 2;
1643 case ASN_GRAPHICSTRING
:
1644 valueType
= CERT_RDN_GRAPHIC_STRING
;
1645 bytesNeeded
+= dataLen
* 2;
1647 case ASN_VISIBLESTRING
:
1648 valueType
= CERT_RDN_VISIBLE_STRING
;
1649 bytesNeeded
+= dataLen
* 2;
1651 case ASN_GENERALSTRING
:
1652 valueType
= CERT_RDN_GENERAL_STRING
;
1653 bytesNeeded
+= dataLen
* 2;
1655 case ASN_UNIVERSALSTRING
:
1656 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1657 bytesNeeded
+= dataLen
/ 2;
1660 valueType
= CERT_RDN_BMP_STRING
;
1661 bytesNeeded
+= dataLen
;
1663 case ASN_UTF8STRING
:
1664 valueType
= CERT_RDN_UTF8_STRING
;
1665 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1666 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1669 SetLastError(CRYPT_E_ASN1_BADTAG
);
1674 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1676 *pcbStructInfo
= bytesNeeded
;
1677 else if (*pcbStructInfo
< bytesNeeded
)
1679 *pcbStructInfo
= bytesNeeded
;
1680 SetLastError(ERROR_MORE_DATA
);
1685 *pcbStructInfo
= bytesNeeded
;
1686 value
->dwValueType
= valueType
;
1690 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1692 assert(value
->Value
.pbData
);
1693 switch (pbEncoded
[0])
1695 case ASN_NUMERICSTRING
:
1696 case ASN_PRINTABLESTRING
:
1699 case ASN_VIDEOTEXSTRING
:
1700 case ASN_GRAPHICSTRING
:
1701 case ASN_VISIBLESTRING
:
1702 case ASN_GENERALSTRING
:
1703 value
->Value
.cbData
= dataLen
* 2;
1704 for (i
= 0; i
< dataLen
; i
++)
1705 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1707 case ASN_UNIVERSALSTRING
:
1708 value
->Value
.cbData
= dataLen
/ 2;
1709 for (i
= 0; i
< dataLen
/ 4; i
++)
1710 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1711 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1714 value
->Value
.cbData
= dataLen
;
1715 for (i
= 0; i
< dataLen
/ 2; i
++)
1716 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1717 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1719 case ASN_UTF8STRING
:
1720 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1721 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1722 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1728 value
->Value
.cbData
= 0;
1729 value
->Value
.pbData
= NULL
;
1736 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1737 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1738 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1744 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1745 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1746 if (ret
&& pvStructInfo
)
1748 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1749 pcbStructInfo
, *pcbStructInfo
);
1752 CERT_NAME_VALUE
*value
;
1754 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1755 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1756 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1757 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1758 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1759 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1760 pcbStructInfo
, NULL
);
1766 SetLastError(STATUS_ACCESS_VIOLATION
);
1773 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1774 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1777 struct AsnDecodeSequenceItem items
[] = {
1778 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1779 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1780 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1781 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1782 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1783 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1785 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1787 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1788 pvStructInfo
, *pcbStructInfo
);
1791 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1792 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1793 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1794 attr
? attr
->pszObjId
: NULL
);
1797 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1798 debugstr_a(attr
->pszObjId
));
1799 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1801 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1805 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1806 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1809 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1810 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1811 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1812 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1814 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1815 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1816 rdn
? rdn
->rgRDNAttr
: NULL
);
1820 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1821 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1822 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1828 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1829 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1830 offsetof(CERT_RDN
, rgRDNAttr
) };
1832 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1833 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1837 SetLastError(STATUS_ACCESS_VIOLATION
);
1844 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1845 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1849 struct AsnDecodeSequenceItem items
[] = {
1850 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1851 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1852 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1853 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1854 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1855 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1857 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1859 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1860 pvStructInfo
, *pcbStructInfo
);
1863 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1864 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1865 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1866 attr
? attr
->pszObjId
: NULL
);
1869 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1870 debugstr_a(attr
->pszObjId
));
1871 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1873 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1877 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1878 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1881 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1882 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1883 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1884 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1886 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1887 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1888 rdn
? rdn
->rgRDNAttr
: NULL
);
1892 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1893 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1894 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1900 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1901 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1902 offsetof(CERT_RDN
, rgRDNAttr
) };
1904 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1905 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1909 SetLastError(STATUS_ACCESS_VIOLATION
);
1916 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1919 BOOL ret
= TRUE
, done
= FALSE
;
1920 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
1922 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
1929 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
1932 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1934 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
1936 indefiniteNestingLevels
++;
1937 pbEncoded
+= 1 + lenBytes
;
1938 cbEncoded
-= 1 + lenBytes
;
1939 decoded
+= 1 + lenBytes
;
1940 TRACE("indefiniteNestingLevels = %d\n",
1941 indefiniteNestingLevels
);
1945 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
1946 indefiniteNestingLevels
)
1948 indefiniteNestingLevels
--;
1949 TRACE("indefiniteNestingLevels = %d\n",
1950 indefiniteNestingLevels
);
1952 pbEncoded
+= 1 + lenBytes
+ dataLen
;
1953 cbEncoded
-= 1 + lenBytes
+ dataLen
;
1954 decoded
+= 1 + lenBytes
+ dataLen
;
1955 if (!indefiniteNestingLevels
)
1959 } while (ret
&& !done
);
1960 /* If we haven't found all 0 TLVs, we haven't found the end */
1961 if (ret
&& indefiniteNestingLevels
)
1963 SetLastError(CRYPT_E_ASN1_EOD
);
1967 *pcbDecoded
= decoded
;
1968 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
1972 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
1973 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1977 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
1979 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1980 pvStructInfo
, *pcbStructInfo
);
1982 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
1984 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1985 bytesNeeded
+= encodedLen
;
1987 *pcbStructInfo
= bytesNeeded
;
1988 else if (*pcbStructInfo
< bytesNeeded
)
1990 SetLastError(ERROR_MORE_DATA
);
1991 *pcbStructInfo
= bytesNeeded
;
1996 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1998 *pcbStructInfo
= bytesNeeded
;
1999 blob
->cbData
= encodedLen
;
2002 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2003 blob
->pbData
= (LPBYTE
)pbEncoded
;
2006 assert(blob
->pbData
);
2007 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2011 blob
->pbData
= NULL
;
2014 *pcbDecoded
= encodedLen
;
2019 static BOOL
CRYPT_DecodeDERArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2020 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2023 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
2024 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2025 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
2027 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2028 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2030 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2031 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2032 array
? array
->rgItems
: NULL
);
2036 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2037 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2041 struct AsnDecodeSequenceItem items
[] = {
2042 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2043 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2044 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2045 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2046 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2047 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2049 PCRYPT_SMIME_CAPABILITY capability
= (PCRYPT_SMIME_CAPABILITY
)pvStructInfo
;
2051 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2052 pvStructInfo
, *pcbStructInfo
);
2054 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2055 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2056 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2057 TRACE("returning %d\n", ret
);
2061 static BOOL
CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE
*pbEncoded
,
2062 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2065 struct AsnArrayDescriptor arrayDesc
= { 0,
2066 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2067 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2068 PCRYPT_SMIME_CAPABILITIES capabilities
=
2069 (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2072 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2073 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2074 capabilities
? capabilities
->rgCapability
: NULL
);
2078 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2079 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2080 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2084 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2085 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2092 SetLastError(CRYPT_E_ASN1_EOD
);
2093 else if (pbEncoded
[0] != ASN_SEQUENCEOF
)
2094 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2095 else if ((ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2096 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2100 *pcbStructInfo
= bytesNeeded
;
2101 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2102 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2104 PCRYPT_SMIME_CAPABILITIES capabilities
;
2106 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2107 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2108 capabilities
= (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2109 capabilities
->rgCapability
=
2110 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2111 sizeof(CRYPT_SMIME_CAPABILITIES
));
2112 ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2113 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2114 &bytesNeeded
, NULL
);
2120 SetLastError(STATUS_ACCESS_VIOLATION
);
2123 TRACE("returning %d\n", ret
);
2127 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2128 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2132 struct AsnDecodeSequenceItem items
[] = {
2133 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2134 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2135 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2136 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2137 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
2138 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2140 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2142 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2143 pvStructInfo
, *pcbStructInfo
);
2145 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2146 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2147 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2148 TRACE("returning %d\n", ret
);
2152 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2153 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2154 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2158 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2159 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2165 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2166 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2170 *pcbStructInfo
= bytesNeeded
;
2171 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2172 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2174 PCRYPT_ATTRIBUTE attr
;
2176 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2177 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2178 attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2179 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2180 sizeof(CRYPT_ATTRIBUTE
));
2181 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2182 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2189 SetLastError(STATUS_ACCESS_VIOLATION
);
2192 TRACE("returning %d\n", ret
);
2196 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2197 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2200 struct AsnArrayDescriptor arrayDesc
= { 0,
2201 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2202 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2203 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2206 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2207 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2212 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2213 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2214 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2218 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2219 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2226 SetLastError(CRYPT_E_ASN1_EOD
);
2227 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2228 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2229 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2230 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2234 *pcbStructInfo
= bytesNeeded
;
2235 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2236 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2238 PCRYPT_ATTRIBUTES attrs
;
2240 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2241 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2242 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2243 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2244 sizeof(CRYPT_ATTRIBUTES
));
2245 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2246 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2247 &bytesNeeded
, NULL
);
2253 SetLastError(STATUS_ACCESS_VIOLATION
);
2256 TRACE("returning %d\n", ret
);
2260 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2261 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2263 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
2264 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
2266 struct AsnDecodeSequenceItem items
[] = {
2267 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2268 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2269 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2270 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2271 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2272 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2275 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2276 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2278 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2279 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2280 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2281 if (ret
&& pvStructInfo
)
2283 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2284 debugstr_a(algo
->pszObjId
));
2289 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2290 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2294 struct AsnDecodeSequenceItem items
[] = {
2295 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2296 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2297 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2298 Algorithm
.pszObjId
) },
2299 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2300 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2301 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2303 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2305 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2306 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2307 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2311 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2312 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2313 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2321 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2322 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2325 *pcbStructInfo
= bytesNeeded
;
2326 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2327 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2329 PCERT_PUBLIC_KEY_INFO info
;
2331 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2332 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2333 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2334 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2335 sizeof(CERT_PUBLIC_KEY_INFO
);
2336 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2337 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2338 &bytesNeeded
, NULL
);
2344 SetLastError(STATUS_ACCESS_VIOLATION
);
2351 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2352 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2358 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2361 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2363 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2366 if (pbEncoded
[1] > 1)
2368 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2375 *pcbStructInfo
= sizeof(BOOL
);
2378 else if (*pcbStructInfo
< sizeof(BOOL
))
2380 *pcbStructInfo
= sizeof(BOOL
);
2381 SetLastError(ERROR_MORE_DATA
);
2386 *pcbStructInfo
= sizeof(BOOL
);
2387 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2390 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2394 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2395 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2397 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2398 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2401 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2402 pvStructInfo
, *pcbStructInfo
);
2406 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2409 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2410 if (1 + lenBytes
> cbEncoded
)
2412 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2415 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2417 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2419 case 1: /* rfc822Name */
2420 case 2: /* dNSName */
2421 case 6: /* uniformResourceIdentifier */
2422 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2424 case 4: /* directoryName */
2425 case 7: /* iPAddress */
2426 bytesNeeded
+= dataLen
;
2428 case 8: /* registeredID */
2429 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2433 /* FIXME: ugly, shouldn't need to know internals of OID decode
2434 * function to use it.
2436 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2439 case 0: /* otherName */
2440 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2441 SetLastError(CRYPT_E_ASN1_BADTAG
);
2444 case 3: /* x400Address, unimplemented */
2445 case 5: /* ediPartyName, unimplemented */
2446 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2447 SetLastError(CRYPT_E_ASN1_BADTAG
);
2451 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2452 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2458 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2460 *pcbStructInfo
= bytesNeeded
;
2461 else if (*pcbStructInfo
< bytesNeeded
)
2463 *pcbStructInfo
= bytesNeeded
;
2464 SetLastError(ERROR_MORE_DATA
);
2469 *pcbStructInfo
= bytesNeeded
;
2470 /* MS used values one greater than the asn1 ones.. sigh */
2471 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2472 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2474 case 1: /* rfc822Name */
2475 case 2: /* dNSName */
2476 case 6: /* uniformResourceIdentifier */
2480 for (i
= 0; i
< dataLen
; i
++)
2481 entry
->u
.pwszURL
[i
] =
2482 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2483 entry
->u
.pwszURL
[i
] = 0;
2484 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2485 debugstr_w(entry
->u
.pwszURL
));
2488 case 4: /* directoryName */
2489 entry
->dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
2490 /* The data are memory-equivalent with the IPAddress case,
2493 case 7: /* iPAddress */
2494 /* The next data pointer is in the pwszURL spot, that is,
2495 * the first 4 bytes. Need to move it to the next spot.
2497 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2498 entry
->u
.IPAddress
.cbData
= dataLen
;
2499 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2502 case 8: /* registeredID */
2503 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2504 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2513 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
2514 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2518 struct AsnArrayDescriptor arrayDesc
= { 0,
2519 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2520 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2521 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2523 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2524 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2527 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2528 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2529 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2530 info
? info
->rgAltEntry
: NULL
);
2534 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2535 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
2536 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2541 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2542 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2544 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2547 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
2548 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
2550 if (ret
&& pvStructInfo
)
2552 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2559 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
2561 temp
= blob
->pbData
[i
];
2562 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
2563 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
2567 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2571 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2572 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2573 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2579 struct AsnDecodeSequenceItem items
[] = {
2580 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2581 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2582 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2583 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2584 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2585 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2586 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2587 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2588 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2589 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2590 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2593 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2594 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2595 pcbStructInfo
, NULL
, NULL
);
2599 SetLastError(STATUS_ACCESS_VIOLATION
);
2606 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2607 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2608 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2614 struct AsnDecodeSequenceItem items
[] = {
2615 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2616 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2617 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2618 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2619 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2620 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2621 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2622 AuthorityCertIssuer
.rgAltEntry
), 0 },
2623 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2624 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2625 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2626 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2627 AuthorityCertSerialNumber
.pbData
), 0 },
2630 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2631 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2632 pcbStructInfo
, NULL
, NULL
);
2636 SetLastError(STATUS_ACCESS_VIOLATION
);
2643 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2644 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2649 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2650 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2652 /* The caller has already checked the tag, no need to check it again.
2653 * Check the outer length is valid:
2655 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
2657 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2660 pbEncoded
+= 1 + lenBytes
;
2661 cbEncoded
-= 1 + lenBytes
;
2662 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2663 cbEncoded
-= 2; /* space for 0 TLV */
2664 /* Check the inner length is valid: */
2665 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
2669 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
2670 pvStructInfo
, pcbStructInfo
, &decodedLen
);
2671 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2673 if (*(pbEncoded
+ decodedLen
) != 0 ||
2674 *(pbEncoded
+ decodedLen
+ 1) != 0)
2676 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2677 *(pbEncoded
+ decodedLen
),
2678 *(pbEncoded
+ decodedLen
+ 1));
2679 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2685 if (ret
&& pcbDecoded
)
2687 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
2688 TRACE("decoded %d bytes\n", *pcbDecoded
);
2695 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
2696 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2699 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2700 struct AsnDecodeSequenceItem items
[] = {
2701 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2702 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2703 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2704 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2705 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2706 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2707 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2711 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2712 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2714 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2715 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2716 pcbDecoded
, info
? info
->pszObjId
: NULL
);
2720 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2721 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2722 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2726 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2727 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2731 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
2732 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
2733 if (ret
&& pvStructInfo
)
2735 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2736 pcbStructInfo
, *pcbStructInfo
);
2739 CRYPT_CONTENT_INFO
*info
;
2741 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2742 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2743 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2744 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2745 sizeof(CRYPT_CONTENT_INFO
));
2746 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
2747 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2748 pcbStructInfo
, NULL
);
2754 SetLastError(STATUS_ACCESS_VIOLATION
);
2760 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2761 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2762 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2765 struct AsnDecodeSequenceItem items
[] = {
2766 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
2767 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2768 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2769 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2770 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2772 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2773 CRYPT_AsnDecodePKCSContentInfoInternal
,
2774 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2775 ContentInfo
.pszObjId
), 0 },
2776 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2777 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2778 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2781 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2782 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
2787 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2788 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2789 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2793 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2794 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2800 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2801 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2804 *pcbStructInfo
= bytesNeeded
;
2805 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2806 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2808 CERT_ALT_NAME_INFO
*name
;
2810 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2811 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2812 name
= (CERT_ALT_NAME_INFO
*)pvStructInfo
;
2813 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
2814 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
2815 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2816 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2817 &bytesNeeded
, NULL
);
2823 SetLastError(STATUS_ACCESS_VIOLATION
);
2830 struct PATH_LEN_CONSTRAINT
2832 BOOL fPathLenConstraint
;
2833 DWORD dwPathLenConstraint
;
2836 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
2837 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2841 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
2843 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2844 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2848 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
2850 *pcbStructInfo
= bytesNeeded
;
2852 else if (*pcbStructInfo
< bytesNeeded
)
2854 SetLastError(ERROR_MORE_DATA
);
2855 *pcbStructInfo
= bytesNeeded
;
2860 struct PATH_LEN_CONSTRAINT
*constraint
=
2861 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2863 *pcbStructInfo
= bytesNeeded
;
2864 size
= sizeof(constraint
->dwPathLenConstraint
);
2865 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
2866 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
2868 constraint
->fPathLenConstraint
= TRUE
;
2869 TRACE("got an int, dwPathLenConstraint is %d\n",
2870 constraint
->dwPathLenConstraint
);
2872 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2876 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
2877 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2881 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2882 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2883 offsetof(CERT_NAME_BLOB
, pbData
) };
2884 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2886 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2887 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2889 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2890 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2891 entries
? entries
->rgItems
: NULL
);
2892 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2896 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2897 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2898 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2904 struct AsnDecodeSequenceItem items
[] = {
2905 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2906 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2907 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2908 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2909 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2910 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2911 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2912 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2913 sizeof(struct GenericArray
), TRUE
, TRUE
,
2914 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2917 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2918 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2919 pcbStructInfo
, NULL
, NULL
);
2923 SetLastError(STATUS_ACCESS_VIOLATION
);
2930 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2931 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2932 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2938 struct AsnDecodeSequenceItem items
[] = {
2939 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2940 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2941 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2942 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2943 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2946 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2947 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2948 pcbStructInfo
, NULL
, NULL
);
2952 SetLastError(STATUS_ACCESS_VIOLATION
);
2959 #define RSA1_MAGIC 0x31415352
2961 struct DECODED_RSA_PUB_KEY
2964 CRYPT_INTEGER_BLOB modulus
;
2967 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2968 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2969 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2975 struct AsnDecodeSequenceItem items
[] = {
2976 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2977 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2978 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2980 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2981 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2983 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2986 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2987 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
2991 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2992 decodedKey
->modulus
.cbData
;
2996 *pcbStructInfo
= bytesNeeded
;
2999 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3000 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3003 RSAPUBKEY
*rsaPubKey
;
3005 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3006 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3007 hdr
= (BLOBHEADER
*)pvStructInfo
;
3008 hdr
->bType
= PUBLICKEYBLOB
;
3009 hdr
->bVersion
= CUR_BLOB_VERSION
;
3011 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3012 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3013 sizeof(BLOBHEADER
));
3014 rsaPubKey
->magic
= RSA1_MAGIC
;
3015 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3016 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3017 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3018 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3019 decodedKey
->modulus
.cbData
);
3021 LocalFree(decodedKey
);
3026 SetLastError(STATUS_ACCESS_VIOLATION
);
3033 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3034 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3038 DWORD bytesNeeded
, dataLen
;
3040 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3041 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3043 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3045 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3047 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3048 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3050 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3052 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3054 *pcbStructInfo
= bytesNeeded
;
3055 else if (*pcbStructInfo
< bytesNeeded
)
3057 SetLastError(ERROR_MORE_DATA
);
3058 *pcbStructInfo
= bytesNeeded
;
3063 CRYPT_DATA_BLOB
*blob
;
3065 *pcbStructInfo
= bytesNeeded
;
3066 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3067 blob
->cbData
= dataLen
;
3068 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3069 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3072 assert(blob
->pbData
);
3074 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3082 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3083 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3084 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3088 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3089 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3097 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3100 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3102 SetLastError(CRYPT_E_ASN1_BADTAG
);
3105 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3106 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3109 *pcbStructInfo
= bytesNeeded
;
3110 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3111 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3113 CRYPT_DATA_BLOB
*blob
;
3115 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3116 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3117 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3118 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3119 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3120 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3121 &bytesNeeded
, NULL
);
3127 SetLastError(STATUS_ACCESS_VIOLATION
);
3134 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3135 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3139 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3140 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3142 if (pbEncoded
[0] == ASN_BITSTRING
)
3144 DWORD bytesNeeded
, dataLen
;
3145 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3147 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3149 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3150 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3152 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3154 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3156 *pcbStructInfo
= bytesNeeded
;
3157 else if (*pcbStructInfo
< bytesNeeded
)
3159 *pcbStructInfo
= bytesNeeded
;
3160 SetLastError(ERROR_MORE_DATA
);
3165 CRYPT_BIT_BLOB
*blob
;
3167 *pcbStructInfo
= bytesNeeded
;
3168 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3169 blob
->cbData
= dataLen
- 1;
3170 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3171 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3173 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3177 assert(blob
->pbData
);
3180 BYTE mask
= 0xff << blob
->cUnusedBits
;
3182 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3184 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3192 SetLastError(CRYPT_E_ASN1_BADTAG
);
3195 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3199 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3200 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3201 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3205 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3206 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3212 if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3213 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3216 *pcbStructInfo
= bytesNeeded
;
3217 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3218 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3220 CRYPT_BIT_BLOB
*blob
;
3222 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3223 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3224 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3225 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3226 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3227 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3228 &bytesNeeded
, NULL
);
3234 SetLastError(STATUS_ACCESS_VIOLATION
);
3238 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3242 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3243 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3244 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3247 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3248 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3249 DWORD size
= sizeof(buf
);
3251 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3252 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
3257 *pcbStructInfo
= sizeof(int);
3258 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3262 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3264 /* initialize to a negative value to sign-extend */
3269 for (i
= 0; i
< blob
->cbData
; i
++)
3272 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3274 memcpy(pvStructInfo
, &val
, sizeof(int));
3277 else if (GetLastError() == ERROR_MORE_DATA
)
3278 SetLastError(CRYPT_E_ASN1_LARGE
);
3282 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3283 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3284 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3294 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3297 else if (pbEncoded
[0] != ASN_INTEGER
)
3299 SetLastError(CRYPT_E_ASN1_BADTAG
);
3303 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3304 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3308 *pcbStructInfo
= bytesNeeded
;
3309 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3310 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3312 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3313 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3314 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3315 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3316 &bytesNeeded
, NULL
);
3322 SetLastError(STATUS_ACCESS_VIOLATION
);
3329 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
3330 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3334 DWORD bytesNeeded
, dataLen
;
3336 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3338 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3340 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3342 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3344 *pcbStructInfo
= bytesNeeded
;
3345 else if (*pcbStructInfo
< bytesNeeded
)
3347 *pcbStructInfo
= bytesNeeded
;
3348 SetLastError(ERROR_MORE_DATA
);
3353 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3355 *pcbStructInfo
= bytesNeeded
;
3356 blob
->cbData
= dataLen
;
3357 assert(blob
->pbData
);
3362 for (i
= 0; i
< blob
->cbData
; i
++)
3364 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3373 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3374 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3375 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3383 if (pbEncoded
[0] != ASN_INTEGER
)
3385 SetLastError(CRYPT_E_ASN1_BADTAG
);
3389 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3390 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3394 *pcbStructInfo
= bytesNeeded
;
3395 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3396 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3398 CRYPT_INTEGER_BLOB
*blob
;
3400 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3401 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3402 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3403 blob
->pbData
= (BYTE
*)pvStructInfo
+
3404 sizeof(CRYPT_INTEGER_BLOB
);
3405 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3406 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3407 &bytesNeeded
, NULL
);
3413 SetLastError(STATUS_ACCESS_VIOLATION
);
3420 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
3421 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3426 if (pbEncoded
[0] == ASN_INTEGER
)
3428 DWORD bytesNeeded
, dataLen
;
3430 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3432 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3435 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3436 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3438 *pcbStructInfo
= bytesNeeded
;
3439 else if (*pcbStructInfo
< bytesNeeded
)
3441 *pcbStructInfo
= bytesNeeded
;
3442 SetLastError(ERROR_MORE_DATA
);
3447 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3449 *pcbStructInfo
= bytesNeeded
;
3450 blob
->cbData
= dataLen
;
3451 assert(blob
->pbData
);
3452 /* remove leading zero byte if it exists */
3453 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3462 for (i
= 0; i
< blob
->cbData
; i
++)
3464 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3473 SetLastError(CRYPT_E_ASN1_BADTAG
);
3479 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3480 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3481 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3489 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
3490 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3493 *pcbStructInfo
= bytesNeeded
;
3494 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3495 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3497 CRYPT_INTEGER_BLOB
*blob
;
3499 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3500 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3501 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3502 blob
->pbData
= (BYTE
*)pvStructInfo
+
3503 sizeof(CRYPT_INTEGER_BLOB
);
3504 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
3505 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3506 &bytesNeeded
, NULL
);
3512 SetLastError(STATUS_ACCESS_VIOLATION
);
3519 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3520 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3521 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3527 *pcbStructInfo
= sizeof(int);
3532 if (pbEncoded
[0] == ASN_ENUMERATED
)
3534 unsigned int val
= 0, i
;
3538 SetLastError(CRYPT_E_ASN1_EOD
);
3541 else if (pbEncoded
[1] == 0)
3543 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3548 /* A little strange looking, but we have to accept a sign byte:
3549 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3550 * assuming a small length is okay here, it has to be in short
3553 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3555 SetLastError(CRYPT_E_ASN1_LARGE
);
3558 for (i
= 0; i
< pbEncoded
[1]; i
++)
3561 val
|= pbEncoded
[2 + i
];
3563 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3564 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3566 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3567 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3568 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3574 SetLastError(CRYPT_E_ASN1_BADTAG
);
3580 SetLastError(STATUS_ACCESS_VIOLATION
);
3587 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3590 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3595 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3597 if (!isdigit(*(pbEncoded))) \
3599 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3605 (word) += *(pbEncoded)++ - '0'; \
3610 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3611 SYSTEMTIME
*sysTime
)
3615 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3617 WORD hours
, minutes
= 0;
3618 BYTE sign
= *pbEncoded
++;
3621 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3622 if (ret
&& hours
>= 24)
3624 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3629 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3630 if (ret
&& minutes
>= 60)
3632 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3640 sysTime
->wHour
+= hours
;
3641 sysTime
->wMinute
+= minutes
;
3645 if (hours
> sysTime
->wHour
)
3648 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3651 sysTime
->wHour
-= hours
;
3652 if (minutes
> sysTime
->wMinute
)
3655 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3658 sysTime
->wMinute
-= minutes
;
3665 #define MIN_ENCODED_TIME_LENGTH 10
3667 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
3668 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3673 if (pbEncoded
[0] == ASN_UTCTIME
)
3676 SetLastError(CRYPT_E_ASN1_EOD
);
3677 else if (pbEncoded
[1] > 0x7f)
3679 /* long-form date strings really can't be valid */
3680 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3684 SYSTEMTIME sysTime
= { 0 };
3685 BYTE len
= pbEncoded
[1];
3687 if (len
< MIN_ENCODED_TIME_LENGTH
)
3688 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3693 *pcbDecoded
= 2 + len
;
3695 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3696 if (sysTime
.wYear
>= 50)
3697 sysTime
.wYear
+= 1900;
3699 sysTime
.wYear
+= 2000;
3700 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3701 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3702 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3703 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3706 if (len
>= 2 && isdigit(*pbEncoded
) &&
3707 isdigit(*(pbEncoded
+ 1)))
3708 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3710 else if (isdigit(*pbEncoded
))
3711 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3714 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3720 *pcbStructInfo
= sizeof(FILETIME
);
3721 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3723 ret
= SystemTimeToFileTime(&sysTime
,
3724 (FILETIME
*)pvStructInfo
);
3730 SetLastError(CRYPT_E_ASN1_BADTAG
);
3734 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3735 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3736 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3744 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3745 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3749 *pcbStructInfo
= bytesNeeded
;
3750 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3751 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3753 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3754 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3755 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3756 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3757 &bytesNeeded
, NULL
);
3763 SetLastError(STATUS_ACCESS_VIOLATION
);
3769 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
3770 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3775 if (pbEncoded
[0] == ASN_GENERALTIME
)
3778 SetLastError(CRYPT_E_ASN1_EOD
);
3779 else if (pbEncoded
[1] > 0x7f)
3781 /* long-form date strings really can't be valid */
3782 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3786 BYTE len
= pbEncoded
[1];
3788 if (len
< MIN_ENCODED_TIME_LENGTH
)
3789 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3792 SYSTEMTIME sysTime
= { 0 };
3796 *pcbDecoded
= 2 + len
;
3798 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3799 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3800 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3801 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3804 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3807 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3809 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3816 /* workaround macro weirdness */
3817 digits
= min(len
, 3);
3818 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3819 sysTime
.wMilliseconds
);
3822 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3828 *pcbStructInfo
= sizeof(FILETIME
);
3829 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3831 ret
= SystemTimeToFileTime(&sysTime
,
3832 (FILETIME
*)pvStructInfo
);
3838 SetLastError(CRYPT_E_ASN1_BADTAG
);
3842 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
3843 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3847 InternalDecodeFunc decode
= NULL
;
3849 if (pbEncoded
[0] == ASN_UTCTIME
)
3850 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
3851 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3852 decode
= CRYPT_AsnDecodeGeneralizedTime
;
3854 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
3855 pcbStructInfo
, pcbDecoded
);
3858 SetLastError(CRYPT_E_ASN1_BADTAG
);
3864 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3865 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3866 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3874 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
3875 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3879 *pcbStructInfo
= bytesNeeded
;
3880 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3881 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3883 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3884 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3885 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
3886 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3887 &bytesNeeded
, NULL
);
3893 SetLastError(STATUS_ACCESS_VIOLATION
);
3900 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3901 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3902 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3908 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3910 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3912 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3917 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3918 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3920 ptr
= pbEncoded
+ 1 + lenBytes
;
3921 remainingLen
= dataLen
;
3922 while (ret
&& remainingLen
)
3926 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3929 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3931 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3932 ptr
+= 1 + nextLenBytes
+ nextLen
;
3933 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3934 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3935 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3941 CRYPT_SEQUENCE_OF_ANY
*seq
;
3946 *pcbStructInfo
= bytesNeeded
;
3947 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3948 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3950 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3951 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3952 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3953 seq
->cValue
= cValue
;
3954 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3956 nextPtr
= (BYTE
*)seq
->rgValue
+
3957 cValue
* sizeof(CRYPT_DER_BLOB
);
3958 ptr
= pbEncoded
+ 1 + lenBytes
;
3959 remainingLen
= dataLen
;
3961 while (ret
&& remainingLen
)
3965 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3968 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3970 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3972 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3973 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3976 seq
->rgValue
[i
].pbData
= nextPtr
;
3977 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3979 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3981 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3982 ptr
+= 1 + nextLenBytes
+ nextLen
;
3992 SetLastError(CRYPT_E_ASN1_BADTAG
);
3998 SetLastError(STATUS_ACCESS_VIOLATION
);
4005 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4006 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4011 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4013 DWORD bytesNeeded
, dataLen
;
4015 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4017 struct AsnArrayDescriptor arrayDesc
= {
4018 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
4019 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4020 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4021 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4026 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4027 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4028 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
4029 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4030 * as the sizeof(struct GenericArray), so don't include it in the
4031 * total bytes needed.
4033 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4034 sizeof(CERT_ALT_NAME_INFO
);
4037 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4039 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4041 *pcbStructInfo
= bytesNeeded
;
4042 else if (*pcbStructInfo
< bytesNeeded
)
4044 *pcbStructInfo
= bytesNeeded
;
4045 SetLastError(ERROR_MORE_DATA
);
4050 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
4052 *pcbStructInfo
= bytesNeeded
;
4055 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4056 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4057 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4058 0, NULL
, &name
->u
.FullName
, &nameLen
, NULL
,
4059 name
->u
.FullName
.rgAltEntry
);
4062 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4068 SetLastError(CRYPT_E_ASN1_BADTAG
);
4074 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4075 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4077 struct AsnDecodeSequenceItem items
[] = {
4078 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4079 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4080 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4081 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4082 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4083 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4084 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4085 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4086 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4087 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4091 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4092 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4097 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4098 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4099 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4103 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4104 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4108 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4109 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4110 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4112 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4113 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4117 SetLastError(STATUS_ACCESS_VIOLATION
);
4124 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
4125 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4126 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4130 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4131 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4135 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4136 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
4138 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4139 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4143 SetLastError(STATUS_ACCESS_VIOLATION
);
4150 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4151 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4152 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4156 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4157 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4161 struct AsnDecodeSequenceItem items
[] = {
4162 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4163 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4164 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4165 offsetof(CRL_ISSUING_DIST_POINT
,
4166 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4167 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4168 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4170 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4171 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4173 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4174 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4175 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4176 OnlySomeReasonFlags
.pbData
), 0 },
4177 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4178 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4181 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4182 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4183 pcbStructInfo
, NULL
, NULL
);
4187 SetLastError(STATUS_ACCESS_VIOLATION
);
4194 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
4195 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4200 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4201 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4205 SetLastError(CRYPT_E_ASN1_EOD
);
4208 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
4210 SetLastError(CRYPT_E_ASN1_BADTAG
);
4213 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4214 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
4215 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
4217 if (ret
&& pvStructInfo
)
4218 *(BOOL
*)pvStructInfo
= TRUE
;
4219 TRACE("returning %d\n", ret
);
4223 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
4224 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4228 struct AsnDecodeSequenceItem items
[] = {
4229 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
4230 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
4231 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
4232 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
4233 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
4234 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
4235 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
4238 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)pvStructInfo
;
4240 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4241 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4243 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4244 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4245 pcbDecoded
, subtree
? (BYTE
*)subtree
->Base
.u
.pwszURL
: NULL
);
4248 TRACE("%d\n", *pcbDecoded
);
4249 if (*pcbDecoded
< cbEncoded
)
4250 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
4251 *(pbEncoded
+ *pcbDecoded
+ 1));
4253 TRACE("returning %d\n", ret
);
4257 static BOOL
CRYPT_AsnDecodeSubtreeArray(const BYTE
*pbEncoded
,
4258 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4262 struct AsnArrayDescriptor arrayDesc
= { 0,
4263 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4264 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4265 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4267 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4268 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4270 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4271 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4272 array
? array
->rgItems
: NULL
);
4277 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
4278 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4279 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4283 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4284 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4288 struct AsnDecodeSequenceItem items
[] = {
4289 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4290 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
4291 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4292 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
4293 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
4294 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4295 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4296 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
4299 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4300 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4301 pcbStructInfo
, NULL
, NULL
);
4305 SetLastError(STATUS_ACCESS_VIOLATION
);
4311 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
4312 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4316 struct AsnDecodeSequenceItem items
[] = {
4317 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4318 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4320 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4321 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4322 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4324 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
4325 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
4327 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4328 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4330 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4331 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4332 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4333 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4335 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4338 TRACE("returning %d\n", ret
);
4342 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4343 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4346 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4347 struct AsnDecodeSequenceItem items
[] = {
4348 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4349 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4350 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4351 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4352 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4353 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4354 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4355 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4356 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4357 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4358 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4359 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4360 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4361 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4362 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4363 HashEncryptionAlgorithm
.pszObjId
), 0 },
4364 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4365 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4366 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4367 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4368 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4369 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4370 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4374 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4375 pvStructInfo
, *pcbStructInfo
);
4377 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4378 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4379 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
4383 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4384 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4385 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4389 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4390 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4394 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4395 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4396 if (ret
&& pvStructInfo
)
4398 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4399 pcbStructInfo
, *pcbStructInfo
);
4402 CMSG_SIGNER_INFO
*info
;
4404 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4405 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4406 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4407 info
->Issuer
.pbData
= ((BYTE
*)info
+
4408 sizeof(CMSG_SIGNER_INFO
));
4409 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
4410 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4411 pcbStructInfo
, NULL
);
4417 SetLastError(STATUS_ACCESS_VIOLATION
);
4420 TRACE("returning %d\n", ret
);
4424 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
4425 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4428 CERT_ID
*id
= (CERT_ID
*)pvStructInfo
;
4431 if (*pbEncoded
== ASN_SEQUENCEOF
)
4433 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
4434 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
4438 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
4439 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
4440 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4441 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
4443 *pcbStructInfo
= sizeof(CERT_ID
);
4446 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
4448 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
4449 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
4453 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
4454 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
4455 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4456 sizeof(CRYPT_DATA_BLOB
);
4458 *pcbStructInfo
= sizeof(CERT_ID
);
4462 SetLastError(CRYPT_E_ASN1_BADTAG
);
4466 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
4467 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4470 CMSG_CMS_SIGNER_INFO
*info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4471 struct AsnDecodeSequenceItem items
[] = {
4472 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
4473 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4474 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
4475 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
4476 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
4477 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
4478 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4479 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4480 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4481 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
4482 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4483 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4484 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
4485 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4486 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
4487 HashEncryptionAlgorithm
.pszObjId
), 0 },
4488 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
4489 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4490 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4491 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4492 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
4493 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4494 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4498 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4499 pvStructInfo
, *pcbStructInfo
);
4501 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4502 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4503 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
4507 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
4508 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4509 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4513 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4514 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4518 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
4519 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4520 if (ret
&& pvStructInfo
)
4522 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4523 pcbStructInfo
, *pcbStructInfo
);
4526 CMSG_CMS_SIGNER_INFO
*info
;
4528 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4529 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4530 info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4531 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
4532 sizeof(CMSG_CMS_SIGNER_INFO
));
4533 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
4534 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4535 pcbStructInfo
, NULL
);
4541 SetLastError(STATUS_ACCESS_VIOLATION
);
4544 TRACE("returning %d\n", ret
);
4548 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4549 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4552 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
4553 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
4554 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
4555 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4557 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4558 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4560 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4561 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4562 array
? array
->rgItems
: NULL
);
4566 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4567 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
4568 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
4571 struct AsnDecodeSequenceItem items
[] = {
4572 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
4573 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4574 /* Placeholder for the hash algorithms - redundant with those in the
4575 * signers, so just ignore them.
4577 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
4578 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
4579 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
4580 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
4581 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4582 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
4583 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4584 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
4585 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4586 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
4587 sizeof(struct GenericArray
), TRUE
, TRUE
,
4588 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
4589 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
4590 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4591 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
4594 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4595 pDecodePara
, signedInfo
, *pcbSignedInfo
);
4597 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4598 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
4600 TRACE("returning %d\n", ret
);
4604 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
4605 LPCSTR lpszStructType
)
4607 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4609 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
4610 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
4612 SetLastError(ERROR_FILE_NOT_FOUND
);
4615 if (!HIWORD(lpszStructType
))
4617 switch (LOWORD(lpszStructType
))
4619 case LOWORD(X509_CERT
):
4620 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
4622 case LOWORD(X509_CERT_TO_BE_SIGNED
):
4623 decodeFunc
= CRYPT_AsnDecodeCert
;
4625 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
4626 decodeFunc
= CRYPT_AsnDecodeCRL
;
4628 case LOWORD(X509_EXTENSIONS
):
4629 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4631 case LOWORD(X509_NAME_VALUE
):
4632 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4634 case LOWORD(X509_NAME
):
4635 decodeFunc
= CRYPT_AsnDecodeName
;
4637 case LOWORD(X509_PUBLIC_KEY_INFO
):
4638 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4640 case LOWORD(X509_AUTHORITY_KEY_ID
):
4641 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4643 case LOWORD(X509_ALTERNATE_NAME
):
4644 decodeFunc
= CRYPT_AsnDecodeAltName
;
4646 case LOWORD(X509_BASIC_CONSTRAINTS
):
4647 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4649 case LOWORD(X509_BASIC_CONSTRAINTS2
):
4650 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4652 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
4653 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4655 case LOWORD(X509_UNICODE_NAME
):
4656 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4658 case LOWORD(PKCS_ATTRIBUTE
):
4659 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4661 case LOWORD(X509_UNICODE_NAME_VALUE
):
4662 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4664 case LOWORD(X509_OCTET_STRING
):
4665 decodeFunc
= CRYPT_AsnDecodeOctets
;
4667 case LOWORD(X509_BITS
):
4668 case LOWORD(X509_KEY_USAGE
):
4669 decodeFunc
= CRYPT_AsnDecodeBits
;
4671 case LOWORD(X509_INTEGER
):
4672 decodeFunc
= CRYPT_AsnDecodeInt
;
4674 case LOWORD(X509_MULTI_BYTE_INTEGER
):
4675 decodeFunc
= CRYPT_AsnDecodeInteger
;
4677 case LOWORD(X509_MULTI_BYTE_UINT
):
4678 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4680 case LOWORD(X509_ENUMERATED
):
4681 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4683 case LOWORD(X509_CHOICE_OF_TIME
):
4684 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4686 case LOWORD(X509_AUTHORITY_KEY_ID2
):
4687 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4689 case LOWORD(PKCS_CONTENT_INFO
):
4690 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4692 case LOWORD(X509_SEQUENCE_OF_ANY
):
4693 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4695 case LOWORD(PKCS_UTC_TIME
):
4696 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4698 case LOWORD(X509_CRL_DIST_POINTS
):
4699 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4701 case LOWORD(X509_ENHANCED_KEY_USAGE
):
4702 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4704 case LOWORD(PKCS_SMIME_CAPABILITIES
):
4705 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4707 case LOWORD(PKCS_ATTRIBUTES
):
4708 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4710 case LOWORD(X509_ISSUING_DIST_POINT
):
4711 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4713 case LOWORD(X509_NAME_CONSTRAINTS
):
4714 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4716 case LOWORD(PKCS7_SIGNER_INFO
):
4717 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4719 case LOWORD(CMS_SIGNER_INFO
):
4720 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
4724 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4725 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4726 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4727 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4728 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
4729 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4730 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4731 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4732 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4733 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4734 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4735 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4736 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4737 decodeFunc
= CRYPT_AsnDecodeBits
;
4738 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4739 decodeFunc
= CRYPT_AsnDecodeOctets
;
4740 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4741 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4742 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4743 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4744 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4745 decodeFunc
= CRYPT_AsnDecodeAltName
;
4746 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4747 decodeFunc
= CRYPT_AsnDecodeAltName
;
4748 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4749 decodeFunc
= CRYPT_AsnDecodeAltName
;
4750 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4751 decodeFunc
= CRYPT_AsnDecodeAltName
;
4752 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4753 decodeFunc
= CRYPT_AsnDecodeAltName
;
4754 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4755 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4756 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4757 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4758 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4759 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4760 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
4761 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4765 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
4766 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4768 static HCRYPTOIDFUNCSET set
= NULL
;
4769 CryptDecodeObjectFunc decodeFunc
= NULL
;
4772 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
4773 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4774 (void **)&decodeFunc
, hFunc
);
4778 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
4779 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4781 static HCRYPTOIDFUNCSET set
= NULL
;
4782 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4785 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4786 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4787 (void **)&decodeFunc
, hFunc
);
4791 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4792 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
4793 DWORD
*pcbStructInfo
)
4796 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
4797 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
4798 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4800 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
4801 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
4802 pvStructInfo
, pcbStructInfo
);
4804 if (!pvStructInfo
&& !pcbStructInfo
)
4806 SetLastError(ERROR_INVALID_PARAMETER
);
4811 SetLastError(CRYPT_E_ASN1_EOD
);
4814 if (cbEncoded
> MAX_ENCODED_LEN
)
4816 SetLastError(CRYPT_E_ASN1_LARGE
);
4820 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
4823 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4824 debugstr_a(lpszStructType
));
4825 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
4826 lpszStructType
, &hFunc
);
4827 if (!pCryptDecodeObject
)
4828 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
4829 lpszStructType
, &hFunc
);
4831 if (pCryptDecodeObject
)
4832 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4833 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4834 else if (pCryptDecodeObjectEx
)
4835 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
4836 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4837 pvStructInfo
, pcbStructInfo
);
4839 CryptFreeOIDFunctionAddress(hFunc
, 0);
4840 TRACE_(crypt
)("returning %d\n", ret
);
4844 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4845 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4846 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4849 CryptDecodeObjectExFunc decodeFunc
;
4850 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4852 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4853 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
4854 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4856 if (!pvStructInfo
&& !pcbStructInfo
)
4858 SetLastError(ERROR_INVALID_PARAMETER
);
4863 SetLastError(CRYPT_E_ASN1_EOD
);
4866 if (cbEncoded
> MAX_ENCODED_LEN
)
4868 SetLastError(CRYPT_E_ASN1_LARGE
);
4872 SetLastError(NOERROR
);
4873 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
4874 *(BYTE
**)pvStructInfo
= NULL
;
4875 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
4878 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4879 debugstr_a(lpszStructType
));
4880 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
4884 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
4885 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4888 CryptDecodeObjectFunc pCryptDecodeObject
=
4889 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
4891 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4892 * directly, as that could cause an infinite loop.
4894 if (pCryptDecodeObject
)
4896 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4898 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4899 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
4900 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4901 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
4902 ret
= pCryptDecodeObject(dwCertEncodingType
,
4903 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
4904 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
4907 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4908 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4912 CryptFreeOIDFunctionAddress(hFunc
, 0);
4913 TRACE_(crypt
)("returning %d\n", ret
);