2 * Copyright 2005-2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
67 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
68 DWORD
, DWORD
, void *, DWORD
*);
69 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
70 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
76 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
78 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
82 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
88 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
92 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
93 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
94 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
97 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
99 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
100 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
101 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
102 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
103 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
104 * member has been initialized, doesn't do exception handling, and doesn't do
105 * memory allocation. Also doesn't check tag, assumes the caller has checked
108 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
111 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
112 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
113 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
115 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
116 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
119 /* Gets the number of length bytes from the given (leading) length byte */
120 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
122 /* Helper function to get the encoded length of the data starting at pbEncoded,
123 * where pbEncoded[0] is the tag. If the data are too short to contain a
124 * length or if the length is too large for cbEncoded, sets an appropriate
125 * error code and returns FALSE. If the encoded length is unknown due to
126 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
128 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
135 SetLastError(CRYPT_E_ASN1_CORRUPT
);
138 else if (pbEncoded
[1] <= 0x7f)
140 if (pbEncoded
[1] + 1 > cbEncoded
)
142 SetLastError(CRYPT_E_ASN1_EOD
);
151 else if (pbEncoded
[1] == 0x80)
153 *len
= CMSG_INDEFINITE_LENGTH
;
158 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
160 if (lenLen
> sizeof(DWORD
) + 1)
162 SetLastError(CRYPT_E_ASN1_LARGE
);
165 else if (lenLen
+ 2 > cbEncoded
)
167 SetLastError(CRYPT_E_ASN1_CORRUPT
);
180 if (out
+ lenLen
+ 1 > cbEncoded
)
182 SetLastError(CRYPT_E_ASN1_EOD
);
195 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
196 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
200 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
201 *len
== CMSG_INDEFINITE_LENGTH
)
203 SetLastError(CRYPT_E_ASN1_CORRUPT
);
209 /* Helper function to check *pcbStructInfo, set it to the required size, and
210 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
211 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
212 * pointer to the newly allocated memory.
214 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
215 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
220 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
222 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
223 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
225 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
226 if (!*(BYTE
**)pvStructInfo
)
229 *pcbStructInfo
= bytesNeeded
;
231 else if (*pcbStructInfo
< bytesNeeded
)
233 *pcbStructInfo
= bytesNeeded
;
234 SetLastError(ERROR_MORE_DATA
);
238 *pcbStructInfo
= bytesNeeded
;
242 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
244 if (pDecodePara
&& pDecodePara
->pfnFree
)
245 pDecodePara
->pfnFree(pv
);
250 /* Helper function to check *pcbStructInfo and set it to the required size.
251 * Assumes pvStructInfo is not NULL.
253 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
257 if (*pcbStructInfo
< bytesNeeded
)
259 *pcbStructInfo
= bytesNeeded
;
260 SetLastError(ERROR_MORE_DATA
);
265 *pcbStructInfo
= bytesNeeded
;
272 * The expected tag of the item. If tag is 0, decodeFunc is called
273 * regardless of the tag value seen.
275 * A sequence is decoded into a struct. The offset member is the
276 * offset of this item within that struct.
278 * The decoder function to use. If this is NULL, then the member isn't
279 * decoded, but minSize space is reserved for it.
281 * The minimum amount of space occupied after decoding. You must set this.
283 * If true, and the tag doesn't match the expected tag for this item,
284 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
285 * filled with 0 for this member.
286 * hasPointer, pointerOffset:
287 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
288 * the offset within the struct of the data pointer (or to the
289 * first data pointer, if more than one exist).
291 * Used by CRYPT_AsnDecodeSequence, not for your use.
293 struct AsnDecodeSequenceItem
297 InternalDecodeFunc decodeFunc
;
305 /* Decodes the items in a sequence, where the items are described in items,
306 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
307 * pvStructInfo. nextData is a pointer to the memory location at which the
308 * first decoded item with a dynamic pointer should point.
309 * Upon decoding, *cbDecoded is the total number of bytes decoded.
310 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
312 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
313 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
314 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
317 DWORD i
, decoded
= 0;
318 const BYTE
*ptr
= pbEncoded
;
320 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
321 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
323 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
325 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
329 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
330 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
332 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
334 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
336 DWORD itemEncodedLen
;
338 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
339 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
341 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
342 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
344 TRACE("Setting next pointer to %p\n",
346 *(BYTE
**)((BYTE
*)pvStructInfo
+
347 items
[i
].pointerOffset
) = nextData
;
349 if (items
[i
].decodeFunc
)
354 TRACE("decoding item %d\n", i
);
356 TRACE("sizing item %d\n", i
);
357 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
358 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
359 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
360 : NULL
, &items
[i
].size
, &itemDecoded
);
363 /* Account for alignment padding */
364 if (items
[i
].size
% sizeof(DWORD_PTR
))
365 items
[i
].size
+= sizeof(DWORD_PTR
) -
366 items
[i
].size
% sizeof(DWORD_PTR
);
367 TRACE("item %d size: %d\n", i
, items
[i
].size
);
368 if (nextData
&& items
[i
].hasPointer
&&
369 items
[i
].size
> items
[i
].minSize
)
370 nextData
+= items
[i
].size
- items
[i
].minSize
;
371 if (itemDecoded
> itemEncodedLen
)
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded
, itemEncodedLen
);
375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
380 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
382 if (itemDecoded
> itemEncodedLen
- 2 ||
383 *(ptr
+ itemDecoded
) != 0 ||
384 *(ptr
+ itemDecoded
+ 1) != 0)
386 TRACE("expected 0 TLV\n");
387 SetLastError(CRYPT_E_ASN1_CORRUPT
);
396 decoded
+= itemDecoded
;
397 TRACE("item %d: decoded %d bytes\n", i
,
402 else if (items
[i
].optional
&&
403 GetLastError() == CRYPT_E_ASN1_BADTAG
)
405 TRACE("skipping optional item %d\n", i
);
406 items
[i
].size
= items
[i
].minSize
;
407 SetLastError(NOERROR
);
411 TRACE("item %d failed: %08x\n", i
,
414 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
416 ERR("can't use indefinite length encoding without a decoder\n");
417 SetLastError(CRYPT_E_ASN1_CORRUPT
);
422 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
423 ptr
+= itemEncodedLen
;
424 decoded
+= itemEncodedLen
;
425 items
[i
].size
= items
[i
].minSize
;
428 else if (items
[i
].optional
)
430 TRACE("skipping optional item %d\n", i
);
431 items
[i
].size
= items
[i
].minSize
;
435 TRACE("item %d: tag %02x doesn't match expected %02x\n",
436 i
, ptr
[0], items
[i
].tag
);
437 SetLastError(CRYPT_E_ASN1_BADTAG
);
442 else if (items
[i
].optional
)
444 TRACE("missing optional item %d, skipping\n", i
);
445 items
[i
].size
= items
[i
].minSize
;
449 TRACE("not enough bytes for item %d, failing\n", i
);
450 SetLastError(CRYPT_E_ASN1_CORRUPT
);
455 *cbDecoded
= decoded
;
456 TRACE("returning %d\n", ret
);
460 /* This decodes an arbitrary sequence into a contiguous block of memory
461 * (basically, a struct.) Each element being decoded is described by a struct
462 * AsnDecodeSequenceItem, see above.
463 * startingPointer is an optional pointer to the first place where dynamic
464 * data will be stored. If you know the starting offset, you may pass it
465 * here. Otherwise, pass NULL, and one will be inferred from the items.
467 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
468 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
469 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
470 DWORD
*pcbDecoded
, void *startingPointer
)
474 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
475 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
480 SetLastError(CRYPT_E_ASN1_EOD
);
483 if (pbEncoded
[0] == ASN_SEQUENCE
)
487 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
489 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
490 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
491 BOOL indefinite
= FALSE
;
493 cbEncoded
-= 1 + lenBytes
;
494 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
499 else if (cbEncoded
< dataLen
)
501 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
503 SetLastError(CRYPT_E_ASN1_CORRUPT
);
508 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
509 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
510 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
512 if (cbDecoded
> cbEncoded
- 2)
514 /* Not enough space for 0 TLV */
515 SetLastError(CRYPT_E_ASN1_CORRUPT
);
518 else if (*(ptr
+ cbDecoded
) != 0 ||
519 *(ptr
+ cbDecoded
+ 1) != 0)
521 TRACE("expected 0 TLV\n");
522 SetLastError(CRYPT_E_ASN1_CORRUPT
);
529 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
531 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
533 SetLastError(CRYPT_E_ASN1_CORRUPT
);
538 DWORD i
, bytesNeeded
= 0, structSize
= 0;
540 for (i
= 0; i
< cItem
; i
++)
542 bytesNeeded
+= items
[i
].size
;
543 structSize
+= items
[i
].minSize
;
546 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
548 *pcbStructInfo
= bytesNeeded
;
549 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
550 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
554 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
555 pvStructInfo
= *(BYTE
**)pvStructInfo
;
557 nextData
= (BYTE
*)startingPointer
;
559 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
560 memset(pvStructInfo
, 0, structSize
);
561 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
562 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
564 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
565 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
572 SetLastError(CRYPT_E_ASN1_BADTAG
);
575 TRACE("returning %d (%08x)\n", ret
, GetLastError());
580 * The expected tag of the entire encoded array (usually a variant
581 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
582 * regardless of the tag seen.
584 * used to decode each item in the array
586 * is the minimum size of each decoded item
588 * indicates whether each item has a dynamic pointer
590 * indicates the offset within itemSize at which the pointer exists
592 struct AsnArrayDescriptor
595 InternalDecodeFunc decodeFunc
;
601 struct AsnArrayItemSize
607 /* Decodes an array of like types into a struct GenericArray.
608 * The layout and decoding of the array are described by a struct
609 * AsnArrayDescriptor.
611 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
612 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
613 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
614 DWORD
*pcbDecoded
, void *startingPointer
)
618 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
619 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
622 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
626 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
628 DWORD bytesNeeded
, cItems
= 0, decoded
;
629 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
630 /* There can be arbitrarily many items, but there is often only one.
632 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
634 decoded
= 1 + lenBytes
;
635 bytesNeeded
= sizeof(struct GenericArray
);
639 BOOL doneDecoding
= FALSE
;
641 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
643 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
650 SetLastError(CRYPT_E_ASN1_CORRUPT
);
657 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
661 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
663 /* Each item decoded may not tolerate extraneous bytes,
664 * so get the length of the next element if known.
666 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
667 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
669 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
670 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
672 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
676 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
677 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
682 if (itemSizes
!= &itemSize
)
683 itemSizes
= CryptMemRealloc(itemSizes
,
684 cItems
* sizeof(struct AsnArrayItemSize
));
689 cItems
* sizeof(struct AsnArrayItemSize
));
691 memcpy(itemSizes
, &itemSize
,
696 decoded
+= itemDecoded
;
697 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
698 itemSizes
[cItems
- 1].size
= size
;
711 *pcbDecoded
= decoded
;
713 *pcbStructInfo
= bytesNeeded
;
714 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
715 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
720 struct GenericArray
*array
;
722 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
723 pvStructInfo
= *(BYTE
**)pvStructInfo
;
724 array
= (struct GenericArray
*)pvStructInfo
;
725 array
->cItems
= cItems
;
727 array
->rgItems
= startingPointer
;
729 array
->rgItems
= (BYTE
*)array
+
730 sizeof(struct GenericArray
);
731 nextData
= array
->rgItems
+
732 array
->cItems
* arrayDesc
->itemSize
;
733 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
734 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
739 if (arrayDesc
->hasPointer
)
740 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
741 + arrayDesc
->pointerOffset
) = nextData
;
742 ret
= arrayDesc
->decodeFunc(ptr
,
743 itemSizes
[i
].encodedLen
,
744 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
745 array
->rgItems
+ i
* arrayDesc
->itemSize
,
746 &itemSizes
[i
].size
, &itemDecoded
);
749 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
753 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
754 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
757 if (itemSizes
!= &itemSize
)
758 CryptMemFree(itemSizes
);
763 SetLastError(CRYPT_E_ASN1_BADTAG
);
769 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
770 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
771 * to CRYPT_E_ASN1_CORRUPT.
772 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
775 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
776 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
781 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
783 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
784 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
786 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
787 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
790 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
792 *pcbStructInfo
= bytesNeeded
;
793 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
795 CRYPT_DER_BLOB
*blob
;
797 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
798 pvStructInfo
= *(BYTE
**)pvStructInfo
;
799 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
800 blob
->cbData
= 1 + lenBytes
+ dataLen
;
803 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
804 blob
->pbData
= (BYTE
*)pbEncoded
;
807 assert(blob
->pbData
);
808 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
813 SetLastError(CRYPT_E_ASN1_CORRUPT
);
821 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
822 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
823 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
828 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
829 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
831 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
834 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
835 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
837 if (ret
&& pvStructInfo
)
839 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
846 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
848 temp
= blob
->pbData
[i
];
849 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
850 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
854 TRACE("returning %d (%08x)\n", ret
, GetLastError());
858 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
859 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
860 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
864 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
865 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
869 struct AsnDecodeSequenceItem items
[] = {
870 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
871 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
872 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
873 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
874 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
875 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
876 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
877 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
878 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
879 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
882 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
883 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
884 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
885 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
886 pcbStructInfo
, NULL
, NULL
);
890 SetLastError(STATUS_ACCESS_VIOLATION
);
895 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
899 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
900 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
905 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
907 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
909 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
910 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
912 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
917 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
918 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
922 struct AsnDecodeSequenceItem items
[] = {
923 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
924 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
925 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
926 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
929 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
930 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
935 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
936 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
942 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
944 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
946 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
947 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
948 if (ret
&& pcbDecoded
)
949 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
954 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
955 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
956 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
959 struct AsnDecodeSequenceItem items
[] = {
960 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
961 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
962 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
963 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
964 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
965 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
966 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
967 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
968 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
969 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
971 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
972 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
974 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
975 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
977 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
978 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
979 FALSE
, TRUE
, offsetof(CERT_INFO
,
980 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
981 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
982 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
983 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
984 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
985 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
986 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
987 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
988 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
989 offsetof(CERT_INFO
, rgExtension
), 0 },
992 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
993 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
995 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
996 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
998 if (ret
&& pvStructInfo
)
1002 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1003 info
= *(CERT_INFO
**)pvStructInfo
;
1005 info
= (CERT_INFO
*)pvStructInfo
;
1006 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1007 !info
->Subject
.cbData
)
1009 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1010 /* Don't need to deallocate, because it should have failed on the
1011 * first pass (and no memory was allocated.)
1017 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1021 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1022 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1023 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1027 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1028 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1034 /* Unless told not to, first try to decode it as a signed cert. */
1035 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1037 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1039 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1040 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1041 (BYTE
*)&signedCert
, &size
);
1045 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1046 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1047 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1048 pvStructInfo
, pcbStructInfo
);
1049 LocalFree(signedCert
);
1052 /* Failing that, try it as an unsigned cert */
1056 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1057 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1058 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1063 SetLastError(STATUS_ACCESS_VIOLATION
);
1067 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1071 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1072 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1075 struct AsnDecodeSequenceItem items
[] = {
1076 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1077 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1078 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1079 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1080 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1081 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1082 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1083 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1085 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
1087 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1090 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1091 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1092 entry
? entry
->SerialNumber
.pbData
: NULL
);
1093 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1095 WARN("empty CRL entry serial number\n");
1096 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1102 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1103 * been set prior to calling.
1105 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1106 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1109 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1110 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1111 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1112 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1114 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1115 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1117 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1118 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1119 entries
? entries
->rgItems
: NULL
);
1120 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1124 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1125 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1126 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1128 struct AsnDecodeSequenceItem items
[] = {
1129 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1130 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1131 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1132 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1133 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1134 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1135 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1137 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1138 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1139 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1140 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1141 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1142 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1143 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1144 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1145 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1146 offsetof(CRL_INFO
, rgExtension
), 0 },
1150 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1151 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1153 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1154 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1157 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1161 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1162 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1163 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1167 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1168 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1174 /* Unless told not to, first try to decode it as a signed crl. */
1175 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1177 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1179 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1180 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1181 (BYTE
*)&signedCrl
, &size
);
1185 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1186 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1187 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1188 pvStructInfo
, pcbStructInfo
);
1189 LocalFree(signedCrl
);
1192 /* Failing that, try it as an unsigned crl */
1196 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1197 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1198 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1203 SetLastError(STATUS_ACCESS_VIOLATION
);
1207 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1211 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1212 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1217 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1218 pvStructInfo
, *pcbStructInfo
);
1220 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1222 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1223 DWORD bytesNeeded
= sizeof(LPSTR
);
1227 /* The largest possible string for the first two components
1228 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1233 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1234 pbEncoded
[1 + lenBytes
] / 40,
1235 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1237 bytesNeeded
+= strlen(firstTwo
) + 1;
1238 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1239 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1241 /* large enough for ".4000000" */
1245 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1252 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1255 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1262 snprintf(str
, sizeof(str
), ".%d", val
);
1263 bytesNeeded
+= strlen(str
);
1268 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1270 *pcbStructInfo
= bytesNeeded
;
1271 else if (*pcbStructInfo
< bytesNeeded
)
1273 *pcbStructInfo
= bytesNeeded
;
1274 SetLastError(ERROR_MORE_DATA
);
1282 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1285 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1286 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1288 pszObjId
+= strlen(pszObjId
);
1289 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1290 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1294 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1303 sprintf(pszObjId
, ".%d", val
);
1304 pszObjId
+= strlen(pszObjId
);
1308 *(LPSTR
*)pvStructInfo
= NULL
;
1309 *pcbStructInfo
= bytesNeeded
;
1315 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1316 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1320 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1321 pvStructInfo
, *pcbStructInfo
);
1323 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1324 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1325 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1328 SetLastError(CRYPT_E_ASN1_BADTAG
);
1334 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1337 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1338 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1340 struct AsnDecodeSequenceItem items
[] = {
1341 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1342 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1343 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1344 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1345 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1346 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1347 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1348 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1351 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1353 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1357 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1358 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1359 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1360 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1362 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1363 debugstr_a(ext
->pszObjId
));
1364 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1368 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
1369 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1373 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1374 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1375 offsetof(CERT_EXTENSION
, pszObjId
) };
1376 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1378 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1379 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1381 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1382 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1383 exts
? exts
->rgExtension
: NULL
);
1387 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1388 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1389 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1395 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1396 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1397 if (ret
&& pvStructInfo
)
1399 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1400 pcbStructInfo
, *pcbStructInfo
);
1403 CERT_EXTENSIONS
*exts
;
1405 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1406 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1407 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1408 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1409 sizeof(CERT_EXTENSIONS
));
1410 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1411 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1412 pcbStructInfo
, NULL
);
1418 SetLastError(STATUS_ACCESS_VIOLATION
);
1425 /* Warning: this assumes the address of value->Value.pbData is already set, in
1426 * order to avoid overwriting memory. (In some cases, it may change it, if it
1427 * doesn't copy anything to memory.) Be sure to set it correctly!
1429 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1430 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1435 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1437 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1439 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1440 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1442 switch (pbEncoded
[0])
1444 case ASN_OCTETSTRING
:
1445 valueType
= CERT_RDN_OCTET_STRING
;
1446 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1447 bytesNeeded
+= dataLen
;
1449 case ASN_NUMERICSTRING
:
1450 valueType
= CERT_RDN_NUMERIC_STRING
;
1451 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1452 bytesNeeded
+= dataLen
;
1454 case ASN_PRINTABLESTRING
:
1455 valueType
= CERT_RDN_PRINTABLE_STRING
;
1456 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1457 bytesNeeded
+= dataLen
;
1460 valueType
= CERT_RDN_IA5_STRING
;
1461 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1462 bytesNeeded
+= dataLen
;
1465 valueType
= CERT_RDN_T61_STRING
;
1466 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1467 bytesNeeded
+= dataLen
;
1469 case ASN_VIDEOTEXSTRING
:
1470 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1471 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1472 bytesNeeded
+= dataLen
;
1474 case ASN_GRAPHICSTRING
:
1475 valueType
= CERT_RDN_GRAPHIC_STRING
;
1476 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1477 bytesNeeded
+= dataLen
;
1479 case ASN_VISIBLESTRING
:
1480 valueType
= CERT_RDN_VISIBLE_STRING
;
1481 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1482 bytesNeeded
+= dataLen
;
1484 case ASN_GENERALSTRING
:
1485 valueType
= CERT_RDN_GENERAL_STRING
;
1486 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1487 bytesNeeded
+= dataLen
;
1489 case ASN_UNIVERSALSTRING
:
1490 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1491 SetLastError(CRYPT_E_ASN1_BADTAG
);
1494 valueType
= CERT_RDN_BMP_STRING
;
1495 bytesNeeded
+= dataLen
;
1497 case ASN_UTF8STRING
:
1498 valueType
= CERT_RDN_UTF8_STRING
;
1499 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1500 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1503 SetLastError(CRYPT_E_ASN1_BADTAG
);
1508 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1510 *pcbStructInfo
= bytesNeeded
;
1511 else if (*pcbStructInfo
< bytesNeeded
)
1513 *pcbStructInfo
= bytesNeeded
;
1514 SetLastError(ERROR_MORE_DATA
);
1519 *pcbStructInfo
= bytesNeeded
;
1520 value
->dwValueType
= valueType
;
1525 assert(value
->Value
.pbData
);
1526 switch (pbEncoded
[0])
1528 case ASN_OCTETSTRING
:
1529 case ASN_NUMERICSTRING
:
1530 case ASN_PRINTABLESTRING
:
1533 case ASN_VIDEOTEXSTRING
:
1534 case ASN_GRAPHICSTRING
:
1535 case ASN_VISIBLESTRING
:
1536 case ASN_GENERALSTRING
:
1537 value
->Value
.cbData
= dataLen
;
1540 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1541 memcpy(value
->Value
.pbData
,
1542 pbEncoded
+ 1 + lenBytes
, dataLen
);
1544 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1550 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1552 value
->Value
.cbData
= dataLen
;
1553 for (i
= 0; i
< dataLen
/ 2; i
++)
1554 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1555 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1558 case ASN_UTF8STRING
:
1560 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1562 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1563 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1564 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1571 value
->Value
.cbData
= 0;
1572 value
->Value
.pbData
= NULL
;
1579 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1580 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1581 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1587 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1588 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1589 if (ret
&& pvStructInfo
)
1591 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1592 pcbStructInfo
, *pcbStructInfo
);
1595 CERT_NAME_VALUE
*value
;
1597 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1598 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1599 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1600 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1601 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1602 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1603 pcbStructInfo
, NULL
);
1609 SetLastError(STATUS_ACCESS_VIOLATION
);
1616 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1617 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1622 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1624 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1626 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1627 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1629 switch (pbEncoded
[0])
1631 case ASN_NUMERICSTRING
:
1632 valueType
= CERT_RDN_NUMERIC_STRING
;
1633 bytesNeeded
+= dataLen
* 2;
1635 case ASN_PRINTABLESTRING
:
1636 valueType
= CERT_RDN_PRINTABLE_STRING
;
1637 bytesNeeded
+= dataLen
* 2;
1640 valueType
= CERT_RDN_IA5_STRING
;
1641 bytesNeeded
+= dataLen
* 2;
1644 valueType
= CERT_RDN_T61_STRING
;
1645 bytesNeeded
+= dataLen
* 2;
1647 case ASN_VIDEOTEXSTRING
:
1648 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1649 bytesNeeded
+= dataLen
* 2;
1651 case ASN_GRAPHICSTRING
:
1652 valueType
= CERT_RDN_GRAPHIC_STRING
;
1653 bytesNeeded
+= dataLen
* 2;
1655 case ASN_VISIBLESTRING
:
1656 valueType
= CERT_RDN_VISIBLE_STRING
;
1657 bytesNeeded
+= dataLen
* 2;
1659 case ASN_GENERALSTRING
:
1660 valueType
= CERT_RDN_GENERAL_STRING
;
1661 bytesNeeded
+= dataLen
* 2;
1663 case ASN_UNIVERSALSTRING
:
1664 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1665 bytesNeeded
+= dataLen
/ 2;
1668 valueType
= CERT_RDN_BMP_STRING
;
1669 bytesNeeded
+= dataLen
;
1671 case ASN_UTF8STRING
:
1672 valueType
= CERT_RDN_UTF8_STRING
;
1673 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1674 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1677 SetLastError(CRYPT_E_ASN1_BADTAG
);
1682 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1684 *pcbStructInfo
= bytesNeeded
;
1685 else if (*pcbStructInfo
< bytesNeeded
)
1687 *pcbStructInfo
= bytesNeeded
;
1688 SetLastError(ERROR_MORE_DATA
);
1693 *pcbStructInfo
= bytesNeeded
;
1694 value
->dwValueType
= valueType
;
1698 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1700 assert(value
->Value
.pbData
);
1701 switch (pbEncoded
[0])
1703 case ASN_NUMERICSTRING
:
1704 case ASN_PRINTABLESTRING
:
1707 case ASN_VIDEOTEXSTRING
:
1708 case ASN_GRAPHICSTRING
:
1709 case ASN_VISIBLESTRING
:
1710 case ASN_GENERALSTRING
:
1711 value
->Value
.cbData
= dataLen
* 2;
1712 for (i
= 0; i
< dataLen
; i
++)
1713 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1715 case ASN_UNIVERSALSTRING
:
1716 value
->Value
.cbData
= dataLen
/ 2;
1717 for (i
= 0; i
< dataLen
/ 4; i
++)
1718 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1719 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1722 value
->Value
.cbData
= dataLen
;
1723 for (i
= 0; i
< dataLen
/ 2; i
++)
1724 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1725 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1727 case ASN_UTF8STRING
:
1728 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1729 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1730 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1736 value
->Value
.cbData
= 0;
1737 value
->Value
.pbData
= NULL
;
1744 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1745 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1746 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1752 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1753 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1754 if (ret
&& pvStructInfo
)
1756 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1757 pcbStructInfo
, *pcbStructInfo
);
1760 CERT_NAME_VALUE
*value
;
1762 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1763 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1764 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1765 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1766 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1767 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1768 pcbStructInfo
, NULL
);
1774 SetLastError(STATUS_ACCESS_VIOLATION
);
1781 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1782 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1785 struct AsnDecodeSequenceItem items
[] = {
1786 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1787 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1788 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1789 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1790 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1791 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1793 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1795 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1796 pvStructInfo
, *pcbStructInfo
);
1799 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1800 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1801 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1802 attr
? attr
->pszObjId
: NULL
);
1805 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1806 debugstr_a(attr
->pszObjId
));
1807 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1809 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1813 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1814 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1817 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1818 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1819 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1820 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1822 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1823 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1824 rdn
? rdn
->rgRDNAttr
: NULL
);
1828 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1829 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1830 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1836 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1837 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1838 offsetof(CERT_RDN
, rgRDNAttr
) };
1840 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1841 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1845 SetLastError(STATUS_ACCESS_VIOLATION
);
1852 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1853 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1857 struct AsnDecodeSequenceItem items
[] = {
1858 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1859 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1860 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1861 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1862 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1863 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1865 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1867 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1868 pvStructInfo
, *pcbStructInfo
);
1871 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1872 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1873 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1874 attr
? attr
->pszObjId
: NULL
);
1877 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1878 debugstr_a(attr
->pszObjId
));
1879 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1881 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1885 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1886 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1889 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1890 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1891 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1892 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1894 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1895 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1896 rdn
? rdn
->rgRDNAttr
: NULL
);
1900 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1901 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1902 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1908 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1909 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1910 offsetof(CERT_RDN
, rgRDNAttr
) };
1912 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1913 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1917 SetLastError(STATUS_ACCESS_VIOLATION
);
1924 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1927 BOOL ret
= TRUE
, done
= FALSE
;
1928 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
1930 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
1937 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
1940 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1942 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
1944 indefiniteNestingLevels
++;
1945 pbEncoded
+= 1 + lenBytes
;
1946 cbEncoded
-= 1 + lenBytes
;
1947 decoded
+= 1 + lenBytes
;
1948 TRACE("indefiniteNestingLevels = %d\n",
1949 indefiniteNestingLevels
);
1953 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
1954 indefiniteNestingLevels
)
1956 indefiniteNestingLevels
--;
1957 TRACE("indefiniteNestingLevels = %d\n",
1958 indefiniteNestingLevels
);
1960 pbEncoded
+= 1 + lenBytes
+ dataLen
;
1961 cbEncoded
-= 1 + lenBytes
+ dataLen
;
1962 decoded
+= 1 + lenBytes
+ dataLen
;
1963 if (!indefiniteNestingLevels
)
1967 } while (ret
&& !done
);
1968 /* If we haven't found all 0 TLVs, we haven't found the end */
1969 if (ret
&& indefiniteNestingLevels
)
1971 SetLastError(CRYPT_E_ASN1_EOD
);
1975 *pcbDecoded
= decoded
;
1976 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
1980 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
1981 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1985 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
1987 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1988 pvStructInfo
, *pcbStructInfo
);
1990 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
1992 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1993 bytesNeeded
+= encodedLen
;
1995 *pcbStructInfo
= bytesNeeded
;
1996 else if (*pcbStructInfo
< bytesNeeded
)
1998 SetLastError(ERROR_MORE_DATA
);
1999 *pcbStructInfo
= bytesNeeded
;
2004 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
2006 *pcbStructInfo
= bytesNeeded
;
2007 blob
->cbData
= encodedLen
;
2010 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2011 blob
->pbData
= (LPBYTE
)pbEncoded
;
2014 assert(blob
->pbData
);
2015 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2019 blob
->pbData
= NULL
;
2022 *pcbDecoded
= encodedLen
;
2027 static BOOL
CRYPT_DecodeDERArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2028 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2031 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
2032 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2033 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
2035 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2036 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2038 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2039 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2040 array
? array
->rgItems
: NULL
);
2044 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2045 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2048 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2049 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2050 CTL_USAGE
*usage
= (CTL_USAGE
*)pvStructInfo
;
2052 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2053 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2054 usage
? usage
->rgpszUsageIdentifier
: NULL
);
2058 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2059 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2061 struct AsnDecodeSequenceItem items
[] = {
2062 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2063 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2064 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2065 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2066 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
), FALSE
,
2067 TRUE
, offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2070 CTL_ENTRY
*entry
= (CTL_ENTRY
*)pvStructInfo
;
2072 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2075 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2076 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2077 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2081 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2082 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2085 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2086 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2087 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2088 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2090 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2091 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2093 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2094 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2095 entries
? entries
->rgItems
: NULL
);
2099 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2100 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2101 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2105 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2106 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2110 struct AsnDecodeSequenceItem items
[] = {
2111 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2112 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2113 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2114 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2115 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2116 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2117 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2118 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2119 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2120 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2121 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2122 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2123 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2125 { 0, offsetof(CTL_INFO
, NextUpdate
),
2126 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2128 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2129 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2130 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2131 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2132 CRYPT_AsnDecodeCTLEntries
, sizeof(struct GenericArray
),
2133 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2134 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2135 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
2136 offsetof(CTL_INFO
, rgExtension
), 0 },
2139 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2140 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2142 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2143 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2144 pcbStructInfo
, NULL
, NULL
);
2148 SetLastError(STATUS_ACCESS_VIOLATION
);
2154 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2155 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2159 struct AsnDecodeSequenceItem items
[] = {
2160 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2161 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2162 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2163 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2164 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2165 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2167 PCRYPT_SMIME_CAPABILITY capability
= (PCRYPT_SMIME_CAPABILITY
)pvStructInfo
;
2169 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2170 pvStructInfo
, *pcbStructInfo
);
2172 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2173 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2174 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2175 TRACE("returning %d\n", ret
);
2179 static BOOL
CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE
*pbEncoded
,
2180 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2183 struct AsnArrayDescriptor arrayDesc
= { 0,
2184 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2185 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2186 PCRYPT_SMIME_CAPABILITIES capabilities
=
2187 (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2190 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2191 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2192 capabilities
? capabilities
->rgCapability
: NULL
);
2196 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2197 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2198 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2202 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2203 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2210 SetLastError(CRYPT_E_ASN1_EOD
);
2211 else if (pbEncoded
[0] != ASN_SEQUENCEOF
)
2212 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2213 else if ((ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2214 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2218 *pcbStructInfo
= bytesNeeded
;
2219 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2220 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2222 PCRYPT_SMIME_CAPABILITIES capabilities
;
2224 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2225 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2226 capabilities
= (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2227 capabilities
->rgCapability
=
2228 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2229 sizeof(CRYPT_SMIME_CAPABILITIES
));
2230 ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2231 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2232 &bytesNeeded
, NULL
);
2238 SetLastError(STATUS_ACCESS_VIOLATION
);
2241 TRACE("returning %d\n", ret
);
2245 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2246 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2250 struct AsnDecodeSequenceItem items
[] = {
2251 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2252 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2253 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2254 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2255 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
2256 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2258 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2260 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2261 pvStructInfo
, *pcbStructInfo
);
2263 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2264 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2265 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2266 TRACE("returning %d\n", ret
);
2270 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2271 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2272 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2276 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2277 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2283 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2284 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2288 *pcbStructInfo
= bytesNeeded
;
2289 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2290 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2292 PCRYPT_ATTRIBUTE attr
;
2294 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2295 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2296 attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2297 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2298 sizeof(CRYPT_ATTRIBUTE
));
2299 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2300 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2307 SetLastError(STATUS_ACCESS_VIOLATION
);
2310 TRACE("returning %d\n", ret
);
2314 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2315 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2318 struct AsnArrayDescriptor arrayDesc
= { 0,
2319 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2320 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2321 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2324 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2325 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2330 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2331 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2332 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2336 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2337 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2344 SetLastError(CRYPT_E_ASN1_EOD
);
2345 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2346 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2347 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2348 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2352 *pcbStructInfo
= bytesNeeded
;
2353 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2354 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2356 PCRYPT_ATTRIBUTES attrs
;
2358 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2359 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2360 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2361 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2362 sizeof(CRYPT_ATTRIBUTES
));
2363 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2364 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2365 &bytesNeeded
, NULL
);
2371 SetLastError(STATUS_ACCESS_VIOLATION
);
2374 TRACE("returning %d\n", ret
);
2378 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2379 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2381 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
2382 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
2384 struct AsnDecodeSequenceItem items
[] = {
2385 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2386 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2387 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2388 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2389 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2390 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2393 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2394 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2396 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2397 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2398 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2399 if (ret
&& pvStructInfo
)
2401 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2402 debugstr_a(algo
->pszObjId
));
2407 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2408 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2412 struct AsnDecodeSequenceItem items
[] = {
2413 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2414 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2415 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2416 Algorithm
.pszObjId
) },
2417 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2418 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2419 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2421 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2423 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2424 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2425 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2429 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2430 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2431 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2439 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2440 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2443 *pcbStructInfo
= bytesNeeded
;
2444 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2445 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2447 PCERT_PUBLIC_KEY_INFO info
;
2449 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2450 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2451 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2452 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2453 sizeof(CERT_PUBLIC_KEY_INFO
);
2454 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2455 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2456 &bytesNeeded
, NULL
);
2462 SetLastError(STATUS_ACCESS_VIOLATION
);
2469 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2470 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2476 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2479 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2481 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2484 if (pbEncoded
[1] > 1)
2486 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2493 *pcbStructInfo
= sizeof(BOOL
);
2496 else if (*pcbStructInfo
< sizeof(BOOL
))
2498 *pcbStructInfo
= sizeof(BOOL
);
2499 SetLastError(ERROR_MORE_DATA
);
2504 *pcbStructInfo
= sizeof(BOOL
);
2505 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2508 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2512 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2513 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2515 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2516 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2519 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2520 pvStructInfo
, *pcbStructInfo
);
2524 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2527 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2528 if (1 + lenBytes
> cbEncoded
)
2530 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2533 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2535 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2537 case 1: /* rfc822Name */
2538 case 2: /* dNSName */
2539 case 6: /* uniformResourceIdentifier */
2540 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2542 case 4: /* directoryName */
2543 case 7: /* iPAddress */
2544 bytesNeeded
+= dataLen
;
2546 case 8: /* registeredID */
2547 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2551 /* FIXME: ugly, shouldn't need to know internals of OID decode
2552 * function to use it.
2554 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2557 case 0: /* otherName */
2558 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2559 SetLastError(CRYPT_E_ASN1_BADTAG
);
2562 case 3: /* x400Address, unimplemented */
2563 case 5: /* ediPartyName, unimplemented */
2564 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2565 SetLastError(CRYPT_E_ASN1_BADTAG
);
2569 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2570 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2576 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2578 *pcbStructInfo
= bytesNeeded
;
2579 else if (*pcbStructInfo
< bytesNeeded
)
2581 *pcbStructInfo
= bytesNeeded
;
2582 SetLastError(ERROR_MORE_DATA
);
2587 *pcbStructInfo
= bytesNeeded
;
2588 /* MS used values one greater than the asn1 ones.. sigh */
2589 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
2590 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2592 case 1: /* rfc822Name */
2593 case 2: /* dNSName */
2594 case 6: /* uniformResourceIdentifier */
2598 for (i
= 0; i
< dataLen
; i
++)
2599 entry
->u
.pwszURL
[i
] =
2600 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2601 entry
->u
.pwszURL
[i
] = 0;
2602 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2603 debugstr_w(entry
->u
.pwszURL
));
2606 case 4: /* directoryName */
2607 /* The data are memory-equivalent with the IPAddress case,
2610 case 7: /* iPAddress */
2611 /* The next data pointer is in the pwszURL spot, that is,
2612 * the first 4 bytes. Need to move it to the next spot.
2614 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2615 entry
->u
.IPAddress
.cbData
= dataLen
;
2616 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2619 case 8: /* registeredID */
2620 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2621 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2630 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
2631 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2635 struct AsnArrayDescriptor arrayDesc
= { 0,
2636 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2637 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2638 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2640 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2641 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2644 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2645 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2646 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2647 info
? info
->rgAltEntry
: NULL
);
2651 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2652 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
2653 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2658 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2659 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2661 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2664 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
2665 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
2667 if (ret
&& pvStructInfo
)
2669 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2676 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
2678 temp
= blob
->pbData
[i
];
2679 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
2680 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
2684 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2688 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2689 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2690 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2696 struct AsnDecodeSequenceItem items
[] = {
2697 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2698 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2699 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2700 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2701 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2702 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2703 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2704 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2705 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2706 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2707 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2710 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2711 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2712 pcbStructInfo
, NULL
, NULL
);
2716 SetLastError(STATUS_ACCESS_VIOLATION
);
2723 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2724 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2725 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2731 struct AsnDecodeSequenceItem items
[] = {
2732 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2733 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2734 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2735 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2736 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2737 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2738 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2739 AuthorityCertIssuer
.rgAltEntry
), 0 },
2740 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2741 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2742 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2743 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2744 AuthorityCertSerialNumber
.pbData
), 0 },
2747 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2748 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2749 pcbStructInfo
, NULL
, NULL
);
2753 SetLastError(STATUS_ACCESS_VIOLATION
);
2760 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
2761 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2764 struct AsnDecodeSequenceItem items
[] = {
2765 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
2766 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
2767 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
2768 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
2769 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
2770 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
2772 CERT_ACCESS_DESCRIPTION
*descr
= (CERT_ACCESS_DESCRIPTION
*)pvStructInfo
;
2774 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2775 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2776 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
2779 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
2780 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2781 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2785 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2786 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2790 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2791 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
2792 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
2794 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2795 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2799 SetLastError(STATUS_ACCESS_VIOLATION
);
2806 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2807 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2812 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2813 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2815 /* The caller has already checked the tag, no need to check it again.
2816 * Check the outer length is valid:
2818 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
2820 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2823 pbEncoded
+= 1 + lenBytes
;
2824 cbEncoded
-= 1 + lenBytes
;
2825 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2826 cbEncoded
-= 2; /* space for 0 TLV */
2827 /* Check the inner length is valid: */
2828 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
2832 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
2833 pvStructInfo
, pcbStructInfo
, &decodedLen
);
2834 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2836 if (*(pbEncoded
+ decodedLen
) != 0 ||
2837 *(pbEncoded
+ decodedLen
+ 1) != 0)
2839 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2840 *(pbEncoded
+ decodedLen
),
2841 *(pbEncoded
+ decodedLen
+ 1));
2842 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2848 if (ret
&& pcbDecoded
)
2850 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
2851 TRACE("decoded %d bytes\n", *pcbDecoded
);
2858 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
2859 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2862 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2863 struct AsnDecodeSequenceItem items
[] = {
2864 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2865 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2866 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2867 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2868 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2869 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2870 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2874 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2875 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2877 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2878 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2879 pcbDecoded
, info
? info
->pszObjId
: NULL
);
2883 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2884 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2885 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2889 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2890 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2894 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
2895 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
2896 if (ret
&& pvStructInfo
)
2898 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2899 pcbStructInfo
, *pcbStructInfo
);
2902 CRYPT_CONTENT_INFO
*info
;
2904 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2905 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2906 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2907 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2908 sizeof(CRYPT_CONTENT_INFO
));
2909 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
2910 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2911 pcbStructInfo
, NULL
);
2917 SetLastError(STATUS_ACCESS_VIOLATION
);
2923 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2924 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2925 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2928 struct AsnDecodeSequenceItem items
[] = {
2929 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
2930 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2931 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2932 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2933 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2935 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2936 CRYPT_AsnDecodePKCSContentInfoInternal
,
2937 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2938 ContentInfo
.pszObjId
), 0 },
2939 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2940 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2941 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2944 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2945 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
2950 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2951 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2952 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2956 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2957 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2963 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2964 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2967 *pcbStructInfo
= bytesNeeded
;
2968 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2969 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2971 CERT_ALT_NAME_INFO
*name
;
2973 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2974 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2975 name
= (CERT_ALT_NAME_INFO
*)pvStructInfo
;
2976 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
2977 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
2978 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2979 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2980 &bytesNeeded
, NULL
);
2986 SetLastError(STATUS_ACCESS_VIOLATION
);
2993 struct PATH_LEN_CONSTRAINT
2995 BOOL fPathLenConstraint
;
2996 DWORD dwPathLenConstraint
;
2999 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3000 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3004 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3006 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3007 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3011 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3013 *pcbStructInfo
= bytesNeeded
;
3015 else if (*pcbStructInfo
< bytesNeeded
)
3017 SetLastError(ERROR_MORE_DATA
);
3018 *pcbStructInfo
= bytesNeeded
;
3023 struct PATH_LEN_CONSTRAINT
*constraint
=
3024 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
3026 *pcbStructInfo
= bytesNeeded
;
3027 size
= sizeof(constraint
->dwPathLenConstraint
);
3028 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3029 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3031 constraint
->fPathLenConstraint
= TRUE
;
3032 TRACE("got an int, dwPathLenConstraint is %d\n",
3033 constraint
->dwPathLenConstraint
);
3035 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3039 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3040 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3044 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3045 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3046 offsetof(CERT_NAME_BLOB
, pbData
) };
3047 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
3049 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3050 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3052 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3053 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3054 entries
? entries
->rgItems
: NULL
);
3055 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3059 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3060 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3061 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3067 struct AsnDecodeSequenceItem items
[] = {
3068 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3069 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3070 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3071 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3072 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3073 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3074 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3075 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3076 sizeof(struct GenericArray
), TRUE
, TRUE
,
3077 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3080 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3081 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3082 pcbStructInfo
, NULL
, NULL
);
3086 SetLastError(STATUS_ACCESS_VIOLATION
);
3093 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3094 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3095 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3101 struct AsnDecodeSequenceItem items
[] = {
3102 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3103 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3104 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3105 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3106 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3109 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3110 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3111 pcbStructInfo
, NULL
, NULL
);
3115 SetLastError(STATUS_ACCESS_VIOLATION
);
3122 #define RSA1_MAGIC 0x31415352
3124 struct DECODED_RSA_PUB_KEY
3127 CRYPT_INTEGER_BLOB modulus
;
3130 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3131 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3132 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3138 struct AsnDecodeSequenceItem items
[] = {
3139 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3140 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3141 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3143 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3144 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3146 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3149 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3150 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3154 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3155 decodedKey
->modulus
.cbData
;
3159 *pcbStructInfo
= bytesNeeded
;
3162 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3163 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3166 RSAPUBKEY
*rsaPubKey
;
3168 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3169 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3170 hdr
= (BLOBHEADER
*)pvStructInfo
;
3171 hdr
->bType
= PUBLICKEYBLOB
;
3172 hdr
->bVersion
= CUR_BLOB_VERSION
;
3174 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3175 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3176 sizeof(BLOBHEADER
));
3177 rsaPubKey
->magic
= RSA1_MAGIC
;
3178 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3179 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3180 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3181 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3182 decodedKey
->modulus
.cbData
);
3184 LocalFree(decodedKey
);
3189 SetLastError(STATUS_ACCESS_VIOLATION
);
3196 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3197 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3201 DWORD bytesNeeded
, dataLen
;
3203 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3204 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3206 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3208 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3210 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3211 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3213 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3215 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3217 *pcbStructInfo
= bytesNeeded
;
3218 else if (*pcbStructInfo
< bytesNeeded
)
3220 SetLastError(ERROR_MORE_DATA
);
3221 *pcbStructInfo
= bytesNeeded
;
3226 CRYPT_DATA_BLOB
*blob
;
3228 *pcbStructInfo
= bytesNeeded
;
3229 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3230 blob
->cbData
= dataLen
;
3231 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3232 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3235 assert(blob
->pbData
);
3237 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3245 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3246 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3247 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3251 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3252 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3260 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3263 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3265 SetLastError(CRYPT_E_ASN1_BADTAG
);
3268 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3269 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3272 *pcbStructInfo
= bytesNeeded
;
3273 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3274 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3276 CRYPT_DATA_BLOB
*blob
;
3278 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3279 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3280 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3281 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3282 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3283 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3284 &bytesNeeded
, NULL
);
3290 SetLastError(STATUS_ACCESS_VIOLATION
);
3297 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3298 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3302 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3303 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3305 if (pbEncoded
[0] == ASN_BITSTRING
)
3307 DWORD bytesNeeded
, dataLen
;
3308 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3310 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3312 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3313 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3315 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3317 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3319 *pcbStructInfo
= bytesNeeded
;
3320 else if (*pcbStructInfo
< bytesNeeded
)
3322 *pcbStructInfo
= bytesNeeded
;
3323 SetLastError(ERROR_MORE_DATA
);
3328 CRYPT_BIT_BLOB
*blob
;
3330 *pcbStructInfo
= bytesNeeded
;
3331 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3332 blob
->cbData
= dataLen
- 1;
3333 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3334 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3336 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3340 assert(blob
->pbData
);
3343 BYTE mask
= 0xff << blob
->cUnusedBits
;
3345 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3347 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3355 SetLastError(CRYPT_E_ASN1_BADTAG
);
3358 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3362 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3363 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3364 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3368 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3369 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3375 if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3376 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3379 *pcbStructInfo
= bytesNeeded
;
3380 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3381 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3383 CRYPT_BIT_BLOB
*blob
;
3385 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3386 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3387 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3388 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3389 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3390 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3391 &bytesNeeded
, NULL
);
3397 SetLastError(STATUS_ACCESS_VIOLATION
);
3401 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3405 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3406 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3407 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3410 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3411 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3412 DWORD size
= sizeof(buf
);
3414 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3415 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
3420 *pcbStructInfo
= sizeof(int);
3421 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3425 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3427 /* initialize to a negative value to sign-extend */
3432 for (i
= 0; i
< blob
->cbData
; i
++)
3435 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3437 memcpy(pvStructInfo
, &val
, sizeof(int));
3440 else if (GetLastError() == ERROR_MORE_DATA
)
3441 SetLastError(CRYPT_E_ASN1_LARGE
);
3445 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3446 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3447 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3457 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3460 else if (pbEncoded
[0] != ASN_INTEGER
)
3462 SetLastError(CRYPT_E_ASN1_BADTAG
);
3466 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3467 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3471 *pcbStructInfo
= bytesNeeded
;
3472 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3473 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3475 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3476 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3477 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3478 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3479 &bytesNeeded
, NULL
);
3485 SetLastError(STATUS_ACCESS_VIOLATION
);
3492 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
3493 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3497 DWORD bytesNeeded
, dataLen
;
3499 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3501 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3503 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3505 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3507 *pcbStructInfo
= bytesNeeded
;
3508 else if (*pcbStructInfo
< bytesNeeded
)
3510 *pcbStructInfo
= bytesNeeded
;
3511 SetLastError(ERROR_MORE_DATA
);
3516 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3518 *pcbStructInfo
= bytesNeeded
;
3519 blob
->cbData
= dataLen
;
3520 assert(blob
->pbData
);
3525 for (i
= 0; i
< blob
->cbData
; i
++)
3527 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3536 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3537 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3538 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3546 if (pbEncoded
[0] != ASN_INTEGER
)
3548 SetLastError(CRYPT_E_ASN1_BADTAG
);
3552 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3553 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3557 *pcbStructInfo
= bytesNeeded
;
3558 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3559 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3561 CRYPT_INTEGER_BLOB
*blob
;
3563 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3564 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3565 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3566 blob
->pbData
= (BYTE
*)pvStructInfo
+
3567 sizeof(CRYPT_INTEGER_BLOB
);
3568 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3569 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3570 &bytesNeeded
, NULL
);
3576 SetLastError(STATUS_ACCESS_VIOLATION
);
3583 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
3584 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3589 if (pbEncoded
[0] == ASN_INTEGER
)
3591 DWORD bytesNeeded
, dataLen
;
3593 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3595 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3598 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3599 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3601 *pcbStructInfo
= bytesNeeded
;
3602 else if (*pcbStructInfo
< bytesNeeded
)
3604 *pcbStructInfo
= bytesNeeded
;
3605 SetLastError(ERROR_MORE_DATA
);
3610 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3612 *pcbStructInfo
= bytesNeeded
;
3613 blob
->cbData
= dataLen
;
3614 assert(blob
->pbData
);
3615 /* remove leading zero byte if it exists */
3616 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3625 for (i
= 0; i
< blob
->cbData
; i
++)
3627 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3636 SetLastError(CRYPT_E_ASN1_BADTAG
);
3642 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3643 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3644 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3652 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
3653 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3656 *pcbStructInfo
= bytesNeeded
;
3657 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3658 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3660 CRYPT_INTEGER_BLOB
*blob
;
3662 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3663 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3664 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3665 blob
->pbData
= (BYTE
*)pvStructInfo
+
3666 sizeof(CRYPT_INTEGER_BLOB
);
3667 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
3668 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3669 &bytesNeeded
, NULL
);
3675 SetLastError(STATUS_ACCESS_VIOLATION
);
3682 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3683 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3684 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3690 *pcbStructInfo
= sizeof(int);
3695 if (pbEncoded
[0] == ASN_ENUMERATED
)
3697 unsigned int val
= 0, i
;
3701 SetLastError(CRYPT_E_ASN1_EOD
);
3704 else if (pbEncoded
[1] == 0)
3706 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3711 /* A little strange looking, but we have to accept a sign byte:
3712 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3713 * assuming a small length is okay here, it has to be in short
3716 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3718 SetLastError(CRYPT_E_ASN1_LARGE
);
3721 for (i
= 0; i
< pbEncoded
[1]; i
++)
3724 val
|= pbEncoded
[2 + i
];
3726 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3727 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3729 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3730 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3731 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3737 SetLastError(CRYPT_E_ASN1_BADTAG
);
3743 SetLastError(STATUS_ACCESS_VIOLATION
);
3750 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3753 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3758 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3760 if (!isdigit(*(pbEncoded))) \
3762 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3768 (word) += *(pbEncoded)++ - '0'; \
3773 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3774 SYSTEMTIME
*sysTime
)
3778 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3780 WORD hours
, minutes
= 0;
3781 BYTE sign
= *pbEncoded
++;
3784 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3785 if (ret
&& hours
>= 24)
3787 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3792 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3793 if (ret
&& minutes
>= 60)
3795 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3803 sysTime
->wHour
+= hours
;
3804 sysTime
->wMinute
+= minutes
;
3808 if (hours
> sysTime
->wHour
)
3811 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3814 sysTime
->wHour
-= hours
;
3815 if (minutes
> sysTime
->wMinute
)
3818 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3821 sysTime
->wMinute
-= minutes
;
3828 #define MIN_ENCODED_TIME_LENGTH 10
3830 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
3831 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3836 if (pbEncoded
[0] == ASN_UTCTIME
)
3839 SetLastError(CRYPT_E_ASN1_EOD
);
3840 else if (pbEncoded
[1] > 0x7f)
3842 /* long-form date strings really can't be valid */
3843 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3847 SYSTEMTIME sysTime
= { 0 };
3848 BYTE len
= pbEncoded
[1];
3850 if (len
< MIN_ENCODED_TIME_LENGTH
)
3851 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3856 *pcbDecoded
= 2 + len
;
3858 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3859 if (sysTime
.wYear
>= 50)
3860 sysTime
.wYear
+= 1900;
3862 sysTime
.wYear
+= 2000;
3863 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3864 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3865 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3866 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3869 if (len
>= 2 && isdigit(*pbEncoded
) &&
3870 isdigit(*(pbEncoded
+ 1)))
3871 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3873 else if (isdigit(*pbEncoded
))
3874 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3877 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3883 *pcbStructInfo
= sizeof(FILETIME
);
3884 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3886 ret
= SystemTimeToFileTime(&sysTime
,
3887 (FILETIME
*)pvStructInfo
);
3893 SetLastError(CRYPT_E_ASN1_BADTAG
);
3897 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3898 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3899 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3907 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3908 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3912 *pcbStructInfo
= bytesNeeded
;
3913 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3914 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3916 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3917 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3918 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3919 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3920 &bytesNeeded
, NULL
);
3926 SetLastError(STATUS_ACCESS_VIOLATION
);
3932 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
3933 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3938 if (pbEncoded
[0] == ASN_GENERALTIME
)
3941 SetLastError(CRYPT_E_ASN1_EOD
);
3942 else if (pbEncoded
[1] > 0x7f)
3944 /* long-form date strings really can't be valid */
3945 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3949 BYTE len
= pbEncoded
[1];
3951 if (len
< MIN_ENCODED_TIME_LENGTH
)
3952 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3955 SYSTEMTIME sysTime
= { 0 };
3959 *pcbDecoded
= 2 + len
;
3961 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3962 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3963 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3964 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3967 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3970 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3972 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3979 /* workaround macro weirdness */
3980 digits
= min(len
, 3);
3981 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3982 sysTime
.wMilliseconds
);
3985 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3991 *pcbStructInfo
= sizeof(FILETIME
);
3992 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3994 ret
= SystemTimeToFileTime(&sysTime
,
3995 (FILETIME
*)pvStructInfo
);
4001 SetLastError(CRYPT_E_ASN1_BADTAG
);
4005 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4006 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4010 InternalDecodeFunc decode
= NULL
;
4012 if (pbEncoded
[0] == ASN_UTCTIME
)
4013 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4014 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4015 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4017 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4018 pcbStructInfo
, pcbDecoded
);
4021 SetLastError(CRYPT_E_ASN1_BADTAG
);
4027 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4028 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4029 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4037 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4038 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4042 *pcbStructInfo
= bytesNeeded
;
4043 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4044 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4046 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4047 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4048 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4049 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4050 &bytesNeeded
, NULL
);
4056 SetLastError(STATUS_ACCESS_VIOLATION
);
4063 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4064 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4065 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4071 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4073 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4075 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4080 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4081 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4083 ptr
= pbEncoded
+ 1 + lenBytes
;
4084 remainingLen
= dataLen
;
4085 while (ret
&& remainingLen
)
4089 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4092 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4094 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4095 ptr
+= 1 + nextLenBytes
+ nextLen
;
4096 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4097 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4098 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4104 CRYPT_SEQUENCE_OF_ANY
*seq
;
4109 *pcbStructInfo
= bytesNeeded
;
4110 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4111 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4113 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4114 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4115 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
4116 seq
->cValue
= cValue
;
4117 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4119 nextPtr
= (BYTE
*)seq
->rgValue
+
4120 cValue
* sizeof(CRYPT_DER_BLOB
);
4121 ptr
= pbEncoded
+ 1 + lenBytes
;
4122 remainingLen
= dataLen
;
4124 while (ret
&& remainingLen
)
4128 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4131 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4133 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4135 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4136 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4139 seq
->rgValue
[i
].pbData
= nextPtr
;
4140 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4142 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4144 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4145 ptr
+= 1 + nextLenBytes
+ nextLen
;
4155 SetLastError(CRYPT_E_ASN1_BADTAG
);
4161 SetLastError(STATUS_ACCESS_VIOLATION
);
4168 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4169 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4174 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4176 DWORD bytesNeeded
, dataLen
;
4178 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4180 struct AsnArrayDescriptor arrayDesc
= {
4181 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
4182 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4183 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4184 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4189 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4190 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4191 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
4192 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4193 * as the sizeof(struct GenericArray), so don't include it in the
4194 * total bytes needed.
4196 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4197 sizeof(CERT_ALT_NAME_INFO
);
4200 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4202 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4204 *pcbStructInfo
= bytesNeeded
;
4205 else if (*pcbStructInfo
< bytesNeeded
)
4207 *pcbStructInfo
= bytesNeeded
;
4208 SetLastError(ERROR_MORE_DATA
);
4213 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
4215 *pcbStructInfo
= bytesNeeded
;
4218 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4219 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4220 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4221 0, NULL
, &name
->u
.FullName
, &nameLen
, NULL
,
4222 name
->u
.FullName
.rgAltEntry
);
4225 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4231 SetLastError(CRYPT_E_ASN1_BADTAG
);
4237 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4238 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4240 struct AsnDecodeSequenceItem items
[] = {
4241 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4242 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4243 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4244 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4245 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4246 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4247 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4248 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4249 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4250 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4254 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4255 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4260 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4261 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4262 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4266 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4267 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4271 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4272 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4273 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4275 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4276 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4280 SetLastError(STATUS_ACCESS_VIOLATION
);
4287 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
4288 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4289 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4293 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4294 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4298 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4299 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
4301 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4302 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4306 SetLastError(STATUS_ACCESS_VIOLATION
);
4313 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4314 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4315 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4319 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4320 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4324 struct AsnDecodeSequenceItem items
[] = {
4325 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4326 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4327 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4328 offsetof(CRL_ISSUING_DIST_POINT
,
4329 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4330 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4331 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4333 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4334 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4336 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4337 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4338 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4339 OnlySomeReasonFlags
.pbData
), 0 },
4340 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4341 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4344 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4345 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4346 pcbStructInfo
, NULL
, NULL
);
4350 SetLastError(STATUS_ACCESS_VIOLATION
);
4357 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
4358 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4363 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4364 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4368 SetLastError(CRYPT_E_ASN1_EOD
);
4371 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
4373 SetLastError(CRYPT_E_ASN1_BADTAG
);
4376 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4377 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
4378 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
4380 if (ret
&& pvStructInfo
)
4381 *(BOOL
*)pvStructInfo
= TRUE
;
4382 TRACE("returning %d\n", ret
);
4386 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
4387 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4391 struct AsnDecodeSequenceItem items
[] = {
4392 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
4393 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
4394 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
4395 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
4396 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
4397 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
4398 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
4401 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)pvStructInfo
;
4403 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4404 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4406 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4407 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4408 pcbDecoded
, subtree
? (BYTE
*)subtree
->Base
.u
.pwszURL
: NULL
);
4411 TRACE("%d\n", *pcbDecoded
);
4412 if (*pcbDecoded
< cbEncoded
)
4413 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
4414 *(pbEncoded
+ *pcbDecoded
+ 1));
4416 TRACE("returning %d\n", ret
);
4420 static BOOL
CRYPT_AsnDecodeSubtreeArray(const BYTE
*pbEncoded
,
4421 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4425 struct AsnArrayDescriptor arrayDesc
= { 0,
4426 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4427 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4428 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4430 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4431 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4433 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4434 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4435 array
? array
->rgItems
: NULL
);
4440 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
4441 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4442 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4446 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4447 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4451 struct AsnDecodeSequenceItem items
[] = {
4452 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4453 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
4454 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4455 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
4456 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
4457 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4458 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4459 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
4462 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4463 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4464 pcbStructInfo
, NULL
, NULL
);
4468 SetLastError(STATUS_ACCESS_VIOLATION
);
4474 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
4475 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4479 struct AsnDecodeSequenceItem items
[] = {
4480 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4481 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4483 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4484 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4485 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4487 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
4488 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
4490 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4491 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4493 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4494 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4495 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4496 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4498 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4501 TRACE("returning %d\n", ret
);
4505 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4506 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4509 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4510 struct AsnDecodeSequenceItem items
[] = {
4511 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4512 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4513 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4514 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4515 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4516 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4517 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4518 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4519 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4520 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4521 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4522 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4523 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4524 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4525 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4526 HashEncryptionAlgorithm
.pszObjId
), 0 },
4527 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4528 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4529 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4530 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4531 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4532 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4533 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4537 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4538 pvStructInfo
, *pcbStructInfo
);
4540 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4541 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4542 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
4546 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4547 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4548 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4552 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4553 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4557 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4558 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4559 if (ret
&& pvStructInfo
)
4561 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4562 pcbStructInfo
, *pcbStructInfo
);
4565 CMSG_SIGNER_INFO
*info
;
4567 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4568 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4569 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4570 info
->Issuer
.pbData
= ((BYTE
*)info
+
4571 sizeof(CMSG_SIGNER_INFO
));
4572 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
4573 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4574 pcbStructInfo
, NULL
);
4580 SetLastError(STATUS_ACCESS_VIOLATION
);
4583 TRACE("returning %d\n", ret
);
4587 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
4588 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4591 CERT_ID
*id
= (CERT_ID
*)pvStructInfo
;
4594 if (*pbEncoded
== ASN_SEQUENCEOF
)
4596 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
4597 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
4601 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
4602 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
4603 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4604 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
4606 *pcbStructInfo
= sizeof(CERT_ID
);
4609 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
4611 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
4612 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
4616 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
4617 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
4618 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4619 sizeof(CRYPT_DATA_BLOB
);
4621 *pcbStructInfo
= sizeof(CERT_ID
);
4625 SetLastError(CRYPT_E_ASN1_BADTAG
);
4629 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
4630 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4633 CMSG_CMS_SIGNER_INFO
*info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4634 struct AsnDecodeSequenceItem items
[] = {
4635 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
4636 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4637 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
4638 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
4639 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
4640 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
4641 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4642 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4643 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4644 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
4645 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4646 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4647 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
4648 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4649 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
4650 HashEncryptionAlgorithm
.pszObjId
), 0 },
4651 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
4652 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4653 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4654 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4655 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
4656 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4657 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4661 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4662 pvStructInfo
, *pcbStructInfo
);
4664 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4665 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4666 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
4670 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
4671 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4672 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4676 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4677 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4681 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
4682 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4683 if (ret
&& pvStructInfo
)
4685 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4686 pcbStructInfo
, *pcbStructInfo
);
4689 CMSG_CMS_SIGNER_INFO
*info
;
4691 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4692 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4693 info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4694 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
4695 sizeof(CMSG_CMS_SIGNER_INFO
));
4696 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
4697 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4698 pcbStructInfo
, NULL
);
4704 SetLastError(STATUS_ACCESS_VIOLATION
);
4707 TRACE("returning %d\n", ret
);
4711 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4712 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4715 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
4716 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
4717 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
4718 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4720 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4721 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4723 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4724 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4725 array
? array
->rgItems
: NULL
);
4729 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4730 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
4731 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
4734 struct AsnDecodeSequenceItem items
[] = {
4735 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
4736 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4737 /* Placeholder for the hash algorithms - redundant with those in the
4738 * signers, so just ignore them.
4740 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
4741 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
4742 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
4743 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
4744 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4745 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
4746 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4747 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
4748 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4749 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
4750 sizeof(struct GenericArray
), TRUE
, TRUE
,
4751 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
4752 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
4753 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4754 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
4757 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4758 pDecodePara
, signedInfo
, *pcbSignedInfo
);
4760 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4761 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
4763 TRACE("returning %d\n", ret
);
4767 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
4768 LPCSTR lpszStructType
)
4770 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4772 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
4773 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
4775 SetLastError(ERROR_FILE_NOT_FOUND
);
4778 if (!HIWORD(lpszStructType
))
4780 switch (LOWORD(lpszStructType
))
4782 case LOWORD(X509_CERT
):
4783 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
4785 case LOWORD(X509_CERT_TO_BE_SIGNED
):
4786 decodeFunc
= CRYPT_AsnDecodeCert
;
4788 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
4789 decodeFunc
= CRYPT_AsnDecodeCRL
;
4791 case LOWORD(X509_EXTENSIONS
):
4792 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4794 case LOWORD(X509_NAME_VALUE
):
4795 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4797 case LOWORD(X509_NAME
):
4798 decodeFunc
= CRYPT_AsnDecodeName
;
4800 case LOWORD(X509_PUBLIC_KEY_INFO
):
4801 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4803 case LOWORD(X509_AUTHORITY_KEY_ID
):
4804 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4806 case LOWORD(X509_ALTERNATE_NAME
):
4807 decodeFunc
= CRYPT_AsnDecodeAltName
;
4809 case LOWORD(X509_BASIC_CONSTRAINTS
):
4810 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4812 case LOWORD(X509_BASIC_CONSTRAINTS2
):
4813 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4815 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
4816 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4818 case LOWORD(X509_UNICODE_NAME
):
4819 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4821 case LOWORD(PKCS_ATTRIBUTE
):
4822 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4824 case LOWORD(X509_UNICODE_NAME_VALUE
):
4825 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4827 case LOWORD(X509_OCTET_STRING
):
4828 decodeFunc
= CRYPT_AsnDecodeOctets
;
4830 case LOWORD(X509_BITS
):
4831 case LOWORD(X509_KEY_USAGE
):
4832 decodeFunc
= CRYPT_AsnDecodeBits
;
4834 case LOWORD(X509_INTEGER
):
4835 decodeFunc
= CRYPT_AsnDecodeInt
;
4837 case LOWORD(X509_MULTI_BYTE_INTEGER
):
4838 decodeFunc
= CRYPT_AsnDecodeInteger
;
4840 case LOWORD(X509_MULTI_BYTE_UINT
):
4841 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4843 case LOWORD(X509_ENUMERATED
):
4844 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4846 case LOWORD(X509_CHOICE_OF_TIME
):
4847 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4849 case LOWORD(X509_AUTHORITY_KEY_ID2
):
4850 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4852 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
4853 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
4855 case LOWORD(PKCS_CONTENT_INFO
):
4856 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4858 case LOWORD(X509_SEQUENCE_OF_ANY
):
4859 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4861 case LOWORD(PKCS_UTC_TIME
):
4862 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4864 case LOWORD(X509_CRL_DIST_POINTS
):
4865 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4867 case LOWORD(X509_ENHANCED_KEY_USAGE
):
4868 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4870 case LOWORD(PKCS_CTL
):
4871 decodeFunc
= CRYPT_AsnDecodeCTL
;
4873 case LOWORD(PKCS_SMIME_CAPABILITIES
):
4874 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4876 case LOWORD(PKCS_ATTRIBUTES
):
4877 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4879 case LOWORD(X509_ISSUING_DIST_POINT
):
4880 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4882 case LOWORD(X509_NAME_CONSTRAINTS
):
4883 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4885 case LOWORD(PKCS7_SIGNER_INFO
):
4886 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4888 case LOWORD(CMS_SIGNER_INFO
):
4889 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
4893 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4894 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4895 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4896 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4897 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
4898 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4899 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4900 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4901 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4902 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4903 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4904 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4905 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4906 decodeFunc
= CRYPT_AsnDecodeBits
;
4907 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4908 decodeFunc
= CRYPT_AsnDecodeOctets
;
4909 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4910 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4911 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4912 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4913 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4914 decodeFunc
= CRYPT_AsnDecodeAltName
;
4915 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4916 decodeFunc
= CRYPT_AsnDecodeAltName
;
4917 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4918 decodeFunc
= CRYPT_AsnDecodeAltName
;
4919 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4920 decodeFunc
= CRYPT_AsnDecodeAltName
;
4921 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4922 decodeFunc
= CRYPT_AsnDecodeAltName
;
4923 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4924 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4925 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4926 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4927 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4928 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4929 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
4930 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4931 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
4932 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
4933 else if (!strcmp(lpszStructType
, szOID_CTL
))
4934 decodeFunc
= CRYPT_AsnDecodeCTL
;
4938 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
4939 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4941 static HCRYPTOIDFUNCSET set
= NULL
;
4942 CryptDecodeObjectFunc decodeFunc
= NULL
;
4945 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
4946 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4947 (void **)&decodeFunc
, hFunc
);
4951 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
4952 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4954 static HCRYPTOIDFUNCSET set
= NULL
;
4955 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4958 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4959 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4960 (void **)&decodeFunc
, hFunc
);
4964 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4965 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
4966 DWORD
*pcbStructInfo
)
4969 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
4970 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
4971 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4973 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
4974 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
4975 pvStructInfo
, pcbStructInfo
);
4977 if (!pvStructInfo
&& !pcbStructInfo
)
4979 SetLastError(ERROR_INVALID_PARAMETER
);
4984 SetLastError(CRYPT_E_ASN1_EOD
);
4987 if (cbEncoded
> MAX_ENCODED_LEN
)
4989 SetLastError(CRYPT_E_ASN1_LARGE
);
4993 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
4996 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4997 debugstr_a(lpszStructType
));
4998 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
4999 lpszStructType
, &hFunc
);
5000 if (!pCryptDecodeObject
)
5001 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5002 lpszStructType
, &hFunc
);
5004 if (pCryptDecodeObject
)
5005 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5006 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5007 else if (pCryptDecodeObjectEx
)
5008 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5009 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5010 pvStructInfo
, pcbStructInfo
);
5012 CryptFreeOIDFunctionAddress(hFunc
, 0);
5013 TRACE_(crypt
)("returning %d\n", ret
);
5017 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5018 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5019 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5022 CryptDecodeObjectExFunc decodeFunc
;
5023 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5025 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5026 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5027 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5029 if (!pvStructInfo
&& !pcbStructInfo
)
5031 SetLastError(ERROR_INVALID_PARAMETER
);
5036 SetLastError(CRYPT_E_ASN1_EOD
);
5039 if (cbEncoded
> MAX_ENCODED_LEN
)
5041 SetLastError(CRYPT_E_ASN1_LARGE
);
5045 SetLastError(NOERROR
);
5046 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5047 *(BYTE
**)pvStructInfo
= NULL
;
5048 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5051 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5052 debugstr_a(lpszStructType
));
5053 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5057 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5058 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5061 CryptDecodeObjectFunc pCryptDecodeObject
=
5062 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5064 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5065 * directly, as that could cause an infinite loop.
5067 if (pCryptDecodeObject
)
5069 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5071 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5072 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5073 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5074 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5075 ret
= pCryptDecodeObject(dwCertEncodingType
,
5076 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5077 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5080 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5081 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5085 CryptFreeOIDFunctionAddress(hFunc
, 0);
5086 TRACE_(crypt
)("returning %d\n", ret
);