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