2 * Copyright 2005-2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
67 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
68 DWORD
, DWORD
, void *, DWORD
*);
69 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
70 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
76 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
78 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
82 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
88 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
92 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
93 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
94 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
97 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
99 /* Doesn't check the tag, assumes the caller does so */
100 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
101 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
102 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
103 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
104 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
105 * member has been initialized, doesn't do exception handling, and doesn't do
106 * memory allocation. Also doesn't check tag, assumes the caller has checked
109 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
113 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
114 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
116 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
117 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
120 /* Gets the number of length bytes from the given (leading) length byte */
121 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
123 /* Helper function to get the encoded length of the data starting at pbEncoded,
124 * where pbEncoded[0] is the tag. If the data are too short to contain a
125 * length or if the length is too large for cbEncoded, sets an appropriate
126 * error code and returns FALSE. If the encoded length is unknown due to
127 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
129 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
136 SetLastError(CRYPT_E_ASN1_CORRUPT
);
139 else if (pbEncoded
[1] <= 0x7f)
141 if (pbEncoded
[1] + 1 > cbEncoded
)
143 SetLastError(CRYPT_E_ASN1_EOD
);
152 else if (pbEncoded
[1] == 0x80)
154 *len
= CMSG_INDEFINITE_LENGTH
;
159 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
161 if (lenLen
> sizeof(DWORD
) + 1)
163 SetLastError(CRYPT_E_ASN1_LARGE
);
166 else if (lenLen
+ 2 > cbEncoded
)
168 SetLastError(CRYPT_E_ASN1_CORRUPT
);
181 if (out
+ lenLen
+ 1 > cbEncoded
)
183 SetLastError(CRYPT_E_ASN1_EOD
);
196 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
197 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
201 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
202 *len
== CMSG_INDEFINITE_LENGTH
)
204 SetLastError(CRYPT_E_ASN1_CORRUPT
);
210 /* Helper function to check *pcbStructInfo, set it to the required size, and
211 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
212 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
213 * pointer to the newly allocated memory.
215 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
216 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
221 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
223 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
224 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
226 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
227 if (!*(BYTE
**)pvStructInfo
)
230 *pcbStructInfo
= bytesNeeded
;
232 else if (*pcbStructInfo
< bytesNeeded
)
234 *pcbStructInfo
= bytesNeeded
;
235 SetLastError(ERROR_MORE_DATA
);
239 *pcbStructInfo
= bytesNeeded
;
243 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
245 if (pDecodePara
&& pDecodePara
->pfnFree
)
246 pDecodePara
->pfnFree(pv
);
251 /* Helper function to check *pcbStructInfo and set it to the required size.
252 * Assumes pvStructInfo is not NULL.
254 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
258 if (*pcbStructInfo
< bytesNeeded
)
260 *pcbStructInfo
= bytesNeeded
;
261 SetLastError(ERROR_MORE_DATA
);
266 *pcbStructInfo
= bytesNeeded
;
273 * The expected tag of the item. If tag is 0, decodeFunc is called
274 * regardless of the tag value seen.
276 * A sequence is decoded into a struct. The offset member is the
277 * offset of this item within that struct.
279 * The decoder function to use. If this is NULL, then the member isn't
280 * decoded, but minSize space is reserved for it.
282 * The minimum amount of space occupied after decoding. You must set this.
284 * If true, and the tag doesn't match the expected tag for this item,
285 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
286 * filled with 0 for this member.
287 * hasPointer, pointerOffset:
288 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
289 * the offset within the struct of the data pointer (or to the
290 * first data pointer, if more than one exist).
292 * Used by CRYPT_AsnDecodeSequence, not for your use.
294 struct AsnDecodeSequenceItem
298 InternalDecodeFunc decodeFunc
;
306 /* Decodes the items in a sequence, where the items are described in items,
307 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
308 * pvStructInfo. nextData is a pointer to the memory location at which the
309 * first decoded item with a dynamic pointer should point.
310 * Upon decoding, *cbDecoded is the total number of bytes decoded.
311 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
313 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
314 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
315 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
318 DWORD i
, decoded
= 0;
319 const BYTE
*ptr
= pbEncoded
;
321 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
322 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
324 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
326 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
330 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
331 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
333 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
335 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
337 DWORD itemEncodedLen
;
339 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
340 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
342 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
343 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
345 TRACE("Setting next pointer to %p\n",
347 *(BYTE
**)((BYTE
*)pvStructInfo
+
348 items
[i
].pointerOffset
) = nextData
;
350 if (items
[i
].decodeFunc
)
355 TRACE("decoding item %d\n", i
);
357 TRACE("sizing item %d\n", i
);
358 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
359 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
360 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
361 : NULL
, &items
[i
].size
, &itemDecoded
);
364 /* Account for alignment padding */
365 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
366 TRACE("item %d size: %d\n", i
, items
[i
].size
);
367 if (nextData
&& items
[i
].hasPointer
&&
368 items
[i
].size
> items
[i
].minSize
)
369 nextData
+= items
[i
].size
- items
[i
].minSize
;
370 if (itemDecoded
> itemEncodedLen
)
372 WARN("decoded length %d exceeds encoded %d\n",
373 itemDecoded
, itemEncodedLen
);
374 SetLastError(CRYPT_E_ASN1_CORRUPT
);
380 decoded
+= itemDecoded
;
381 TRACE("item %d: decoded %d bytes\n", i
,
385 else if (items
[i
].optional
&&
386 GetLastError() == CRYPT_E_ASN1_BADTAG
)
388 TRACE("skipping optional item %d\n", i
);
389 items
[i
].size
= items
[i
].minSize
;
390 SetLastError(NOERROR
);
394 TRACE("item %d failed: %08x\n", i
,
397 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
399 ERR("can't use indefinite length encoding without a decoder\n");
400 SetLastError(CRYPT_E_ASN1_CORRUPT
);
405 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
406 ptr
+= itemEncodedLen
;
407 decoded
+= itemEncodedLen
;
408 items
[i
].size
= items
[i
].minSize
;
411 else if (items
[i
].optional
)
413 TRACE("skipping optional item %d\n", i
);
414 items
[i
].size
= items
[i
].minSize
;
418 TRACE("item %d: tag %02x doesn't match expected %02x\n",
419 i
, ptr
[0], items
[i
].tag
);
420 SetLastError(CRYPT_E_ASN1_BADTAG
);
425 else if (items
[i
].optional
)
427 TRACE("missing optional item %d, skipping\n", i
);
428 items
[i
].size
= items
[i
].minSize
;
432 TRACE("not enough bytes for item %d, failing\n", i
);
433 SetLastError(CRYPT_E_ASN1_CORRUPT
);
438 *cbDecoded
= decoded
;
439 TRACE("returning %d\n", ret
);
443 /* This decodes an arbitrary sequence into a contiguous block of memory
444 * (basically, a struct.) Each element being decoded is described by a struct
445 * AsnDecodeSequenceItem, see above.
446 * startingPointer is an optional pointer to the first place where dynamic
447 * data will be stored. If you know the starting offset, you may pass it
448 * here. Otherwise, pass NULL, and one will be inferred from the items.
450 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
451 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
452 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
453 DWORD
*pcbDecoded
, void *startingPointer
)
457 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
458 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
463 SetLastError(CRYPT_E_ASN1_EOD
);
466 if (pbEncoded
[0] == ASN_SEQUENCE
)
470 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
472 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
473 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
474 BOOL indefinite
= FALSE
;
476 cbEncoded
-= 1 + lenBytes
;
477 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
482 else if (cbEncoded
< dataLen
)
484 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
486 SetLastError(CRYPT_E_ASN1_CORRUPT
);
491 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
492 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
493 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
495 if (cbDecoded
> cbEncoded
- 2)
497 /* Not enough space for 0 TLV */
498 SetLastError(CRYPT_E_ASN1_CORRUPT
);
501 else if (*(ptr
+ cbDecoded
) != 0 ||
502 *(ptr
+ cbDecoded
+ 1) != 0)
504 TRACE("expected 0 TLV\n");
505 SetLastError(CRYPT_E_ASN1_CORRUPT
);
512 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
514 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
516 SetLastError(CRYPT_E_ASN1_CORRUPT
);
521 DWORD i
, bytesNeeded
= 0, structSize
= 0;
523 for (i
= 0; i
< cItem
; i
++)
525 bytesNeeded
+= items
[i
].size
;
526 structSize
+= items
[i
].minSize
;
529 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
531 *pcbStructInfo
= bytesNeeded
;
532 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
533 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
537 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
538 pvStructInfo
= *(BYTE
**)pvStructInfo
;
540 nextData
= (BYTE
*)startingPointer
;
542 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
543 memset(pvStructInfo
, 0, structSize
);
544 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
545 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
547 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
548 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
555 SetLastError(CRYPT_E_ASN1_BADTAG
);
558 TRACE("returning %d (%08x)\n", ret
, GetLastError());
563 * The expected tag of the entire encoded array (usually a variant
564 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
565 * regardless of the tag seen.
567 * used to decode each item in the array
569 * is the minimum size of each decoded item
571 * indicates whether each item has a dynamic pointer
573 * indicates the offset within itemSize at which the pointer exists
575 struct AsnArrayDescriptor
578 InternalDecodeFunc decodeFunc
;
584 struct AsnArrayItemSize
590 /* Decodes an array of like types into a struct GenericArray.
591 * The layout and decoding of the array are described by a struct
592 * AsnArrayDescriptor.
594 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
595 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
596 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
597 DWORD
*pcbDecoded
, void *startingPointer
)
601 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
602 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
605 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
609 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
611 DWORD bytesNeeded
, cItems
= 0, decoded
;
612 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
613 /* There can be arbitrarily many items, but there is often only one.
615 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
617 decoded
= 1 + lenBytes
;
618 bytesNeeded
= sizeof(struct GenericArray
);
622 BOOL doneDecoding
= FALSE
;
624 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
626 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
633 SetLastError(CRYPT_E_ASN1_CORRUPT
);
640 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
644 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
646 /* Each item decoded may not tolerate extraneous bytes,
647 * so get the length of the next element if known.
649 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
650 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
652 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
653 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
655 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
659 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
660 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
665 if (itemSizes
!= &itemSize
)
666 itemSizes
= CryptMemRealloc(itemSizes
,
667 cItems
* sizeof(struct AsnArrayItemSize
));
672 cItems
* sizeof(struct AsnArrayItemSize
));
674 memcpy(itemSizes
, &itemSize
,
679 decoded
+= itemDecoded
;
680 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
681 itemSizes
[cItems
- 1].size
= size
;
694 *pcbDecoded
= decoded
;
696 *pcbStructInfo
= bytesNeeded
;
697 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
698 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
703 struct GenericArray
*array
;
705 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
706 pvStructInfo
= *(BYTE
**)pvStructInfo
;
707 array
= (struct GenericArray
*)pvStructInfo
;
708 array
->cItems
= cItems
;
710 array
->rgItems
= startingPointer
;
712 array
->rgItems
= (BYTE
*)array
+
713 sizeof(struct GenericArray
);
714 nextData
= array
->rgItems
+
715 array
->cItems
* arrayDesc
->itemSize
;
716 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
717 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
722 if (arrayDesc
->hasPointer
)
723 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
724 + arrayDesc
->pointerOffset
) = nextData
;
725 ret
= arrayDesc
->decodeFunc(ptr
,
726 itemSizes
[i
].encodedLen
,
727 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
728 array
->rgItems
+ i
* arrayDesc
->itemSize
,
729 &itemSizes
[i
].size
, &itemDecoded
);
732 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
736 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
737 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
740 if (itemSizes
!= &itemSize
)
741 CryptMemFree(itemSizes
);
746 SetLastError(CRYPT_E_ASN1_BADTAG
);
752 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
753 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
754 * to CRYPT_E_ASN1_CORRUPT.
755 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
758 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
759 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
764 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
766 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
767 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
769 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
770 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
773 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
775 *pcbStructInfo
= bytesNeeded
;
776 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
778 CRYPT_DER_BLOB
*blob
;
780 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
781 pvStructInfo
= *(BYTE
**)pvStructInfo
;
782 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
783 blob
->cbData
= 1 + lenBytes
+ dataLen
;
786 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
787 blob
->pbData
= (BYTE
*)pbEncoded
;
790 assert(blob
->pbData
);
791 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
796 SetLastError(CRYPT_E_ASN1_CORRUPT
);
804 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
805 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
806 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
811 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
812 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
814 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
817 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
818 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
820 if (ret
&& pvStructInfo
)
822 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
829 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
831 temp
= blob
->pbData
[i
];
832 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
833 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
837 TRACE("returning %d (%08x)\n", ret
, GetLastError());
841 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
842 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
843 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
847 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
848 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
852 struct AsnDecodeSequenceItem items
[] = {
853 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
854 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
855 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
856 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
857 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
858 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
859 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
860 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
861 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
862 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
865 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
866 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
867 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
868 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
869 pcbStructInfo
, NULL
, NULL
);
873 SetLastError(STATUS_ACCESS_VIOLATION
);
878 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
882 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
883 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
888 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
890 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
892 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
893 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
895 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
900 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
901 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
905 struct AsnDecodeSequenceItem items
[] = {
906 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
907 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
908 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
909 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
912 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
913 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
918 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
919 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
925 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
927 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
929 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
930 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
931 if (ret
&& pcbDecoded
)
932 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
937 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
938 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
939 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
942 struct AsnDecodeSequenceItem items
[] = {
943 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
944 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
945 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
946 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
947 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
948 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
949 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
950 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
951 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
952 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
954 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
955 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
957 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
958 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
960 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
961 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
962 FALSE
, TRUE
, offsetof(CERT_INFO
,
963 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
964 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
965 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
966 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
967 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
968 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
969 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
970 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
971 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
972 offsetof(CERT_INFO
, rgExtension
), 0 },
975 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
976 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
978 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
979 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
981 if (ret
&& pvStructInfo
)
985 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
986 info
= *(CERT_INFO
**)pvStructInfo
;
988 info
= (CERT_INFO
*)pvStructInfo
;
989 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
990 !info
->Subject
.cbData
)
992 SetLastError(CRYPT_E_ASN1_CORRUPT
);
993 /* Don't need to deallocate, because it should have failed on the
994 * first pass (and no memory was allocated.)
1000 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1004 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1005 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1006 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1010 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1011 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1017 /* Unless told not to, first try to decode it as a signed cert. */
1018 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1020 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1022 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1023 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1024 (BYTE
*)&signedCert
, &size
);
1028 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1029 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1030 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1031 pvStructInfo
, pcbStructInfo
);
1032 LocalFree(signedCert
);
1035 /* Failing that, try it as an unsigned cert */
1039 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1040 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1041 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1046 SetLastError(STATUS_ACCESS_VIOLATION
);
1050 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1054 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1055 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1058 struct AsnDecodeSequenceItem items
[] = {
1059 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1060 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1061 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1062 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1063 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1064 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1065 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1066 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1068 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
1070 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1073 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1074 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1075 entry
? entry
->SerialNumber
.pbData
: NULL
);
1076 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1078 WARN("empty CRL entry serial number\n");
1079 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1085 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1086 * been set prior to calling.
1088 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1089 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1092 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1093 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1094 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1095 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1097 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1098 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1100 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1101 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1102 entries
? entries
->rgItems
: NULL
);
1103 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1107 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1108 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1109 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1111 struct AsnDecodeSequenceItem items
[] = {
1112 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1113 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1114 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1115 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1116 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1117 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1118 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1120 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1121 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1122 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1123 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1124 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1125 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1126 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1127 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1128 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1129 offsetof(CRL_INFO
, rgExtension
), 0 },
1133 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1134 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1136 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1137 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1140 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1144 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1145 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1146 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1150 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1151 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1157 /* Unless told not to, first try to decode it as a signed crl. */
1158 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1160 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1162 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1163 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1164 (BYTE
*)&signedCrl
, &size
);
1168 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1169 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1170 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1171 pvStructInfo
, pcbStructInfo
);
1172 LocalFree(signedCrl
);
1175 /* Failing that, try it as an unsigned crl */
1179 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1180 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1181 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1186 SetLastError(STATUS_ACCESS_VIOLATION
);
1190 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1194 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1195 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1200 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1201 pvStructInfo
, *pcbStructInfo
);
1203 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1205 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1206 DWORD bytesNeeded
= sizeof(LPSTR
);
1210 /* The largest possible string for the first two components
1211 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1216 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1217 pbEncoded
[1 + lenBytes
] / 40,
1218 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1220 bytesNeeded
+= strlen(firstTwo
) + 1;
1221 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1222 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1224 /* large enough for ".4000000" */
1228 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1235 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1238 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1245 snprintf(str
, sizeof(str
), ".%d", val
);
1246 bytesNeeded
+= strlen(str
);
1251 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1253 *pcbStructInfo
= bytesNeeded
;
1254 else if (*pcbStructInfo
< bytesNeeded
)
1256 *pcbStructInfo
= bytesNeeded
;
1257 SetLastError(ERROR_MORE_DATA
);
1265 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1268 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1269 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1271 pszObjId
+= strlen(pszObjId
);
1272 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1273 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1277 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1286 sprintf(pszObjId
, ".%d", val
);
1287 pszObjId
+= strlen(pszObjId
);
1291 *(LPSTR
*)pvStructInfo
= NULL
;
1292 *pcbStructInfo
= bytesNeeded
;
1298 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1299 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1303 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1304 pvStructInfo
, *pcbStructInfo
);
1306 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1307 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1308 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1311 SetLastError(CRYPT_E_ASN1_BADTAG
);
1317 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1320 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1321 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1323 struct AsnDecodeSequenceItem items
[] = {
1324 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1325 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1326 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1327 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1328 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1329 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1330 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1331 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1334 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1336 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1340 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1341 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1342 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1343 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1345 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1346 debugstr_a(ext
->pszObjId
));
1347 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1351 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
1352 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1356 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1357 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1358 offsetof(CERT_EXTENSION
, pszObjId
) };
1359 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1361 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1362 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1364 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1365 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1366 exts
? exts
->rgExtension
: NULL
);
1370 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1371 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1372 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1378 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1379 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1380 if (ret
&& pvStructInfo
)
1382 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1383 pcbStructInfo
, *pcbStructInfo
);
1386 CERT_EXTENSIONS
*exts
;
1388 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1389 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1390 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1391 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1392 sizeof(CERT_EXTENSIONS
));
1393 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1394 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1395 pcbStructInfo
, NULL
);
1401 SetLastError(STATUS_ACCESS_VIOLATION
);
1408 /* Warning: this assumes the address of value->Value.pbData is already set, in
1409 * order to avoid overwriting memory. (In some cases, it may change it, if it
1410 * doesn't copy anything to memory.) Be sure to set it correctly!
1412 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1413 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1418 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1420 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1422 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1423 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1425 switch (pbEncoded
[0])
1427 case ASN_OCTETSTRING
:
1428 valueType
= CERT_RDN_OCTET_STRING
;
1429 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1430 bytesNeeded
+= dataLen
;
1432 case ASN_NUMERICSTRING
:
1433 valueType
= CERT_RDN_NUMERIC_STRING
;
1434 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1435 bytesNeeded
+= dataLen
;
1437 case ASN_PRINTABLESTRING
:
1438 valueType
= CERT_RDN_PRINTABLE_STRING
;
1439 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1440 bytesNeeded
+= dataLen
;
1443 valueType
= CERT_RDN_IA5_STRING
;
1444 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1445 bytesNeeded
+= dataLen
;
1448 valueType
= CERT_RDN_T61_STRING
;
1449 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1450 bytesNeeded
+= dataLen
;
1452 case ASN_VIDEOTEXSTRING
:
1453 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1454 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1455 bytesNeeded
+= dataLen
;
1457 case ASN_GRAPHICSTRING
:
1458 valueType
= CERT_RDN_GRAPHIC_STRING
;
1459 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1460 bytesNeeded
+= dataLen
;
1462 case ASN_VISIBLESTRING
:
1463 valueType
= CERT_RDN_VISIBLE_STRING
;
1464 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1465 bytesNeeded
+= dataLen
;
1467 case ASN_GENERALSTRING
:
1468 valueType
= CERT_RDN_GENERAL_STRING
;
1469 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1470 bytesNeeded
+= dataLen
;
1472 case ASN_UNIVERSALSTRING
:
1473 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1474 SetLastError(CRYPT_E_ASN1_BADTAG
);
1477 valueType
= CERT_RDN_BMP_STRING
;
1478 bytesNeeded
+= dataLen
;
1480 case ASN_UTF8STRING
:
1481 valueType
= CERT_RDN_UTF8_STRING
;
1482 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1483 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1486 SetLastError(CRYPT_E_ASN1_BADTAG
);
1491 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1493 *pcbStructInfo
= bytesNeeded
;
1494 else if (*pcbStructInfo
< bytesNeeded
)
1496 *pcbStructInfo
= bytesNeeded
;
1497 SetLastError(ERROR_MORE_DATA
);
1502 *pcbStructInfo
= bytesNeeded
;
1503 value
->dwValueType
= valueType
;
1508 assert(value
->Value
.pbData
);
1509 switch (pbEncoded
[0])
1511 case ASN_OCTETSTRING
:
1512 case ASN_NUMERICSTRING
:
1513 case ASN_PRINTABLESTRING
:
1516 case ASN_VIDEOTEXSTRING
:
1517 case ASN_GRAPHICSTRING
:
1518 case ASN_VISIBLESTRING
:
1519 case ASN_GENERALSTRING
:
1520 value
->Value
.cbData
= dataLen
;
1523 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1524 memcpy(value
->Value
.pbData
,
1525 pbEncoded
+ 1 + lenBytes
, dataLen
);
1527 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1533 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1535 value
->Value
.cbData
= dataLen
;
1536 for (i
= 0; i
< dataLen
/ 2; i
++)
1537 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1538 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1541 case ASN_UTF8STRING
:
1543 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1545 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1546 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1547 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1554 value
->Value
.cbData
= 0;
1555 value
->Value
.pbData
= NULL
;
1562 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1563 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1564 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1570 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1571 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1572 if (ret
&& pvStructInfo
)
1574 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1575 pcbStructInfo
, *pcbStructInfo
);
1578 CERT_NAME_VALUE
*value
;
1580 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1581 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1582 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1583 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1584 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1585 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1586 pcbStructInfo
, NULL
);
1592 SetLastError(STATUS_ACCESS_VIOLATION
);
1599 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1600 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1605 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1607 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1609 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1610 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1612 switch (pbEncoded
[0])
1614 case ASN_NUMERICSTRING
:
1615 valueType
= CERT_RDN_NUMERIC_STRING
;
1617 bytesNeeded
+= (dataLen
+ 1) * 2;
1619 case ASN_PRINTABLESTRING
:
1620 valueType
= CERT_RDN_PRINTABLE_STRING
;
1622 bytesNeeded
+= (dataLen
+ 1) * 2;
1625 valueType
= CERT_RDN_IA5_STRING
;
1627 bytesNeeded
+= (dataLen
+ 1) * 2;
1630 valueType
= CERT_RDN_T61_STRING
;
1632 bytesNeeded
+= (dataLen
+ 1) * 2;
1634 case ASN_VIDEOTEXSTRING
:
1635 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1637 bytesNeeded
+= (dataLen
+ 1) * 2;
1639 case ASN_GRAPHICSTRING
:
1640 valueType
= CERT_RDN_GRAPHIC_STRING
;
1642 bytesNeeded
+= (dataLen
+ 1) * 2;
1644 case ASN_VISIBLESTRING
:
1645 valueType
= CERT_RDN_VISIBLE_STRING
;
1647 bytesNeeded
+= (dataLen
+ 1) * 2;
1649 case ASN_GENERALSTRING
:
1650 valueType
= CERT_RDN_GENERAL_STRING
;
1652 bytesNeeded
+= (dataLen
+ 1) * 2;
1654 case ASN_UNIVERSALSTRING
:
1655 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1657 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1660 valueType
= CERT_RDN_BMP_STRING
;
1662 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1664 case ASN_UTF8STRING
:
1665 valueType
= CERT_RDN_UTF8_STRING
;
1667 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1668 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1671 SetLastError(CRYPT_E_ASN1_BADTAG
);
1676 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1678 *pcbStructInfo
= bytesNeeded
;
1679 else if (*pcbStructInfo
< bytesNeeded
)
1681 *pcbStructInfo
= bytesNeeded
;
1682 SetLastError(ERROR_MORE_DATA
);
1687 *pcbStructInfo
= bytesNeeded
;
1688 value
->dwValueType
= valueType
;
1692 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1694 assert(value
->Value
.pbData
);
1695 switch (pbEncoded
[0])
1697 case ASN_NUMERICSTRING
:
1698 case ASN_PRINTABLESTRING
:
1701 case ASN_VIDEOTEXSTRING
:
1702 case ASN_GRAPHICSTRING
:
1703 case ASN_VISIBLESTRING
:
1704 case ASN_GENERALSTRING
:
1705 value
->Value
.cbData
= dataLen
* 2;
1706 for (i
= 0; i
< dataLen
; i
++)
1707 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1710 case ASN_UNIVERSALSTRING
:
1711 value
->Value
.cbData
= dataLen
/ 2;
1712 for (i
= 0; i
< dataLen
/ 4; i
++)
1713 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1714 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1718 value
->Value
.cbData
= dataLen
;
1719 for (i
= 0; i
< dataLen
/ 2; i
++)
1720 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1721 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1724 case ASN_UTF8STRING
:
1725 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1726 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1727 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1728 value
->Value
.pbData
[value
->Value
.cbData
/ sizeof(WCHAR
)]
1730 value
->Value
.cbData
+= sizeof(WCHAR
);
1736 value
->Value
.cbData
= 0;
1737 value
->Value
.pbData
= NULL
;
1744 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1745 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1746 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1752 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1753 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1754 if (ret
&& pvStructInfo
)
1756 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1757 pcbStructInfo
, *pcbStructInfo
);
1760 CERT_NAME_VALUE
*value
;
1762 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1763 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1764 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1765 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1766 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1767 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1768 pcbStructInfo
, NULL
);
1774 SetLastError(STATUS_ACCESS_VIOLATION
);
1781 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1782 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1785 struct AsnDecodeSequenceItem items
[] = {
1786 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1787 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1788 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1789 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1790 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1791 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1793 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1795 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1796 pvStructInfo
, *pcbStructInfo
);
1799 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1800 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1801 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1802 attr
? attr
->pszObjId
: NULL
);
1805 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1806 debugstr_a(attr
->pszObjId
));
1807 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1809 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1813 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1814 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1817 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1818 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1819 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1820 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1822 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1823 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1824 rdn
? rdn
->rgRDNAttr
: NULL
);
1828 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1829 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1830 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1836 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1837 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1838 offsetof(CERT_RDN
, rgRDNAttr
) };
1840 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1841 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1845 SetLastError(STATUS_ACCESS_VIOLATION
);
1852 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1853 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1857 struct AsnDecodeSequenceItem items
[] = {
1858 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1859 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1860 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1861 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1862 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1863 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1865 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1867 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1868 pvStructInfo
, *pcbStructInfo
);
1871 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1872 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1873 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1874 attr
? attr
->pszObjId
: NULL
);
1877 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1878 debugstr_a(attr
->pszObjId
));
1879 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1881 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1885 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1886 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1889 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1890 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1891 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1892 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1894 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1895 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1896 rdn
? rdn
->rgRDNAttr
: NULL
);
1900 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1901 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1902 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1908 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1909 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1910 offsetof(CERT_RDN
, rgRDNAttr
) };
1912 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1913 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1917 SetLastError(STATUS_ACCESS_VIOLATION
);
1924 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1927 BOOL ret
= TRUE
, done
= FALSE
;
1928 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
1930 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
1937 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
1940 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1942 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
1944 indefiniteNestingLevels
++;
1945 pbEncoded
+= 1 + lenBytes
;
1946 cbEncoded
-= 1 + lenBytes
;
1947 decoded
+= 1 + lenBytes
;
1948 TRACE("indefiniteNestingLevels = %d\n",
1949 indefiniteNestingLevels
);
1953 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
1954 indefiniteNestingLevels
)
1956 indefiniteNestingLevels
--;
1957 TRACE("indefiniteNestingLevels = %d\n",
1958 indefiniteNestingLevels
);
1960 pbEncoded
+= 1 + lenBytes
+ dataLen
;
1961 cbEncoded
-= 1 + lenBytes
+ dataLen
;
1962 decoded
+= 1 + lenBytes
+ dataLen
;
1963 if (!indefiniteNestingLevels
)
1967 } while (ret
&& !done
);
1968 /* If we haven't found all 0 TLVs, we haven't found the end */
1969 if (ret
&& indefiniteNestingLevels
)
1971 SetLastError(CRYPT_E_ASN1_EOD
);
1975 *pcbDecoded
= decoded
;
1976 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
1980 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
1981 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1985 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
1987 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1988 pvStructInfo
, *pcbStructInfo
);
1990 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
1992 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1993 bytesNeeded
+= encodedLen
;
1995 *pcbStructInfo
= bytesNeeded
;
1996 else if (*pcbStructInfo
< bytesNeeded
)
1998 SetLastError(ERROR_MORE_DATA
);
1999 *pcbStructInfo
= bytesNeeded
;
2004 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
2006 *pcbStructInfo
= bytesNeeded
;
2007 blob
->cbData
= encodedLen
;
2010 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2011 blob
->pbData
= (LPBYTE
)pbEncoded
;
2014 assert(blob
->pbData
);
2015 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2019 blob
->pbData
= NULL
;
2022 *pcbDecoded
= encodedLen
;
2027 static BOOL
CRYPT_DecodeDERArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2028 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2031 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
2032 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2033 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
2035 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2036 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2038 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2039 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2040 array
? array
->rgItems
: NULL
);
2044 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2045 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2048 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2049 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2050 CTL_USAGE
*usage
= (CTL_USAGE
*)pvStructInfo
;
2052 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2053 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2054 usage
? usage
->rgpszUsageIdentifier
: NULL
);
2058 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2059 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2061 struct AsnDecodeSequenceItem items
[] = {
2062 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2063 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2064 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2065 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2066 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
), FALSE
,
2067 TRUE
, offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2070 CTL_ENTRY
*entry
= (CTL_ENTRY
*)pvStructInfo
;
2072 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2075 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2076 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2077 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2081 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2082 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2085 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2086 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2087 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2088 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2090 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2091 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2093 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2094 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2095 entries
? entries
->rgItems
: NULL
);
2099 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2100 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2101 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2105 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2106 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2110 struct AsnDecodeSequenceItem items
[] = {
2111 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2112 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2113 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2114 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2115 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2116 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2117 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2118 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2119 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2120 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2121 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2122 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2123 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2125 { 0, offsetof(CTL_INFO
, NextUpdate
),
2126 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2128 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2129 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2130 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2131 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2132 CRYPT_AsnDecodeCTLEntries
, sizeof(struct GenericArray
),
2133 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2134 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2135 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
2136 offsetof(CTL_INFO
, rgExtension
), 0 },
2139 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2140 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2142 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2143 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2144 pcbStructInfo
, NULL
, NULL
);
2148 SetLastError(STATUS_ACCESS_VIOLATION
);
2154 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2155 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2159 struct AsnDecodeSequenceItem items
[] = {
2160 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2161 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2162 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2163 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2164 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2165 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2167 PCRYPT_SMIME_CAPABILITY capability
= (PCRYPT_SMIME_CAPABILITY
)pvStructInfo
;
2169 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2170 pvStructInfo
, *pcbStructInfo
);
2172 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2173 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2174 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2175 TRACE("returning %d\n", ret
);
2179 static BOOL
CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE
*pbEncoded
,
2180 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2183 struct AsnArrayDescriptor arrayDesc
= { 0,
2184 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2185 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2186 PCRYPT_SMIME_CAPABILITIES capabilities
=
2187 (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2190 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2191 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2192 capabilities
? capabilities
->rgCapability
: NULL
);
2196 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2197 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2198 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2202 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2203 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2210 SetLastError(CRYPT_E_ASN1_EOD
);
2211 else if (pbEncoded
[0] != ASN_SEQUENCEOF
)
2212 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2213 else if ((ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2214 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2218 *pcbStructInfo
= bytesNeeded
;
2219 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2220 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2222 PCRYPT_SMIME_CAPABILITIES capabilities
;
2224 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2225 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2226 capabilities
= (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2227 capabilities
->rgCapability
=
2228 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2229 sizeof(CRYPT_SMIME_CAPABILITIES
));
2230 ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2231 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2232 &bytesNeeded
, NULL
);
2238 SetLastError(STATUS_ACCESS_VIOLATION
);
2241 TRACE("returning %d\n", ret
);
2245 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2246 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2251 LPSTR
*pStr
= pvStructInfo
;
2253 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2255 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2256 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2258 if (pbEncoded
[0] != ASN_IA5STRING
)
2260 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2265 bytesNeeded
+= dataLen
;
2267 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2269 *pcbStructInfo
= bytesNeeded
;
2270 else if (*pcbStructInfo
< bytesNeeded
)
2272 *pcbStructInfo
= bytesNeeded
;
2273 SetLastError(ERROR_MORE_DATA
);
2278 *pcbStructInfo
= bytesNeeded
;
2284 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2295 static BOOL
CRYPT_AsnDecodeIntArray(const BYTE
*pbEncoded
,
2296 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2299 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2300 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2301 struct GenericArray
*array
= pvStructInfo
;
2304 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2305 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2307 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2308 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2309 array
? array
->rgItems
: NULL
);
2310 TRACE("returning %d\n", ret
);
2314 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2315 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2319 struct AsnDecodeSequenceItem items
[] = {
2320 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2321 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2322 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2323 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2324 cNoticeNumbers
), CRYPT_AsnDecodeIntArray
, sizeof(struct GenericArray
),
2325 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2326 rgNoticeNumbers
), 0 },
2330 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2331 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2333 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2334 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2338 /* The caller is expecting a pointer to a
2339 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2340 * CRYPT_AsnDecodeSequence is decoding a
2341 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2342 * needed, and decode again if the requisite space is available.
2344 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2346 *pcbStructInfo
= bytesNeeded
;
2347 else if (*pcbStructInfo
< bytesNeeded
)
2349 *pcbStructInfo
= bytesNeeded
;
2350 SetLastError(ERROR_MORE_DATA
);
2355 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2357 *pcbStructInfo
= bytesNeeded
;
2358 /* The pointer (pvStructInfo) passed in points to the first dynamic
2359 * pointer, so use it as the pointer to the
2360 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2361 * appropriate offset for the first dynamic pointer within the
2362 * notice reference by pointing to the first memory location past
2363 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2366 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2367 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2368 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2369 ret
= CRYPT_AsnDecodeSequence(items
,
2370 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2371 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2372 noticeRef
->pszOrganization
);
2375 TRACE("returning %d\n", ret
);
2379 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2380 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2386 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2388 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2389 DWORD bytesNeeded
= sizeof(LPWSTR
);
2391 switch (pbEncoded
[0])
2393 case ASN_NUMERICSTRING
:
2395 bytesNeeded
+= (dataLen
+ 1) * 2;
2397 case ASN_PRINTABLESTRING
:
2399 bytesNeeded
+= (dataLen
+ 1) * 2;
2403 bytesNeeded
+= (dataLen
+ 1) * 2;
2407 bytesNeeded
+= (dataLen
+ 1) * 2;
2409 case ASN_VIDEOTEXSTRING
:
2411 bytesNeeded
+= (dataLen
+ 1) * 2;
2413 case ASN_GRAPHICSTRING
:
2415 bytesNeeded
+= (dataLen
+ 1) * 2;
2417 case ASN_VISIBLESTRING
:
2419 bytesNeeded
+= (dataLen
+ 1) * 2;
2421 case ASN_GENERALSTRING
:
2423 bytesNeeded
+= (dataLen
+ 1) * 2;
2425 case ASN_UNIVERSALSTRING
:
2427 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2431 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2433 case ASN_UTF8STRING
:
2435 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2436 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2439 SetLastError(CRYPT_E_ASN1_BADTAG
);
2444 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2446 *pcbStructInfo
= bytesNeeded
;
2447 else if (*pcbStructInfo
< bytesNeeded
)
2449 *pcbStructInfo
= bytesNeeded
;
2450 SetLastError(ERROR_MORE_DATA
);
2455 LPWSTR
*pStr
= pvStructInfo
;
2457 *pcbStructInfo
= bytesNeeded
;
2461 LPWSTR str
= *(LPWSTR
*)pStr
;
2464 switch (pbEncoded
[0])
2466 case ASN_NUMERICSTRING
:
2467 case ASN_PRINTABLESTRING
:
2470 case ASN_VIDEOTEXSTRING
:
2471 case ASN_GRAPHICSTRING
:
2472 case ASN_VISIBLESTRING
:
2473 case ASN_GENERALSTRING
:
2474 for (i
= 0; i
< dataLen
; i
++)
2475 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2478 case ASN_UNIVERSALSTRING
:
2479 for (i
= 0; i
< dataLen
/ 4; i
++)
2480 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2481 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2485 for (i
= 0; i
< dataLen
/ 2; i
++)
2486 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2487 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2490 case ASN_UTF8STRING
:
2492 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2493 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2494 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2507 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2508 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2509 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2512 struct AsnDecodeSequenceItem items
[] = {
2513 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2514 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2515 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2516 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2517 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2518 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2519 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2521 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2523 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2524 pvStructInfo
, *pcbStructInfo
);
2526 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2527 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2528 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2529 TRACE("returning %d\n", ret
);
2533 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2534 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2535 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2536 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2540 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2541 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2547 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2548 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2553 *pcbStructInfo
= bytesNeeded
;
2554 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2555 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2557 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2559 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2560 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2561 notice
= pvStructInfo
;
2562 notice
->pNoticeReference
=
2563 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2564 ((BYTE
*)pvStructInfo
+
2565 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2566 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2567 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2568 pvStructInfo
, &bytesNeeded
, NULL
);
2574 SetLastError(STATUS_ACCESS_VIOLATION
);
2577 TRACE("returning %d\n", ret
);
2581 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2582 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2586 struct AsnDecodeSequenceItem items
[] = {
2587 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2588 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2589 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2590 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2591 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
2592 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2594 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2596 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2597 pvStructInfo
, *pcbStructInfo
);
2599 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2600 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2601 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2602 TRACE("returning %d\n", ret
);
2606 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2607 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2608 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2612 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2613 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2619 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2620 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2624 *pcbStructInfo
= bytesNeeded
;
2625 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2626 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2628 PCRYPT_ATTRIBUTE attr
;
2630 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2631 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2632 attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2633 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2634 sizeof(CRYPT_ATTRIBUTE
));
2635 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2636 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2643 SetLastError(STATUS_ACCESS_VIOLATION
);
2646 TRACE("returning %d\n", ret
);
2650 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2651 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2654 struct AsnArrayDescriptor arrayDesc
= { 0,
2655 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2656 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2657 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2660 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2661 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2666 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2667 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2668 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2672 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2673 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2680 SetLastError(CRYPT_E_ASN1_EOD
);
2681 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2682 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2683 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2684 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2688 *pcbStructInfo
= bytesNeeded
;
2689 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2690 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2692 PCRYPT_ATTRIBUTES attrs
;
2694 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2695 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2696 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2697 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2698 sizeof(CRYPT_ATTRIBUTES
));
2699 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2700 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2701 &bytesNeeded
, NULL
);
2707 SetLastError(STATUS_ACCESS_VIOLATION
);
2710 TRACE("returning %d\n", ret
);
2714 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2715 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2717 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
2718 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
2720 struct AsnDecodeSequenceItem items
[] = {
2721 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2722 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2723 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2724 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2725 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2726 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2729 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2730 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2732 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2733 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2734 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2735 if (ret
&& pvStructInfo
)
2737 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2738 debugstr_a(algo
->pszObjId
));
2743 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2744 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2748 struct AsnDecodeSequenceItem items
[] = {
2749 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2750 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2751 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2752 Algorithm
.pszObjId
) },
2753 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2754 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2755 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2757 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2759 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2760 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2761 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2765 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2766 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2767 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2775 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2776 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2779 *pcbStructInfo
= bytesNeeded
;
2780 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2781 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2783 PCERT_PUBLIC_KEY_INFO info
;
2785 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2786 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2787 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2788 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2789 sizeof(CERT_PUBLIC_KEY_INFO
);
2790 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2791 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2792 &bytesNeeded
, NULL
);
2798 SetLastError(STATUS_ACCESS_VIOLATION
);
2805 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2806 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2812 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2815 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2817 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2820 if (pbEncoded
[1] > 1)
2822 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2829 *pcbStructInfo
= sizeof(BOOL
);
2832 else if (*pcbStructInfo
< sizeof(BOOL
))
2834 *pcbStructInfo
= sizeof(BOOL
);
2835 SetLastError(ERROR_MORE_DATA
);
2840 *pcbStructInfo
= sizeof(BOOL
);
2841 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2844 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2848 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2849 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2851 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2852 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2855 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2856 pvStructInfo
, *pcbStructInfo
);
2860 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2863 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2864 if (1 + lenBytes
> cbEncoded
)
2866 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2869 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2871 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2873 case 1: /* rfc822Name */
2874 case 2: /* dNSName */
2875 case 6: /* uniformResourceIdentifier */
2876 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2878 case 4: /* directoryName */
2879 case 7: /* iPAddress */
2880 bytesNeeded
+= dataLen
;
2882 case 8: /* registeredID */
2883 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2887 /* FIXME: ugly, shouldn't need to know internals of OID decode
2888 * function to use it.
2890 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2893 case 0: /* otherName */
2894 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2895 SetLastError(CRYPT_E_ASN1_BADTAG
);
2898 case 3: /* x400Address, unimplemented */
2899 case 5: /* ediPartyName, unimplemented */
2900 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2901 SetLastError(CRYPT_E_ASN1_BADTAG
);
2905 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2906 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2912 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2914 *pcbStructInfo
= bytesNeeded
;
2915 else if (*pcbStructInfo
< bytesNeeded
)
2917 *pcbStructInfo
= bytesNeeded
;
2918 SetLastError(ERROR_MORE_DATA
);
2923 *pcbStructInfo
= bytesNeeded
;
2924 /* MS used values one greater than the asn1 ones.. sigh */
2925 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
2926 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2928 case 1: /* rfc822Name */
2929 case 2: /* dNSName */
2930 case 6: /* uniformResourceIdentifier */
2934 for (i
= 0; i
< dataLen
; i
++)
2935 entry
->u
.pwszURL
[i
] =
2936 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2937 entry
->u
.pwszURL
[i
] = 0;
2938 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2939 debugstr_w(entry
->u
.pwszURL
));
2942 case 4: /* directoryName */
2943 /* The data are memory-equivalent with the IPAddress case,
2946 case 7: /* iPAddress */
2947 /* The next data pointer is in the pwszURL spot, that is,
2948 * the first 4 bytes. Need to move it to the next spot.
2950 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2951 entry
->u
.IPAddress
.cbData
= dataLen
;
2952 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2955 case 8: /* registeredID */
2956 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2957 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2966 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
2967 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2971 struct AsnArrayDescriptor arrayDesc
= { 0,
2972 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2973 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2974 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2976 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2977 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2980 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2981 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2982 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2983 info
? info
->rgAltEntry
: NULL
);
2987 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2988 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
2989 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2994 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2995 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2997 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3000 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3001 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
3003 if (ret
&& pvStructInfo
)
3005 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3012 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
3014 temp
= blob
->pbData
[i
];
3015 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
3016 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
3020 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3024 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3025 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3026 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3032 struct AsnDecodeSequenceItem items
[] = {
3033 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3034 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3035 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3036 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3037 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3038 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3039 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3040 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3041 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3042 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3043 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3046 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3047 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3048 pcbStructInfo
, NULL
, NULL
);
3052 SetLastError(STATUS_ACCESS_VIOLATION
);
3059 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3060 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3061 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3067 struct AsnDecodeSequenceItem items
[] = {
3068 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3069 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3070 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3071 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3072 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3073 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3074 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3075 AuthorityCertIssuer
.rgAltEntry
), 0 },
3076 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3077 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3078 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3079 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3080 AuthorityCertSerialNumber
.pbData
), 0 },
3083 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3084 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3085 pcbStructInfo
, NULL
, NULL
);
3089 SetLastError(STATUS_ACCESS_VIOLATION
);
3096 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3097 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3100 struct AsnDecodeSequenceItem items
[] = {
3101 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3102 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3103 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3104 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3105 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3106 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3108 CERT_ACCESS_DESCRIPTION
*descr
= (CERT_ACCESS_DESCRIPTION
*)pvStructInfo
;
3110 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3111 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3112 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3115 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3116 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3117 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3121 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3122 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3126 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3127 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3128 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3130 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3131 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3135 SetLastError(STATUS_ACCESS_VIOLATION
);
3142 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3143 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3148 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3149 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3151 /* The caller has already checked the tag, no need to check it again.
3152 * Check the outer length is valid:
3154 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3156 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3159 pbEncoded
+= 1 + lenBytes
;
3160 cbEncoded
-= 1 + lenBytes
;
3161 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3162 cbEncoded
-= 2; /* space for 0 TLV */
3163 /* Check the inner length is valid: */
3164 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3168 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3169 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3170 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3172 if (*(pbEncoded
+ decodedLen
) != 0 ||
3173 *(pbEncoded
+ decodedLen
+ 1) != 0)
3175 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3176 *(pbEncoded
+ decodedLen
),
3177 *(pbEncoded
+ decodedLen
+ 1));
3178 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3184 if (ret
&& pcbDecoded
)
3186 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3187 TRACE("decoded %d bytes\n", *pcbDecoded
);
3194 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3195 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3198 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
3199 struct AsnDecodeSequenceItem items
[] = {
3200 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3201 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3202 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3203 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3204 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3205 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3206 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3210 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3211 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3213 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3214 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3215 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3219 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3220 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3221 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3225 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3226 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3230 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3231 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3232 if (ret
&& pvStructInfo
)
3234 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3235 pcbStructInfo
, *pcbStructInfo
);
3238 CRYPT_CONTENT_INFO
*info
;
3240 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3241 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3242 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
3243 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3244 sizeof(CRYPT_CONTENT_INFO
));
3245 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3246 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3247 pcbStructInfo
, NULL
);
3253 SetLastError(STATUS_ACCESS_VIOLATION
);
3259 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3260 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3261 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3264 struct AsnDecodeSequenceItem items
[] = {
3265 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3266 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3267 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3268 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3269 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3271 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3272 CRYPT_AsnDecodePKCSContentInfoInternal
,
3273 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3274 ContentInfo
.pszObjId
), 0 },
3275 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3276 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3277 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3280 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3281 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3286 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3287 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3288 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3292 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3293 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3299 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3300 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3303 *pcbStructInfo
= bytesNeeded
;
3304 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3305 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3307 CERT_ALT_NAME_INFO
*name
;
3309 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3310 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3311 name
= (CERT_ALT_NAME_INFO
*)pvStructInfo
;
3312 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3313 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3314 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3315 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3316 &bytesNeeded
, NULL
);
3322 SetLastError(STATUS_ACCESS_VIOLATION
);
3329 struct PATH_LEN_CONSTRAINT
3331 BOOL fPathLenConstraint
;
3332 DWORD dwPathLenConstraint
;
3335 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3336 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3340 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3342 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3343 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3347 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3349 *pcbStructInfo
= bytesNeeded
;
3351 else if (*pcbStructInfo
< bytesNeeded
)
3353 SetLastError(ERROR_MORE_DATA
);
3354 *pcbStructInfo
= bytesNeeded
;
3359 struct PATH_LEN_CONSTRAINT
*constraint
=
3360 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
3362 *pcbStructInfo
= bytesNeeded
;
3363 size
= sizeof(constraint
->dwPathLenConstraint
);
3364 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3365 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3367 constraint
->fPathLenConstraint
= TRUE
;
3368 TRACE("got an int, dwPathLenConstraint is %d\n",
3369 constraint
->dwPathLenConstraint
);
3371 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3375 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3376 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3380 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3381 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3382 offsetof(CERT_NAME_BLOB
, pbData
) };
3383 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
3385 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3386 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3388 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3389 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3390 entries
? entries
->rgItems
: NULL
);
3391 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3395 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3396 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3397 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3403 struct AsnDecodeSequenceItem items
[] = {
3404 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3405 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3406 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3407 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3408 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3409 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3410 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3411 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3412 sizeof(struct GenericArray
), TRUE
, TRUE
,
3413 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3416 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3417 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3418 pcbStructInfo
, NULL
, NULL
);
3422 SetLastError(STATUS_ACCESS_VIOLATION
);
3429 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3430 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3431 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3437 struct AsnDecodeSequenceItem items
[] = {
3438 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3439 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3440 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3441 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3442 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3445 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3446 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3447 pcbStructInfo
, NULL
, NULL
);
3451 SetLastError(STATUS_ACCESS_VIOLATION
);
3458 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3459 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3462 struct AsnDecodeSequenceItem items
[] = {
3463 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3464 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3465 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3467 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3468 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3469 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3472 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3474 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3475 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3477 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3478 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3479 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3483 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3484 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3488 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3489 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3490 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3491 struct GenericArray
*entries
= pvStructInfo
;
3493 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3494 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3496 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3497 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3498 entries
? entries
->rgItems
: NULL
);
3499 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3503 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3504 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3506 struct AsnDecodeSequenceItem items
[] = {
3507 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3508 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3509 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3510 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3511 CRYPT_AsnDecodePolicyQualifiers
, sizeof(struct GenericArray
), TRUE
,
3512 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3514 CERT_POLICY_INFO
*info
= pvStructInfo
;
3517 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3518 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3520 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3521 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3522 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3526 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3527 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3528 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3532 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3533 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3537 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3538 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3539 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3541 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3542 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3546 SetLastError(STATUS_ACCESS_VIOLATION
);
3552 #define RSA1_MAGIC 0x31415352
3554 struct DECODED_RSA_PUB_KEY
3557 CRYPT_INTEGER_BLOB modulus
;
3560 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3561 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3562 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3568 struct AsnDecodeSequenceItem items
[] = {
3569 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3570 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3571 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3573 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3574 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3576 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3579 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3580 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3584 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3585 decodedKey
->modulus
.cbData
;
3589 *pcbStructInfo
= bytesNeeded
;
3592 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3593 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3596 RSAPUBKEY
*rsaPubKey
;
3598 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3599 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3600 hdr
= (BLOBHEADER
*)pvStructInfo
;
3601 hdr
->bType
= PUBLICKEYBLOB
;
3602 hdr
->bVersion
= CUR_BLOB_VERSION
;
3604 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3605 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3606 sizeof(BLOBHEADER
));
3607 rsaPubKey
->magic
= RSA1_MAGIC
;
3608 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3609 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3610 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3611 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3612 decodedKey
->modulus
.cbData
);
3614 LocalFree(decodedKey
);
3619 SetLastError(STATUS_ACCESS_VIOLATION
);
3626 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3627 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3631 DWORD bytesNeeded
, dataLen
;
3633 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3634 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3636 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3638 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3640 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3641 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3643 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3645 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3647 *pcbStructInfo
= bytesNeeded
;
3648 else if (*pcbStructInfo
< bytesNeeded
)
3650 SetLastError(ERROR_MORE_DATA
);
3651 *pcbStructInfo
= bytesNeeded
;
3656 CRYPT_DATA_BLOB
*blob
;
3658 *pcbStructInfo
= bytesNeeded
;
3659 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3660 blob
->cbData
= dataLen
;
3661 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3662 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3665 assert(blob
->pbData
);
3667 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3675 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3676 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3677 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3681 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3682 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3690 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3693 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3695 SetLastError(CRYPT_E_ASN1_BADTAG
);
3698 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3699 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3702 *pcbStructInfo
= bytesNeeded
;
3703 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3704 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3706 CRYPT_DATA_BLOB
*blob
;
3708 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3709 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3710 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3711 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3712 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3713 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3714 &bytesNeeded
, NULL
);
3720 SetLastError(STATUS_ACCESS_VIOLATION
);
3727 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3728 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3731 DWORD bytesNeeded
, dataLen
;
3732 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3734 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3735 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3737 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3739 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3740 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3742 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3744 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3746 *pcbStructInfo
= bytesNeeded
;
3747 else if (*pcbStructInfo
< bytesNeeded
)
3749 *pcbStructInfo
= bytesNeeded
;
3750 SetLastError(ERROR_MORE_DATA
);
3755 CRYPT_BIT_BLOB
*blob
;
3757 *pcbStructInfo
= bytesNeeded
;
3758 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3759 blob
->cbData
= dataLen
- 1;
3760 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3761 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3763 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3767 assert(blob
->pbData
);
3770 BYTE mask
= 0xff << blob
->cUnusedBits
;
3772 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3774 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3782 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3783 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3784 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3788 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3789 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3797 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3800 else if (pbEncoded
[0] != ASN_BITSTRING
)
3802 SetLastError(CRYPT_E_ASN1_BADTAG
);
3805 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3806 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3809 *pcbStructInfo
= bytesNeeded
;
3810 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3811 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3813 CRYPT_BIT_BLOB
*blob
;
3815 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3816 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3817 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3818 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3819 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3820 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3821 &bytesNeeded
, NULL
);
3827 SetLastError(STATUS_ACCESS_VIOLATION
);
3831 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3835 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3836 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3837 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3840 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3841 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3842 DWORD size
= sizeof(buf
);
3844 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3845 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
3850 *pcbStructInfo
= sizeof(int);
3851 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3855 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3857 /* initialize to a negative value to sign-extend */
3862 for (i
= 0; i
< blob
->cbData
; i
++)
3865 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3867 memcpy(pvStructInfo
, &val
, sizeof(int));
3870 else if (GetLastError() == ERROR_MORE_DATA
)
3871 SetLastError(CRYPT_E_ASN1_LARGE
);
3875 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3876 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3877 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3887 SetLastError(CRYPT_E_ASN1_EOD
);
3890 else if (pbEncoded
[0] != ASN_INTEGER
)
3892 SetLastError(CRYPT_E_ASN1_BADTAG
);
3896 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3897 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3901 *pcbStructInfo
= bytesNeeded
;
3902 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3903 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3905 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3906 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3907 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3908 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3909 &bytesNeeded
, NULL
);
3915 SetLastError(STATUS_ACCESS_VIOLATION
);
3922 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
3923 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3927 DWORD bytesNeeded
, dataLen
;
3929 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3931 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3933 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3935 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3937 *pcbStructInfo
= bytesNeeded
;
3938 else if (*pcbStructInfo
< bytesNeeded
)
3940 *pcbStructInfo
= bytesNeeded
;
3941 SetLastError(ERROR_MORE_DATA
);
3946 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3948 *pcbStructInfo
= bytesNeeded
;
3949 blob
->cbData
= dataLen
;
3950 assert(blob
->pbData
);
3955 for (i
= 0; i
< blob
->cbData
; i
++)
3957 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3966 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3967 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3968 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3976 if (pbEncoded
[0] != ASN_INTEGER
)
3978 SetLastError(CRYPT_E_ASN1_BADTAG
);
3982 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3983 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3987 *pcbStructInfo
= bytesNeeded
;
3988 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3989 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3991 CRYPT_INTEGER_BLOB
*blob
;
3993 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3994 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3995 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3996 blob
->pbData
= (BYTE
*)pvStructInfo
+
3997 sizeof(CRYPT_INTEGER_BLOB
);
3998 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3999 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4000 &bytesNeeded
, NULL
);
4006 SetLastError(STATUS_ACCESS_VIOLATION
);
4013 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4014 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4019 if (pbEncoded
[0] == ASN_INTEGER
)
4021 DWORD bytesNeeded
, dataLen
;
4023 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4025 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4028 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4029 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4031 *pcbStructInfo
= bytesNeeded
;
4032 else if (*pcbStructInfo
< bytesNeeded
)
4034 *pcbStructInfo
= bytesNeeded
;
4035 SetLastError(ERROR_MORE_DATA
);
4040 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
4042 *pcbStructInfo
= bytesNeeded
;
4043 blob
->cbData
= dataLen
;
4044 assert(blob
->pbData
);
4045 /* remove leading zero byte if it exists */
4046 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4055 for (i
= 0; i
< blob
->cbData
; i
++)
4057 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4066 SetLastError(CRYPT_E_ASN1_BADTAG
);
4072 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4073 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4074 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4082 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4083 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4086 *pcbStructInfo
= bytesNeeded
;
4087 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4088 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4090 CRYPT_INTEGER_BLOB
*blob
;
4092 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4093 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4094 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
4095 blob
->pbData
= (BYTE
*)pvStructInfo
+
4096 sizeof(CRYPT_INTEGER_BLOB
);
4097 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4098 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4099 &bytesNeeded
, NULL
);
4105 SetLastError(STATUS_ACCESS_VIOLATION
);
4112 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4113 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4114 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4120 *pcbStructInfo
= sizeof(int);
4125 if (pbEncoded
[0] == ASN_ENUMERATED
)
4127 unsigned int val
= 0, i
;
4131 SetLastError(CRYPT_E_ASN1_EOD
);
4134 else if (pbEncoded
[1] == 0)
4136 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4141 /* A little strange looking, but we have to accept a sign byte:
4142 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4143 * assuming a small length is okay here, it has to be in short
4146 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4148 SetLastError(CRYPT_E_ASN1_LARGE
);
4151 for (i
= 0; i
< pbEncoded
[1]; i
++)
4154 val
|= pbEncoded
[2 + i
];
4156 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4157 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4159 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4160 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4161 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4167 SetLastError(CRYPT_E_ASN1_BADTAG
);
4173 SetLastError(STATUS_ACCESS_VIOLATION
);
4180 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4183 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4188 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4190 if (!isdigit(*(pbEncoded))) \
4192 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4198 (word) += *(pbEncoded)++ - '0'; \
4203 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4204 SYSTEMTIME
*sysTime
)
4208 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4210 WORD hours
, minutes
= 0;
4211 BYTE sign
= *pbEncoded
++;
4214 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4215 if (ret
&& hours
>= 24)
4217 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4222 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4223 if (ret
&& minutes
>= 60)
4225 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4233 sysTime
->wHour
+= hours
;
4234 sysTime
->wMinute
+= minutes
;
4238 if (hours
> sysTime
->wHour
)
4241 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4244 sysTime
->wHour
-= hours
;
4245 if (minutes
> sysTime
->wMinute
)
4248 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4251 sysTime
->wMinute
-= minutes
;
4258 #define MIN_ENCODED_TIME_LENGTH 10
4260 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4261 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4266 if (pbEncoded
[0] == ASN_UTCTIME
)
4269 SetLastError(CRYPT_E_ASN1_EOD
);
4270 else if (pbEncoded
[1] > 0x7f)
4272 /* long-form date strings really can't be valid */
4273 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4277 SYSTEMTIME sysTime
= { 0 };
4278 BYTE len
= pbEncoded
[1];
4280 if (len
< MIN_ENCODED_TIME_LENGTH
)
4281 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4286 *pcbDecoded
= 2 + len
;
4288 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4289 if (sysTime
.wYear
>= 50)
4290 sysTime
.wYear
+= 1900;
4292 sysTime
.wYear
+= 2000;
4293 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4294 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4295 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4296 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4299 if (len
>= 2 && isdigit(*pbEncoded
) &&
4300 isdigit(*(pbEncoded
+ 1)))
4301 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4303 else if (isdigit(*pbEncoded
))
4304 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4307 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4313 *pcbStructInfo
= sizeof(FILETIME
);
4314 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4316 ret
= SystemTimeToFileTime(&sysTime
,
4317 (FILETIME
*)pvStructInfo
);
4323 SetLastError(CRYPT_E_ASN1_BADTAG
);
4327 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4328 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4329 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4337 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4338 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4342 *pcbStructInfo
= bytesNeeded
;
4343 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4344 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4346 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4347 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4348 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4349 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4350 &bytesNeeded
, NULL
);
4356 SetLastError(STATUS_ACCESS_VIOLATION
);
4362 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4363 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4368 if (pbEncoded
[0] == ASN_GENERALTIME
)
4371 SetLastError(CRYPT_E_ASN1_EOD
);
4372 else if (pbEncoded
[1] > 0x7f)
4374 /* long-form date strings really can't be valid */
4375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4379 BYTE len
= pbEncoded
[1];
4381 if (len
< MIN_ENCODED_TIME_LENGTH
)
4382 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4385 SYSTEMTIME sysTime
= { 0 };
4389 *pcbDecoded
= 2 + len
;
4391 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4392 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4393 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4394 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4397 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4400 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4402 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4409 /* workaround macro weirdness */
4410 digits
= min(len
, 3);
4411 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4412 sysTime
.wMilliseconds
);
4415 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4421 *pcbStructInfo
= sizeof(FILETIME
);
4422 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4424 ret
= SystemTimeToFileTime(&sysTime
,
4425 (FILETIME
*)pvStructInfo
);
4431 SetLastError(CRYPT_E_ASN1_BADTAG
);
4435 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4436 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4440 InternalDecodeFunc decode
= NULL
;
4442 if (pbEncoded
[0] == ASN_UTCTIME
)
4443 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4444 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4445 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4447 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4448 pcbStructInfo
, pcbDecoded
);
4451 SetLastError(CRYPT_E_ASN1_BADTAG
);
4457 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4458 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4459 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4467 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4468 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4472 *pcbStructInfo
= bytesNeeded
;
4473 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4474 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4476 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4477 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4478 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4479 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4480 &bytesNeeded
, NULL
);
4486 SetLastError(STATUS_ACCESS_VIOLATION
);
4493 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4494 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4495 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4501 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4503 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4505 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4510 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4511 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4513 ptr
= pbEncoded
+ 1 + lenBytes
;
4514 remainingLen
= dataLen
;
4515 while (ret
&& remainingLen
)
4519 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4522 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4524 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4525 ptr
+= 1 + nextLenBytes
+ nextLen
;
4526 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4527 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4528 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4534 CRYPT_SEQUENCE_OF_ANY
*seq
;
4539 *pcbStructInfo
= bytesNeeded
;
4540 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4541 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4543 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4544 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4545 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
4546 seq
->cValue
= cValue
;
4547 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4549 nextPtr
= (BYTE
*)seq
->rgValue
+
4550 cValue
* sizeof(CRYPT_DER_BLOB
);
4551 ptr
= pbEncoded
+ 1 + lenBytes
;
4552 remainingLen
= dataLen
;
4554 while (ret
&& remainingLen
)
4558 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4561 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4563 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4565 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4566 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4569 seq
->rgValue
[i
].pbData
= nextPtr
;
4570 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4572 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4574 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4575 ptr
+= 1 + nextLenBytes
+ nextLen
;
4585 SetLastError(CRYPT_E_ASN1_BADTAG
);
4591 SetLastError(STATUS_ACCESS_VIOLATION
);
4598 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4599 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4604 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4606 DWORD bytesNeeded
, dataLen
;
4608 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4610 struct AsnArrayDescriptor arrayDesc
= {
4611 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
4612 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4613 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4614 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4619 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4620 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4621 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
4622 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4623 * as the sizeof(struct GenericArray), so don't include it in the
4624 * total bytes needed.
4626 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4627 sizeof(CERT_ALT_NAME_INFO
);
4630 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4632 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4634 *pcbStructInfo
= bytesNeeded
;
4635 else if (*pcbStructInfo
< bytesNeeded
)
4637 *pcbStructInfo
= bytesNeeded
;
4638 SetLastError(ERROR_MORE_DATA
);
4643 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
4645 *pcbStructInfo
= bytesNeeded
;
4648 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4649 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4650 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4651 0, NULL
, &name
->u
.FullName
, &nameLen
, NULL
,
4652 name
->u
.FullName
.rgAltEntry
);
4655 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4661 SetLastError(CRYPT_E_ASN1_BADTAG
);
4667 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4668 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4670 struct AsnDecodeSequenceItem items
[] = {
4671 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4672 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4673 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4674 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4675 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4676 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4677 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4678 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4679 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4680 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4682 CRL_DIST_POINT
*point
= (CRL_DIST_POINT
*)pvStructInfo
;
4685 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4686 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4687 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
4691 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4692 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4693 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4697 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4698 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4702 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4703 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4704 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4706 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4707 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4711 SetLastError(STATUS_ACCESS_VIOLATION
);
4718 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
4719 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4720 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4724 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4725 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4729 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4730 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
4732 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4733 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4737 SetLastError(STATUS_ACCESS_VIOLATION
);
4744 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4745 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4746 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4750 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4751 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4755 struct AsnDecodeSequenceItem items
[] = {
4756 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4757 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4758 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4759 offsetof(CRL_ISSUING_DIST_POINT
,
4760 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4761 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4762 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4764 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4765 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4767 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4768 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4769 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4770 OnlySomeReasonFlags
.pbData
), 0 },
4771 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4772 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4775 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4776 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4777 pcbStructInfo
, NULL
, NULL
);
4781 SetLastError(STATUS_ACCESS_VIOLATION
);
4788 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
4789 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4794 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4795 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4799 SetLastError(CRYPT_E_ASN1_EOD
);
4802 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
4804 SetLastError(CRYPT_E_ASN1_BADTAG
);
4807 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4808 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
4809 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
4811 if (ret
&& pvStructInfo
)
4812 *(BOOL
*)pvStructInfo
= TRUE
;
4813 TRACE("returning %d\n", ret
);
4817 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
4818 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4822 struct AsnDecodeSequenceItem items
[] = {
4823 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
4824 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
4825 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
4826 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
4827 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
4828 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
4829 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
4832 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)pvStructInfo
;
4834 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4835 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4837 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4838 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4839 pcbDecoded
, subtree
? (BYTE
*)subtree
->Base
.u
.pwszURL
: NULL
);
4842 TRACE("%d\n", *pcbDecoded
);
4843 if (*pcbDecoded
< cbEncoded
)
4844 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
4845 *(pbEncoded
+ *pcbDecoded
+ 1));
4847 TRACE("returning %d\n", ret
);
4851 static BOOL
CRYPT_AsnDecodeSubtreeArray(const BYTE
*pbEncoded
,
4852 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4856 struct AsnArrayDescriptor arrayDesc
= { 0,
4857 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4858 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4859 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4861 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4862 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4864 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4865 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4866 array
? array
->rgItems
: NULL
);
4871 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
4872 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4873 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4877 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4878 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4882 struct AsnDecodeSequenceItem items
[] = {
4883 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4884 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
4885 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4886 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
4887 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
4888 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4889 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4890 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
4893 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4894 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4895 pcbStructInfo
, NULL
, NULL
);
4899 SetLastError(STATUS_ACCESS_VIOLATION
);
4905 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
4906 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4910 struct AsnDecodeSequenceItem items
[] = {
4911 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4912 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4914 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4915 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4916 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4918 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
4919 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
4921 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4922 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4924 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4925 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4926 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4927 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4929 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4932 TRACE("returning %d\n", ret
);
4936 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4937 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4940 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4941 struct AsnDecodeSequenceItem items
[] = {
4942 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4943 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4944 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4945 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4946 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4947 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4948 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4949 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4950 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4951 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4952 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4953 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4954 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4955 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4956 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4957 HashEncryptionAlgorithm
.pszObjId
), 0 },
4958 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4959 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4960 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4961 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4962 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4963 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4964 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4968 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4969 pvStructInfo
, *pcbStructInfo
);
4971 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4972 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4973 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
4977 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4978 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4979 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4983 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4984 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4988 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4989 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4990 if (ret
&& pvStructInfo
)
4992 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4993 pcbStructInfo
, *pcbStructInfo
);
4996 CMSG_SIGNER_INFO
*info
;
4998 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4999 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5000 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
5001 info
->Issuer
.pbData
= ((BYTE
*)info
+
5002 sizeof(CMSG_SIGNER_INFO
));
5003 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5004 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5005 pcbStructInfo
, NULL
);
5011 SetLastError(STATUS_ACCESS_VIOLATION
);
5014 TRACE("returning %d\n", ret
);
5018 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5019 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5022 CERT_ID
*id
= (CERT_ID
*)pvStructInfo
;
5025 if (*pbEncoded
== ASN_SEQUENCEOF
)
5027 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5028 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5032 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5033 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5034 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5035 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5037 *pcbStructInfo
= sizeof(CERT_ID
);
5040 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5042 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5043 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5047 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5048 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5049 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5050 sizeof(CRYPT_DATA_BLOB
);
5052 *pcbStructInfo
= sizeof(CERT_ID
);
5056 SetLastError(CRYPT_E_ASN1_BADTAG
);
5060 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5061 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5064 CMSG_CMS_SIGNER_INFO
*info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
5065 struct AsnDecodeSequenceItem items
[] = {
5066 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5067 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5068 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5069 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5070 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5071 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5072 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5073 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5074 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5075 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5076 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5077 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5078 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5079 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5080 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5081 HashEncryptionAlgorithm
.pszObjId
), 0 },
5082 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5083 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5084 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5085 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5086 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5087 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5088 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5092 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5093 pvStructInfo
, *pcbStructInfo
);
5095 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5096 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5097 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5101 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5102 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5103 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5107 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5108 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5112 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5113 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5114 if (ret
&& pvStructInfo
)
5116 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5117 pcbStructInfo
, *pcbStructInfo
);
5120 CMSG_CMS_SIGNER_INFO
*info
;
5122 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5123 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5124 info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
5125 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5126 sizeof(CMSG_CMS_SIGNER_INFO
));
5127 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5128 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5129 pcbStructInfo
, NULL
);
5135 SetLastError(STATUS_ACCESS_VIOLATION
);
5138 TRACE("returning %d\n", ret
);
5142 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5143 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5146 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5147 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5148 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5149 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
5151 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5152 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5154 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
5155 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
5156 array
? array
->rgItems
: NULL
);
5160 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5161 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5162 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5165 struct AsnDecodeSequenceItem items
[] = {
5166 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5167 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5168 /* Placeholder for the hash algorithms - redundant with those in the
5169 * signers, so just ignore them.
5171 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5172 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5173 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5174 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5175 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5176 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5177 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
5178 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5179 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5180 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
5181 sizeof(struct GenericArray
), TRUE
, TRUE
,
5182 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5183 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5184 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
5185 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5188 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5189 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5191 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5192 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5194 TRACE("returning %d\n", ret
);
5198 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5199 LPCSTR lpszStructType
)
5201 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5203 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5204 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5206 SetLastError(ERROR_FILE_NOT_FOUND
);
5209 if (!HIWORD(lpszStructType
))
5211 switch (LOWORD(lpszStructType
))
5213 case LOWORD(X509_CERT
):
5214 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5216 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5217 decodeFunc
= CRYPT_AsnDecodeCert
;
5219 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5220 decodeFunc
= CRYPT_AsnDecodeCRL
;
5222 case LOWORD(X509_EXTENSIONS
):
5223 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5225 case LOWORD(X509_NAME_VALUE
):
5226 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5228 case LOWORD(X509_NAME
):
5229 decodeFunc
= CRYPT_AsnDecodeName
;
5231 case LOWORD(X509_PUBLIC_KEY_INFO
):
5232 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5234 case LOWORD(X509_AUTHORITY_KEY_ID
):
5235 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5237 case LOWORD(X509_ALTERNATE_NAME
):
5238 decodeFunc
= CRYPT_AsnDecodeAltName
;
5240 case LOWORD(X509_BASIC_CONSTRAINTS
):
5241 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5243 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5244 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5246 case LOWORD(X509_CERT_POLICIES
):
5247 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5249 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5250 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5252 case LOWORD(X509_UNICODE_NAME
):
5253 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5255 case LOWORD(PKCS_ATTRIBUTE
):
5256 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5258 case LOWORD(X509_UNICODE_NAME_VALUE
):
5259 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5261 case LOWORD(X509_OCTET_STRING
):
5262 decodeFunc
= CRYPT_AsnDecodeOctets
;
5264 case LOWORD(X509_BITS
):
5265 case LOWORD(X509_KEY_USAGE
):
5266 decodeFunc
= CRYPT_AsnDecodeBits
;
5268 case LOWORD(X509_INTEGER
):
5269 decodeFunc
= CRYPT_AsnDecodeInt
;
5271 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5272 decodeFunc
= CRYPT_AsnDecodeInteger
;
5274 case LOWORD(X509_MULTI_BYTE_UINT
):
5275 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5277 case LOWORD(X509_ENUMERATED
):
5278 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5280 case LOWORD(X509_CHOICE_OF_TIME
):
5281 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5283 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5284 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5286 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5287 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5289 case LOWORD(PKCS_CONTENT_INFO
):
5290 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5292 case LOWORD(X509_SEQUENCE_OF_ANY
):
5293 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5295 case LOWORD(PKCS_UTC_TIME
):
5296 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5298 case LOWORD(X509_CRL_DIST_POINTS
):
5299 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5301 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5302 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5304 case LOWORD(PKCS_CTL
):
5305 decodeFunc
= CRYPT_AsnDecodeCTL
;
5307 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5308 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5310 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5311 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5313 case LOWORD(PKCS_ATTRIBUTES
):
5314 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5316 case LOWORD(X509_ISSUING_DIST_POINT
):
5317 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5319 case LOWORD(X509_NAME_CONSTRAINTS
):
5320 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5322 case LOWORD(PKCS7_SIGNER_INFO
):
5323 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5325 case LOWORD(CMS_SIGNER_INFO
):
5326 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5330 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5331 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5332 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5333 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5334 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5335 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5336 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5337 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5338 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5339 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5340 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5341 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5342 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5343 decodeFunc
= CRYPT_AsnDecodeBits
;
5344 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5345 decodeFunc
= CRYPT_AsnDecodeOctets
;
5346 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5347 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5348 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5349 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5350 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5351 decodeFunc
= CRYPT_AsnDecodeAltName
;
5352 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5353 decodeFunc
= CRYPT_AsnDecodeAltName
;
5354 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5355 decodeFunc
= CRYPT_AsnDecodeAltName
;
5356 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5357 decodeFunc
= CRYPT_AsnDecodeAltName
;
5358 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5359 decodeFunc
= CRYPT_AsnDecodeAltName
;
5360 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5361 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5362 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5363 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5364 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5365 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5366 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5367 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5368 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5369 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5370 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5371 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5372 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5373 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5374 else if (!strcmp(lpszStructType
, szOID_CTL
))
5375 decodeFunc
= CRYPT_AsnDecodeCTL
;
5379 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5380 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5382 static HCRYPTOIDFUNCSET set
= NULL
;
5383 CryptDecodeObjectFunc decodeFunc
= NULL
;
5386 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5387 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5388 (void **)&decodeFunc
, hFunc
);
5392 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5393 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5395 static HCRYPTOIDFUNCSET set
= NULL
;
5396 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5399 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5400 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5401 (void **)&decodeFunc
, hFunc
);
5405 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5406 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5407 DWORD
*pcbStructInfo
)
5410 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5411 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5412 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5414 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5415 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5416 pvStructInfo
, pcbStructInfo
);
5418 if (!pvStructInfo
&& !pcbStructInfo
)
5420 SetLastError(ERROR_INVALID_PARAMETER
);
5423 if (cbEncoded
> MAX_ENCODED_LEN
)
5425 SetLastError(CRYPT_E_ASN1_LARGE
);
5429 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5432 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5433 debugstr_a(lpszStructType
));
5434 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5435 lpszStructType
, &hFunc
);
5436 if (!pCryptDecodeObject
)
5437 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5438 lpszStructType
, &hFunc
);
5440 if (pCryptDecodeObject
)
5441 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5442 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5443 else if (pCryptDecodeObjectEx
)
5444 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5445 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5446 pvStructInfo
, pcbStructInfo
);
5448 CryptFreeOIDFunctionAddress(hFunc
, 0);
5449 TRACE_(crypt
)("returning %d\n", ret
);
5453 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5454 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5455 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5458 CryptDecodeObjectExFunc decodeFunc
;
5459 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5461 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5462 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5463 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5465 if (!pvStructInfo
&& !pcbStructInfo
)
5467 SetLastError(ERROR_INVALID_PARAMETER
);
5470 if (cbEncoded
> MAX_ENCODED_LEN
)
5472 SetLastError(CRYPT_E_ASN1_LARGE
);
5476 SetLastError(NOERROR
);
5477 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5478 *(BYTE
**)pvStructInfo
= NULL
;
5479 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5482 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5483 debugstr_a(lpszStructType
));
5484 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5488 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5489 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5492 CryptDecodeObjectFunc pCryptDecodeObject
=
5493 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5495 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5496 * directly, as that could cause an infinite loop.
5498 if (pCryptDecodeObject
)
5500 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5502 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5503 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5504 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5505 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5506 ret
= pCryptDecodeObject(dwCertEncodingType
,
5507 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5508 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5511 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5512 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5516 CryptFreeOIDFunctionAddress(hFunc
, 0);
5517 TRACE_(crypt
)("returning %d\n", ret
);