2 * Copyright 2005-2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
67 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
68 DWORD
, DWORD
, void *, DWORD
*);
69 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
70 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
76 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
78 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
82 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
88 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
92 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
93 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
94 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
97 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
99 /* Doesn't check the tag, assumes the caller does so */
100 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
101 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
102 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
103 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
104 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
105 * member has been initialized, doesn't do exception handling, and doesn't do
106 * memory allocation. Also doesn't check tag, assumes the caller has checked
109 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
113 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
114 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
116 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
117 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
120 /* Gets the number of length bytes from the given (leading) length byte */
121 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
123 /* Helper function to get the encoded length of the data starting at pbEncoded,
124 * where pbEncoded[0] is the tag. If the data are too short to contain a
125 * length or if the length is too large for cbEncoded, sets an appropriate
126 * error code and returns FALSE. If the encoded length is unknown due to
127 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
129 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
136 SetLastError(CRYPT_E_ASN1_CORRUPT
);
139 else if (pbEncoded
[1] <= 0x7f)
141 if (pbEncoded
[1] + 1 > cbEncoded
)
143 SetLastError(CRYPT_E_ASN1_EOD
);
152 else if (pbEncoded
[1] == 0x80)
154 *len
= CMSG_INDEFINITE_LENGTH
;
159 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
161 if (lenLen
> sizeof(DWORD
) + 1)
163 SetLastError(CRYPT_E_ASN1_LARGE
);
166 else if (lenLen
+ 2 > cbEncoded
)
168 SetLastError(CRYPT_E_ASN1_CORRUPT
);
181 if (out
+ lenLen
+ 1 > cbEncoded
)
183 SetLastError(CRYPT_E_ASN1_EOD
);
196 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
197 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
201 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
202 *len
== CMSG_INDEFINITE_LENGTH
)
204 SetLastError(CRYPT_E_ASN1_CORRUPT
);
210 /* Helper function to check *pcbStructInfo, set it to the required size, and
211 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
212 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
213 * pointer to the newly allocated memory.
215 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
216 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
221 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
223 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
224 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
226 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
227 if (!*(BYTE
**)pvStructInfo
)
230 *pcbStructInfo
= bytesNeeded
;
232 else if (*pcbStructInfo
< bytesNeeded
)
234 *pcbStructInfo
= bytesNeeded
;
235 SetLastError(ERROR_MORE_DATA
);
239 *pcbStructInfo
= bytesNeeded
;
243 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
245 if (pDecodePara
&& pDecodePara
->pfnFree
)
246 pDecodePara
->pfnFree(pv
);
251 /* Helper function to check *pcbStructInfo and set it to the required size.
252 * Assumes pvStructInfo is not NULL.
254 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
258 if (*pcbStructInfo
< bytesNeeded
)
260 *pcbStructInfo
= bytesNeeded
;
261 SetLastError(ERROR_MORE_DATA
);
266 *pcbStructInfo
= bytesNeeded
;
273 * The expected tag of the item. If tag is 0, decodeFunc is called
274 * regardless of the tag value seen.
276 * A sequence is decoded into a struct. The offset member is the
277 * offset of this item within that struct.
279 * The decoder function to use. If this is NULL, then the member isn't
280 * decoded, but minSize space is reserved for it.
282 * The minimum amount of space occupied after decoding. You must set this.
284 * If true, and the tag doesn't match the expected tag for this item,
285 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
286 * filled with 0 for this member.
287 * hasPointer, pointerOffset:
288 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
289 * the offset within the struct of the data pointer (or to the
290 * first data pointer, if more than one exist).
292 * Used by CRYPT_AsnDecodeSequence, not for your use.
294 struct AsnDecodeSequenceItem
298 InternalDecodeFunc decodeFunc
;
306 /* Decodes the items in a sequence, where the items are described in items,
307 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
308 * pvStructInfo. nextData is a pointer to the memory location at which the
309 * first decoded item with a dynamic pointer should point.
310 * Upon decoding, *cbDecoded is the total number of bytes decoded.
311 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
313 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
314 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
315 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
318 DWORD i
, decoded
= 0;
319 const BYTE
*ptr
= pbEncoded
;
321 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
322 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
324 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
326 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
330 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
331 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
333 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
335 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
337 DWORD itemEncodedLen
;
339 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
340 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
342 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
343 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
345 TRACE("Setting next pointer to %p\n",
347 *(BYTE
**)((BYTE
*)pvStructInfo
+
348 items
[i
].pointerOffset
) = nextData
;
350 if (items
[i
].decodeFunc
)
355 TRACE("decoding item %d\n", i
);
357 TRACE("sizing item %d\n", i
);
358 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
359 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
360 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
361 : NULL
, &items
[i
].size
, &itemDecoded
);
364 /* Account for alignment padding */
365 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
366 TRACE("item %d size: %d\n", i
, items
[i
].size
);
367 if (nextData
&& items
[i
].hasPointer
&&
368 items
[i
].size
> items
[i
].minSize
)
369 nextData
+= items
[i
].size
- items
[i
].minSize
;
370 if (itemDecoded
> itemEncodedLen
)
372 WARN("decoded length %d exceeds encoded %d\n",
373 itemDecoded
, itemEncodedLen
);
374 SetLastError(CRYPT_E_ASN1_CORRUPT
);
380 decoded
+= itemDecoded
;
381 TRACE("item %d: decoded %d bytes\n", i
,
385 else if (items
[i
].optional
&&
386 GetLastError() == CRYPT_E_ASN1_BADTAG
)
388 TRACE("skipping optional item %d\n", i
);
389 items
[i
].size
= items
[i
].minSize
;
390 SetLastError(NOERROR
);
394 TRACE("item %d failed: %08x\n", i
,
397 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
399 ERR("can't use indefinite length encoding without a decoder\n");
400 SetLastError(CRYPT_E_ASN1_CORRUPT
);
405 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
406 ptr
+= itemEncodedLen
;
407 decoded
+= itemEncodedLen
;
408 items
[i
].size
= items
[i
].minSize
;
411 else if (items
[i
].optional
)
413 TRACE("skipping optional item %d\n", i
);
414 items
[i
].size
= items
[i
].minSize
;
418 TRACE("item %d: tag %02x doesn't match expected %02x\n",
419 i
, ptr
[0], items
[i
].tag
);
420 SetLastError(CRYPT_E_ASN1_BADTAG
);
425 else if (items
[i
].optional
)
427 TRACE("missing optional item %d, skipping\n", i
);
428 items
[i
].size
= items
[i
].minSize
;
432 TRACE("not enough bytes for item %d, failing\n", i
);
433 SetLastError(CRYPT_E_ASN1_CORRUPT
);
438 *cbDecoded
= decoded
;
439 TRACE("returning %d\n", ret
);
443 /* This decodes an arbitrary sequence into a contiguous block of memory
444 * (basically, a struct.) Each element being decoded is described by a struct
445 * AsnDecodeSequenceItem, see above.
446 * startingPointer is an optional pointer to the first place where dynamic
447 * data will be stored. If you know the starting offset, you may pass it
448 * here. Otherwise, pass NULL, and one will be inferred from the items.
450 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
451 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
452 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
453 DWORD
*pcbDecoded
, void *startingPointer
)
457 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
458 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
463 SetLastError(CRYPT_E_ASN1_EOD
);
466 if (pbEncoded
[0] == ASN_SEQUENCE
)
470 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
472 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
473 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
474 BOOL indefinite
= FALSE
;
476 cbEncoded
-= 1 + lenBytes
;
477 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
482 else if (cbEncoded
< dataLen
)
484 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
486 SetLastError(CRYPT_E_ASN1_CORRUPT
);
491 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
492 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
493 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
495 if (cbDecoded
> cbEncoded
- 2)
497 /* Not enough space for 0 TLV */
498 SetLastError(CRYPT_E_ASN1_CORRUPT
);
501 else if (*(ptr
+ cbDecoded
) != 0 ||
502 *(ptr
+ cbDecoded
+ 1) != 0)
504 TRACE("expected 0 TLV\n");
505 SetLastError(CRYPT_E_ASN1_CORRUPT
);
512 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
514 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
516 SetLastError(CRYPT_E_ASN1_CORRUPT
);
521 DWORD i
, bytesNeeded
= 0, structSize
= 0;
523 for (i
= 0; i
< cItem
; i
++)
525 bytesNeeded
+= items
[i
].size
;
526 structSize
+= items
[i
].minSize
;
529 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
531 *pcbStructInfo
= bytesNeeded
;
532 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
533 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
537 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
538 pvStructInfo
= *(BYTE
**)pvStructInfo
;
540 nextData
= startingPointer
;
542 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
543 memset(pvStructInfo
, 0, structSize
);
544 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
545 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
547 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
548 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
555 SetLastError(CRYPT_E_ASN1_BADTAG
);
558 TRACE("returning %d (%08x)\n", ret
, GetLastError());
563 * The expected tag of the entire encoded array (usually a variant
564 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
565 * regardless of the tag seen.
567 * used to decode each item in the array
569 * is the minimum size of each decoded item
571 * indicates whether each item has a dynamic pointer
573 * indicates the offset within itemSize at which the pointer exists
575 struct AsnArrayDescriptor
578 InternalDecodeFunc decodeFunc
;
584 struct AsnArrayItemSize
590 /* Decodes an array of like types into a struct GenericArray.
591 * The layout and decoding of the array are described by a struct
592 * AsnArrayDescriptor.
594 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
595 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
596 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
597 DWORD
*pcbDecoded
, void *startingPointer
)
601 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
602 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
605 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
609 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
611 DWORD bytesNeeded
, cItems
= 0, decoded
;
612 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
613 /* There can be arbitrarily many items, but there is often only one.
615 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
617 decoded
= 1 + lenBytes
;
618 bytesNeeded
= sizeof(struct GenericArray
);
622 BOOL doneDecoding
= FALSE
;
624 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
626 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
633 SetLastError(CRYPT_E_ASN1_CORRUPT
);
640 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
644 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
646 /* Each item decoded may not tolerate extraneous bytes,
647 * so get the length of the next element if known.
649 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
650 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
652 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
653 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
655 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
659 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
660 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
665 if (itemSizes
!= &itemSize
)
666 itemSizes
= CryptMemRealloc(itemSizes
,
667 cItems
* sizeof(struct AsnArrayItemSize
));
672 cItems
* sizeof(struct AsnArrayItemSize
));
674 memcpy(itemSizes
, &itemSize
,
679 decoded
+= itemDecoded
;
680 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
681 itemSizes
[cItems
- 1].size
= size
;
694 *pcbDecoded
= decoded
;
696 *pcbStructInfo
= bytesNeeded
;
697 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
698 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
703 struct GenericArray
*array
;
705 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
706 pvStructInfo
= *(BYTE
**)pvStructInfo
;
707 array
= pvStructInfo
;
708 array
->cItems
= cItems
;
710 array
->rgItems
= startingPointer
;
712 array
->rgItems
= (BYTE
*)array
+
713 sizeof(struct GenericArray
);
714 nextData
= array
->rgItems
+
715 array
->cItems
* arrayDesc
->itemSize
;
716 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
717 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
722 if (arrayDesc
->hasPointer
)
723 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
724 + arrayDesc
->pointerOffset
) = nextData
;
725 ret
= arrayDesc
->decodeFunc(ptr
,
726 itemSizes
[i
].encodedLen
,
727 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
728 array
->rgItems
+ i
* arrayDesc
->itemSize
,
729 &itemSizes
[i
].size
, &itemDecoded
);
732 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
736 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
737 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
740 if (itemSizes
!= &itemSize
)
741 CryptMemFree(itemSizes
);
746 SetLastError(CRYPT_E_ASN1_BADTAG
);
752 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
753 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
754 * to CRYPT_E_ASN1_CORRUPT.
755 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
758 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
759 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
764 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
766 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
767 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
769 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
770 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
773 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
775 *pcbStructInfo
= bytesNeeded
;
776 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
778 CRYPT_DER_BLOB
*blob
;
780 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
781 pvStructInfo
= *(BYTE
**)pvStructInfo
;
783 blob
->cbData
= 1 + lenBytes
+ dataLen
;
786 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
787 blob
->pbData
= (BYTE
*)pbEncoded
;
790 assert(blob
->pbData
);
791 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
796 SetLastError(CRYPT_E_ASN1_CORRUPT
);
804 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
805 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
806 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
811 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
812 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
814 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
817 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
818 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
820 if (ret
&& pvStructInfo
)
822 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
829 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
831 temp
= blob
->pbData
[i
];
832 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
833 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
837 TRACE("returning %d (%08x)\n", ret
, GetLastError());
841 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
842 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
843 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
847 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
848 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
852 struct AsnDecodeSequenceItem items
[] = {
853 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
854 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
855 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
856 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
857 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
858 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
859 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
860 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
861 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
862 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
865 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
866 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
867 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
868 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
869 pcbStructInfo
, NULL
, NULL
);
873 SetLastError(STATUS_ACCESS_VIOLATION
);
878 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
882 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
883 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
888 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
890 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
892 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
893 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
895 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
900 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
901 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
905 struct AsnDecodeSequenceItem items
[] = {
906 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
907 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
908 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
909 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
912 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
913 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
918 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
919 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
925 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
927 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
929 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
930 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
931 if (ret
&& pcbDecoded
)
932 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
937 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
938 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
939 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
942 struct AsnDecodeSequenceItem items
[] = {
943 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
944 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
945 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
946 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
947 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
948 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
949 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
950 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
951 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
952 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
954 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
955 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
957 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
958 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
960 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
961 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
962 FALSE
, TRUE
, offsetof(CERT_INFO
,
963 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
964 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
965 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
966 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
967 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
968 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
969 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
970 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
971 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
972 offsetof(CERT_INFO
, rgExtension
), 0 },
975 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
976 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
978 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
979 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
981 if (ret
&& pvStructInfo
)
985 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
986 info
= *(CERT_INFO
**)pvStructInfo
;
989 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
990 !info
->Subject
.cbData
)
992 SetLastError(CRYPT_E_ASN1_CORRUPT
);
993 /* Don't need to deallocate, because it should have failed on the
994 * first pass (and no memory was allocated.)
1000 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1004 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1005 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1006 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1010 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1011 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1017 /* Unless told not to, first try to decode it as a signed cert. */
1018 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1020 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1022 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1023 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1024 &signedCert
, &size
);
1028 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1029 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1030 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1031 pvStructInfo
, pcbStructInfo
);
1032 LocalFree(signedCert
);
1035 /* Failing that, try it as an unsigned cert */
1039 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1040 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1041 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1046 SetLastError(STATUS_ACCESS_VIOLATION
);
1050 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1054 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1055 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1058 struct AsnDecodeSequenceItem items
[] = {
1059 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1060 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1061 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1062 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1063 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1064 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1065 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1066 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1068 PCRL_ENTRY entry
= pvStructInfo
;
1070 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1073 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1074 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1075 entry
? entry
->SerialNumber
.pbData
: NULL
);
1076 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1078 WARN("empty CRL entry serial number\n");
1079 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1085 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1086 * been set prior to calling.
1088 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1089 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1092 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1093 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1094 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1095 struct GenericArray
*entries
= pvStructInfo
;
1097 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1098 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1100 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1101 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1102 entries
? entries
->rgItems
: NULL
);
1103 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1107 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1108 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1109 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1111 struct AsnDecodeSequenceItem items
[] = {
1112 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1113 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1114 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1115 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1116 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1117 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1118 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1120 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1121 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1122 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1123 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1124 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1125 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1126 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1127 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1128 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1129 offsetof(CRL_INFO
, rgExtension
), 0 },
1133 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1134 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1136 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1137 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1140 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1144 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1145 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1146 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1150 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1151 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1157 /* Unless told not to, first try to decode it as a signed crl. */
1158 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1160 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1162 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1163 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1168 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1169 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1170 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1171 pvStructInfo
, pcbStructInfo
);
1172 LocalFree(signedCrl
);
1175 /* Failing that, try it as an unsigned crl */
1179 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1180 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1181 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1186 SetLastError(STATUS_ACCESS_VIOLATION
);
1190 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1194 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1195 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1200 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1201 pvStructInfo
, *pcbStructInfo
);
1203 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1205 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1206 DWORD bytesNeeded
= sizeof(LPSTR
);
1210 /* The largest possible string for the first two components
1211 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1216 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1217 pbEncoded
[1 + lenBytes
] / 40,
1218 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1220 bytesNeeded
+= strlen(firstTwo
) + 1;
1221 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1222 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1224 /* large enough for ".4000000" */
1228 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1235 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1238 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1245 snprintf(str
, sizeof(str
), ".%d", val
);
1246 bytesNeeded
+= strlen(str
);
1251 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1253 *pcbStructInfo
= bytesNeeded
;
1254 else if (*pcbStructInfo
< bytesNeeded
)
1256 *pcbStructInfo
= bytesNeeded
;
1257 SetLastError(ERROR_MORE_DATA
);
1265 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1268 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1269 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1271 pszObjId
+= strlen(pszObjId
);
1272 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1273 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1277 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1286 sprintf(pszObjId
, ".%d", val
);
1287 pszObjId
+= strlen(pszObjId
);
1291 *(LPSTR
*)pvStructInfo
= NULL
;
1292 *pcbStructInfo
= bytesNeeded
;
1298 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1299 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1303 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1304 pvStructInfo
, *pcbStructInfo
);
1306 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1307 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1308 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1311 SetLastError(CRYPT_E_ASN1_BADTAG
);
1317 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1320 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1321 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1323 struct AsnDecodeSequenceItem items
[] = {
1324 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1325 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1326 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1327 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1328 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1329 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1330 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1331 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1334 PCERT_EXTENSION ext
= pvStructInfo
;
1336 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1340 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1341 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1342 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1343 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1345 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1346 debugstr_a(ext
->pszObjId
));
1347 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1351 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
1352 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1356 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1357 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1358 offsetof(CERT_EXTENSION
, pszObjId
) };
1359 PCERT_EXTENSIONS exts
= pvStructInfo
;
1361 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1362 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1364 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1365 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1366 exts
? exts
->rgExtension
: NULL
);
1370 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1371 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1372 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1378 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1379 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1380 if (ret
&& pvStructInfo
)
1382 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1383 pcbStructInfo
, *pcbStructInfo
);
1386 CERT_EXTENSIONS
*exts
;
1388 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1389 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1390 exts
= pvStructInfo
;
1391 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1392 sizeof(CERT_EXTENSIONS
));
1393 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1394 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1395 pcbStructInfo
, NULL
);
1401 SetLastError(STATUS_ACCESS_VIOLATION
);
1408 /* Warning: this assumes the address of value->Value.pbData is already set, in
1409 * order to avoid overwriting memory. (In some cases, it may change it, if it
1410 * doesn't copy anything to memory.) Be sure to set it correctly!
1412 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1413 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1418 CERT_NAME_VALUE
*value
= pvStructInfo
;
1420 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1422 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1423 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1425 switch (pbEncoded
[0])
1427 case ASN_OCTETSTRING
:
1428 valueType
= CERT_RDN_OCTET_STRING
;
1429 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1430 bytesNeeded
+= dataLen
;
1432 case ASN_NUMERICSTRING
:
1433 valueType
= CERT_RDN_NUMERIC_STRING
;
1434 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1435 bytesNeeded
+= dataLen
;
1437 case ASN_PRINTABLESTRING
:
1438 valueType
= CERT_RDN_PRINTABLE_STRING
;
1439 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1440 bytesNeeded
+= dataLen
;
1443 valueType
= CERT_RDN_IA5_STRING
;
1444 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1445 bytesNeeded
+= dataLen
;
1448 valueType
= CERT_RDN_T61_STRING
;
1449 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1450 bytesNeeded
+= dataLen
;
1452 case ASN_VIDEOTEXSTRING
:
1453 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1454 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1455 bytesNeeded
+= dataLen
;
1457 case ASN_GRAPHICSTRING
:
1458 valueType
= CERT_RDN_GRAPHIC_STRING
;
1459 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1460 bytesNeeded
+= dataLen
;
1462 case ASN_VISIBLESTRING
:
1463 valueType
= CERT_RDN_VISIBLE_STRING
;
1464 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1465 bytesNeeded
+= dataLen
;
1467 case ASN_GENERALSTRING
:
1468 valueType
= CERT_RDN_GENERAL_STRING
;
1469 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1470 bytesNeeded
+= dataLen
;
1472 case ASN_UNIVERSALSTRING
:
1473 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1474 SetLastError(CRYPT_E_ASN1_BADTAG
);
1477 valueType
= CERT_RDN_BMP_STRING
;
1478 bytesNeeded
+= dataLen
;
1480 case ASN_UTF8STRING
:
1481 valueType
= CERT_RDN_UTF8_STRING
;
1482 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1483 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1486 SetLastError(CRYPT_E_ASN1_BADTAG
);
1491 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1493 *pcbStructInfo
= bytesNeeded
;
1494 else if (*pcbStructInfo
< bytesNeeded
)
1496 *pcbStructInfo
= bytesNeeded
;
1497 SetLastError(ERROR_MORE_DATA
);
1502 *pcbStructInfo
= bytesNeeded
;
1503 value
->dwValueType
= valueType
;
1508 assert(value
->Value
.pbData
);
1509 switch (pbEncoded
[0])
1511 case ASN_OCTETSTRING
:
1512 case ASN_NUMERICSTRING
:
1513 case ASN_PRINTABLESTRING
:
1516 case ASN_VIDEOTEXSTRING
:
1517 case ASN_GRAPHICSTRING
:
1518 case ASN_VISIBLESTRING
:
1519 case ASN_GENERALSTRING
:
1520 value
->Value
.cbData
= dataLen
;
1523 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1524 memcpy(value
->Value
.pbData
,
1525 pbEncoded
+ 1 + lenBytes
, dataLen
);
1527 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1533 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1535 value
->Value
.cbData
= dataLen
;
1536 for (i
= 0; i
< dataLen
/ 2; i
++)
1537 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1538 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1541 case ASN_UTF8STRING
:
1543 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1545 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1546 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1547 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1554 value
->Value
.cbData
= 0;
1555 value
->Value
.pbData
= NULL
;
1562 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1563 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1564 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1570 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1571 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1572 if (ret
&& pvStructInfo
)
1574 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1575 pcbStructInfo
, *pcbStructInfo
);
1578 CERT_NAME_VALUE
*value
;
1580 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1581 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1582 value
= pvStructInfo
;
1583 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1584 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1585 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1586 pcbStructInfo
, NULL
);
1592 SetLastError(STATUS_ACCESS_VIOLATION
);
1599 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1600 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1605 CERT_NAME_VALUE
*value
= pvStructInfo
;
1607 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1609 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1610 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1612 switch (pbEncoded
[0])
1614 case ASN_NUMERICSTRING
:
1615 valueType
= CERT_RDN_NUMERIC_STRING
;
1617 bytesNeeded
+= (dataLen
+ 1) * 2;
1619 case ASN_PRINTABLESTRING
:
1620 valueType
= CERT_RDN_PRINTABLE_STRING
;
1622 bytesNeeded
+= (dataLen
+ 1) * 2;
1625 valueType
= CERT_RDN_IA5_STRING
;
1627 bytesNeeded
+= (dataLen
+ 1) * 2;
1630 valueType
= CERT_RDN_T61_STRING
;
1632 bytesNeeded
+= (dataLen
+ 1) * 2;
1634 case ASN_VIDEOTEXSTRING
:
1635 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1637 bytesNeeded
+= (dataLen
+ 1) * 2;
1639 case ASN_GRAPHICSTRING
:
1640 valueType
= CERT_RDN_GRAPHIC_STRING
;
1642 bytesNeeded
+= (dataLen
+ 1) * 2;
1644 case ASN_VISIBLESTRING
:
1645 valueType
= CERT_RDN_VISIBLE_STRING
;
1647 bytesNeeded
+= (dataLen
+ 1) * 2;
1649 case ASN_GENERALSTRING
:
1650 valueType
= CERT_RDN_GENERAL_STRING
;
1652 bytesNeeded
+= (dataLen
+ 1) * 2;
1654 case ASN_UNIVERSALSTRING
:
1655 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1657 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1660 valueType
= CERT_RDN_BMP_STRING
;
1662 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1664 case ASN_UTF8STRING
:
1665 valueType
= CERT_RDN_UTF8_STRING
;
1667 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1668 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1671 SetLastError(CRYPT_E_ASN1_BADTAG
);
1676 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1678 *pcbStructInfo
= bytesNeeded
;
1679 else if (*pcbStructInfo
< bytesNeeded
)
1681 *pcbStructInfo
= bytesNeeded
;
1682 SetLastError(ERROR_MORE_DATA
);
1687 *pcbStructInfo
= bytesNeeded
;
1688 value
->dwValueType
= valueType
;
1692 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1694 assert(value
->Value
.pbData
);
1695 switch (pbEncoded
[0])
1697 case ASN_NUMERICSTRING
:
1698 case ASN_PRINTABLESTRING
:
1701 case ASN_VIDEOTEXSTRING
:
1702 case ASN_GRAPHICSTRING
:
1703 case ASN_VISIBLESTRING
:
1704 case ASN_GENERALSTRING
:
1705 value
->Value
.cbData
= dataLen
* 2;
1706 for (i
= 0; i
< dataLen
; i
++)
1707 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1710 case ASN_UNIVERSALSTRING
:
1711 value
->Value
.cbData
= dataLen
/ 2;
1712 for (i
= 0; i
< dataLen
/ 4; i
++)
1713 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1714 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1718 value
->Value
.cbData
= dataLen
;
1719 for (i
= 0; i
< dataLen
/ 2; i
++)
1720 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1721 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1724 case ASN_UTF8STRING
:
1725 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1726 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1727 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1728 value
->Value
.pbData
[value
->Value
.cbData
/ sizeof(WCHAR
)]
1730 value
->Value
.cbData
+= sizeof(WCHAR
);
1736 value
->Value
.cbData
= 0;
1737 value
->Value
.pbData
= NULL
;
1744 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1745 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1746 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1752 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1753 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1754 if (ret
&& pvStructInfo
)
1756 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1757 pcbStructInfo
, *pcbStructInfo
);
1760 CERT_NAME_VALUE
*value
;
1762 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1763 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1764 value
= 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
= 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
= 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
= 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
= 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
= 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
= 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
= 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
= 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
= 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
= 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
= pvStructInfo
;
2189 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2190 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2191 capabilities
? capabilities
->rgCapability
: NULL
);
2195 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2196 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2197 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2201 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2202 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2209 SetLastError(CRYPT_E_ASN1_EOD
);
2210 else if (pbEncoded
[0] != ASN_SEQUENCEOF
)
2211 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2212 else if ((ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2213 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2217 *pcbStructInfo
= bytesNeeded
;
2218 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2219 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2221 PCRYPT_SMIME_CAPABILITIES capabilities
;
2223 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2224 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2225 capabilities
= pvStructInfo
;
2226 capabilities
->rgCapability
=
2227 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2228 sizeof(CRYPT_SMIME_CAPABILITIES
));
2229 ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2230 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2231 &bytesNeeded
, NULL
);
2237 SetLastError(STATUS_ACCESS_VIOLATION
);
2240 TRACE("returning %d\n", ret
);
2244 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2245 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2250 LPSTR
*pStr
= pvStructInfo
;
2252 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2254 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2255 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2257 if (pbEncoded
[0] != ASN_IA5STRING
)
2259 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2264 bytesNeeded
+= dataLen
;
2266 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2268 *pcbStructInfo
= bytesNeeded
;
2269 else if (*pcbStructInfo
< bytesNeeded
)
2271 *pcbStructInfo
= bytesNeeded
;
2272 SetLastError(ERROR_MORE_DATA
);
2277 *pcbStructInfo
= bytesNeeded
;
2283 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2294 static BOOL
CRYPT_AsnDecodeIntArray(const BYTE
*pbEncoded
,
2295 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2298 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2299 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2300 struct GenericArray
*array
= pvStructInfo
;
2303 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2304 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2306 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2307 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2308 array
? array
->rgItems
: NULL
);
2309 TRACE("returning %d\n", ret
);
2313 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2314 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2318 struct AsnDecodeSequenceItem items
[] = {
2319 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2320 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2321 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2322 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2323 cNoticeNumbers
), CRYPT_AsnDecodeIntArray
, sizeof(struct GenericArray
),
2324 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2325 rgNoticeNumbers
), 0 },
2329 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2330 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2332 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2333 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2337 /* The caller is expecting a pointer to a
2338 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2339 * CRYPT_AsnDecodeSequence is decoding a
2340 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2341 * needed, and decode again if the requisite space is available.
2343 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2345 *pcbStructInfo
= bytesNeeded
;
2346 else if (*pcbStructInfo
< bytesNeeded
)
2348 *pcbStructInfo
= bytesNeeded
;
2349 SetLastError(ERROR_MORE_DATA
);
2354 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2356 *pcbStructInfo
= bytesNeeded
;
2357 /* The pointer (pvStructInfo) passed in points to the first dynamic
2358 * pointer, so use it as the pointer to the
2359 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2360 * appropriate offset for the first dynamic pointer within the
2361 * notice reference by pointing to the first memory location past
2362 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2365 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2366 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2367 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2368 ret
= CRYPT_AsnDecodeSequence(items
,
2369 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2370 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2371 noticeRef
->pszOrganization
);
2374 TRACE("returning %d\n", ret
);
2378 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2379 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2385 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2387 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2388 DWORD bytesNeeded
= sizeof(LPWSTR
);
2390 switch (pbEncoded
[0])
2392 case ASN_NUMERICSTRING
:
2394 bytesNeeded
+= (dataLen
+ 1) * 2;
2396 case ASN_PRINTABLESTRING
:
2398 bytesNeeded
+= (dataLen
+ 1) * 2;
2402 bytesNeeded
+= (dataLen
+ 1) * 2;
2406 bytesNeeded
+= (dataLen
+ 1) * 2;
2408 case ASN_VIDEOTEXSTRING
:
2410 bytesNeeded
+= (dataLen
+ 1) * 2;
2412 case ASN_GRAPHICSTRING
:
2414 bytesNeeded
+= (dataLen
+ 1) * 2;
2416 case ASN_VISIBLESTRING
:
2418 bytesNeeded
+= (dataLen
+ 1) * 2;
2420 case ASN_GENERALSTRING
:
2422 bytesNeeded
+= (dataLen
+ 1) * 2;
2424 case ASN_UNIVERSALSTRING
:
2426 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2430 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2432 case ASN_UTF8STRING
:
2434 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2435 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2438 SetLastError(CRYPT_E_ASN1_BADTAG
);
2443 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2445 *pcbStructInfo
= bytesNeeded
;
2446 else if (*pcbStructInfo
< bytesNeeded
)
2448 *pcbStructInfo
= bytesNeeded
;
2449 SetLastError(ERROR_MORE_DATA
);
2454 LPWSTR
*pStr
= pvStructInfo
;
2456 *pcbStructInfo
= bytesNeeded
;
2460 LPWSTR str
= *(LPWSTR
*)pStr
;
2463 switch (pbEncoded
[0])
2465 case ASN_NUMERICSTRING
:
2466 case ASN_PRINTABLESTRING
:
2469 case ASN_VIDEOTEXSTRING
:
2470 case ASN_GRAPHICSTRING
:
2471 case ASN_VISIBLESTRING
:
2472 case ASN_GENERALSTRING
:
2473 for (i
= 0; i
< dataLen
; i
++)
2474 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2477 case ASN_UNIVERSALSTRING
:
2478 for (i
= 0; i
< dataLen
/ 4; i
++)
2479 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2480 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2484 for (i
= 0; i
< dataLen
/ 2; i
++)
2485 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2486 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2489 case ASN_UTF8STRING
:
2491 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2492 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2493 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2506 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2507 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2508 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2511 struct AsnDecodeSequenceItem items
[] = {
2512 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2513 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2514 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2515 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2516 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2517 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2518 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2520 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2522 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2523 pvStructInfo
, *pcbStructInfo
);
2525 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2526 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2527 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2528 TRACE("returning %d\n", ret
);
2532 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2533 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2534 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2535 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2539 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2540 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2546 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2547 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2552 *pcbStructInfo
= bytesNeeded
;
2553 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2554 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2556 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2558 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2559 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2560 notice
= pvStructInfo
;
2561 notice
->pNoticeReference
=
2562 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2563 ((BYTE
*)pvStructInfo
+
2564 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2565 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2566 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2567 pvStructInfo
, &bytesNeeded
, NULL
);
2573 SetLastError(STATUS_ACCESS_VIOLATION
);
2576 TRACE("returning %d\n", ret
);
2580 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2581 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2585 struct AsnDecodeSequenceItem items
[] = {
2586 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2587 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2588 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2589 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2590 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
2591 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2593 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2595 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2596 pvStructInfo
, *pcbStructInfo
);
2598 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2599 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2600 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2601 TRACE("returning %d\n", ret
);
2605 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2606 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2607 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2611 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2612 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2618 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2619 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2623 *pcbStructInfo
= bytesNeeded
;
2624 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2625 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2627 PCRYPT_ATTRIBUTE attr
;
2629 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2630 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2631 attr
= pvStructInfo
;
2632 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2633 sizeof(CRYPT_ATTRIBUTE
));
2634 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2635 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2642 SetLastError(STATUS_ACCESS_VIOLATION
);
2645 TRACE("returning %d\n", ret
);
2649 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2650 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2653 struct AsnArrayDescriptor arrayDesc
= { 0,
2654 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2655 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2656 PCRYPT_ATTRIBUTES attrs
= pvStructInfo
;
2659 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2660 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2665 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2666 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2667 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2671 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2672 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2679 SetLastError(CRYPT_E_ASN1_EOD
);
2680 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2681 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2682 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2683 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2687 *pcbStructInfo
= bytesNeeded
;
2688 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2689 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2691 PCRYPT_ATTRIBUTES attrs
;
2693 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2694 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2695 attrs
= pvStructInfo
;
2696 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2697 sizeof(CRYPT_ATTRIBUTES
));
2698 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2699 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2700 &bytesNeeded
, NULL
);
2706 SetLastError(STATUS_ACCESS_VIOLATION
);
2709 TRACE("returning %d\n", ret
);
2713 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2714 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2716 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2718 struct AsnDecodeSequenceItem items
[] = {
2719 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2720 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2721 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2722 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2723 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2724 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2727 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2728 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2730 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2731 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2732 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2733 if (ret
&& pvStructInfo
)
2735 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2736 debugstr_a(algo
->pszObjId
));
2741 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2742 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2746 struct AsnDecodeSequenceItem items
[] = {
2747 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2748 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2749 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2750 Algorithm
.pszObjId
) },
2751 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2752 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2753 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2755 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2757 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2758 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2759 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2763 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2764 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2765 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2773 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2774 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2777 *pcbStructInfo
= bytesNeeded
;
2778 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2779 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2781 PCERT_PUBLIC_KEY_INFO info
;
2783 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2784 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2785 info
= pvStructInfo
;
2786 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2787 sizeof(CERT_PUBLIC_KEY_INFO
);
2788 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2789 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2790 &bytesNeeded
, NULL
);
2796 SetLastError(STATUS_ACCESS_VIOLATION
);
2803 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2804 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2810 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2813 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2815 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2818 if (pbEncoded
[1] > 1)
2820 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2827 *pcbStructInfo
= sizeof(BOOL
);
2830 else if (*pcbStructInfo
< sizeof(BOOL
))
2832 *pcbStructInfo
= sizeof(BOOL
);
2833 SetLastError(ERROR_MORE_DATA
);
2838 *pcbStructInfo
= sizeof(BOOL
);
2839 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2842 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2846 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2847 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2849 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2850 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2853 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2854 pvStructInfo
, *pcbStructInfo
);
2858 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2861 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2862 if (1 + lenBytes
> cbEncoded
)
2864 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2867 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2869 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2871 case 1: /* rfc822Name */
2872 case 2: /* dNSName */
2873 case 6: /* uniformResourceIdentifier */
2874 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2876 case 4: /* directoryName */
2877 case 7: /* iPAddress */
2878 bytesNeeded
+= dataLen
;
2880 case 8: /* registeredID */
2881 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2885 /* FIXME: ugly, shouldn't need to know internals of OID decode
2886 * function to use it.
2888 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2891 case 0: /* otherName */
2892 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2893 SetLastError(CRYPT_E_ASN1_BADTAG
);
2896 case 3: /* x400Address, unimplemented */
2897 case 5: /* ediPartyName, unimplemented */
2898 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2899 SetLastError(CRYPT_E_ASN1_BADTAG
);
2903 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2904 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2910 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2912 *pcbStructInfo
= bytesNeeded
;
2913 else if (*pcbStructInfo
< bytesNeeded
)
2915 *pcbStructInfo
= bytesNeeded
;
2916 SetLastError(ERROR_MORE_DATA
);
2921 *pcbStructInfo
= bytesNeeded
;
2922 /* MS used values one greater than the asn1 ones.. sigh */
2923 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
2924 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2926 case 1: /* rfc822Name */
2927 case 2: /* dNSName */
2928 case 6: /* uniformResourceIdentifier */
2932 for (i
= 0; i
< dataLen
; i
++)
2933 entry
->u
.pwszURL
[i
] =
2934 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2935 entry
->u
.pwszURL
[i
] = 0;
2936 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2937 debugstr_w(entry
->u
.pwszURL
));
2940 case 4: /* directoryName */
2941 /* The data are memory-equivalent with the IPAddress case,
2944 case 7: /* iPAddress */
2945 /* The next data pointer is in the pwszURL spot, that is,
2946 * the first 4 bytes. Need to move it to the next spot.
2948 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2949 entry
->u
.IPAddress
.cbData
= dataLen
;
2950 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2953 case 8: /* registeredID */
2954 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2955 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2964 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
2965 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2969 struct AsnArrayDescriptor arrayDesc
= { 0,
2970 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2971 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2972 PCERT_ALT_NAME_INFO info
= pvStructInfo
;
2974 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2975 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2978 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2979 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2980 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2981 info
? info
->rgAltEntry
: NULL
);
2985 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2986 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
2987 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2992 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2993 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2995 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2998 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
2999 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
3001 if (ret
&& pvStructInfo
)
3003 CRYPT_DATA_BLOB
*blob
= pvStructInfo
;
3010 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
3012 temp
= blob
->pbData
[i
];
3013 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
3014 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
3018 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3022 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3023 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3024 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3030 struct AsnDecodeSequenceItem items
[] = {
3031 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3032 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3033 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3034 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3035 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3036 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3037 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3038 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3039 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3040 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3041 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3044 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3045 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3046 pcbStructInfo
, NULL
, NULL
);
3050 SetLastError(STATUS_ACCESS_VIOLATION
);
3057 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3058 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3059 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3065 struct AsnDecodeSequenceItem items
[] = {
3066 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3067 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3068 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3069 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3070 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3071 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3072 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3073 AuthorityCertIssuer
.rgAltEntry
), 0 },
3074 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3075 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3076 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3077 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3078 AuthorityCertSerialNumber
.pbData
), 0 },
3081 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3082 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3083 pcbStructInfo
, NULL
, NULL
);
3087 SetLastError(STATUS_ACCESS_VIOLATION
);
3094 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3095 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3098 struct AsnDecodeSequenceItem items
[] = {
3099 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3100 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3101 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3102 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3103 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3104 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3106 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3108 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3109 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3110 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3113 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3114 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3115 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3119 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3120 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3124 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3125 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3126 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3128 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3129 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3133 SetLastError(STATUS_ACCESS_VIOLATION
);
3140 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3141 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3146 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3147 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3149 /* The caller has already checked the tag, no need to check it again.
3150 * Check the outer length is valid:
3152 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3154 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3157 pbEncoded
+= 1 + lenBytes
;
3158 cbEncoded
-= 1 + lenBytes
;
3159 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3160 cbEncoded
-= 2; /* space for 0 TLV */
3161 /* Check the inner length is valid: */
3162 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3166 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3167 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3168 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3170 if (*(pbEncoded
+ decodedLen
) != 0 ||
3171 *(pbEncoded
+ decodedLen
+ 1) != 0)
3173 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3174 *(pbEncoded
+ decodedLen
),
3175 *(pbEncoded
+ decodedLen
+ 1));
3176 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3182 if (ret
&& pcbDecoded
)
3184 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3185 TRACE("decoded %d bytes\n", *pcbDecoded
);
3192 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3193 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3196 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3197 struct AsnDecodeSequenceItem items
[] = {
3198 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3199 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3200 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3201 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3202 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3203 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3204 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3208 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3209 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3211 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3212 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3213 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3217 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3218 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3219 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3223 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3224 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3228 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3229 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3230 if (ret
&& pvStructInfo
)
3232 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3233 pcbStructInfo
, *pcbStructInfo
);
3236 CRYPT_CONTENT_INFO
*info
;
3238 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3239 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3240 info
= pvStructInfo
;
3241 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3242 sizeof(CRYPT_CONTENT_INFO
));
3243 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3244 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3245 pcbStructInfo
, NULL
);
3251 SetLastError(STATUS_ACCESS_VIOLATION
);
3257 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3258 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3259 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3262 struct AsnDecodeSequenceItem items
[] = {
3263 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3264 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3265 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3266 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3267 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3269 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3270 CRYPT_AsnDecodePKCSContentInfoInternal
,
3271 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3272 ContentInfo
.pszObjId
), 0 },
3273 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3274 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3275 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3278 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3279 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3284 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3285 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3286 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3290 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3291 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3297 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3298 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3301 *pcbStructInfo
= bytesNeeded
;
3302 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3303 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3305 CERT_ALT_NAME_INFO
*name
;
3307 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3308 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3309 name
= pvStructInfo
;
3310 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3311 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3312 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3313 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3314 &bytesNeeded
, NULL
);
3320 SetLastError(STATUS_ACCESS_VIOLATION
);
3327 struct PATH_LEN_CONSTRAINT
3329 BOOL fPathLenConstraint
;
3330 DWORD dwPathLenConstraint
;
3333 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3334 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3338 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3340 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3341 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3345 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3347 *pcbStructInfo
= bytesNeeded
;
3349 else if (*pcbStructInfo
< bytesNeeded
)
3351 SetLastError(ERROR_MORE_DATA
);
3352 *pcbStructInfo
= bytesNeeded
;
3357 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3359 *pcbStructInfo
= bytesNeeded
;
3360 size
= sizeof(constraint
->dwPathLenConstraint
);
3361 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3362 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3364 constraint
->fPathLenConstraint
= TRUE
;
3365 TRACE("got an int, dwPathLenConstraint is %d\n",
3366 constraint
->dwPathLenConstraint
);
3368 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3372 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3373 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3377 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3378 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3379 offsetof(CERT_NAME_BLOB
, pbData
) };
3380 struct GenericArray
*entries
= pvStructInfo
;
3382 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3383 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3385 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3386 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3387 entries
? entries
->rgItems
: NULL
);
3388 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3392 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3393 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3394 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3400 struct AsnDecodeSequenceItem items
[] = {
3401 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3402 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3403 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3404 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3405 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3406 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3407 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3408 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3409 sizeof(struct GenericArray
), TRUE
, TRUE
,
3410 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3413 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3414 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3415 pcbStructInfo
, NULL
, NULL
);
3419 SetLastError(STATUS_ACCESS_VIOLATION
);
3426 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3427 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3428 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3434 struct AsnDecodeSequenceItem items
[] = {
3435 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3436 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3437 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3438 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3439 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3442 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3443 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3444 pcbStructInfo
, NULL
, NULL
);
3448 SetLastError(STATUS_ACCESS_VIOLATION
);
3455 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3456 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3459 struct AsnDecodeSequenceItem items
[] = {
3460 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3461 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3462 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3464 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3465 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3466 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3469 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3471 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3472 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3474 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3475 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3476 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3480 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3481 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3485 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3486 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3487 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3488 struct GenericArray
*entries
= pvStructInfo
;
3490 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3491 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3493 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3494 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3495 entries
? entries
->rgItems
: NULL
);
3496 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3500 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3501 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3503 struct AsnDecodeSequenceItem items
[] = {
3504 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3505 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3506 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3507 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3508 CRYPT_AsnDecodePolicyQualifiers
, sizeof(struct GenericArray
), TRUE
,
3509 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3511 CERT_POLICY_INFO
*info
= pvStructInfo
;
3514 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3515 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3517 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3518 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3519 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3523 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3524 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3525 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3529 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3530 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3534 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3535 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3536 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3538 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3539 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3543 SetLastError(STATUS_ACCESS_VIOLATION
);
3549 #define RSA1_MAGIC 0x31415352
3551 struct DECODED_RSA_PUB_KEY
3554 CRYPT_INTEGER_BLOB modulus
;
3557 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3558 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3559 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3565 struct AsnDecodeSequenceItem items
[] = {
3566 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3567 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3568 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3570 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3571 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3573 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3576 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3577 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3581 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3582 decodedKey
->modulus
.cbData
;
3586 *pcbStructInfo
= bytesNeeded
;
3589 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3590 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3593 RSAPUBKEY
*rsaPubKey
;
3595 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3596 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3598 hdr
->bType
= PUBLICKEYBLOB
;
3599 hdr
->bVersion
= CUR_BLOB_VERSION
;
3601 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3602 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3603 sizeof(BLOBHEADER
));
3604 rsaPubKey
->magic
= RSA1_MAGIC
;
3605 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3606 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3607 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3608 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3609 decodedKey
->modulus
.cbData
);
3611 LocalFree(decodedKey
);
3616 SetLastError(STATUS_ACCESS_VIOLATION
);
3623 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3624 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3628 DWORD bytesNeeded
, dataLen
;
3630 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3631 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3633 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3635 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3637 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3638 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3640 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3642 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3644 *pcbStructInfo
= bytesNeeded
;
3645 else if (*pcbStructInfo
< bytesNeeded
)
3647 SetLastError(ERROR_MORE_DATA
);
3648 *pcbStructInfo
= bytesNeeded
;
3653 CRYPT_DATA_BLOB
*blob
;
3655 *pcbStructInfo
= bytesNeeded
;
3656 blob
= pvStructInfo
;
3657 blob
->cbData
= dataLen
;
3658 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3659 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3662 assert(blob
->pbData
);
3664 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3672 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3673 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3674 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3678 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3679 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3687 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3690 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3692 SetLastError(CRYPT_E_ASN1_BADTAG
);
3695 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3696 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3699 *pcbStructInfo
= bytesNeeded
;
3700 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3701 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3703 CRYPT_DATA_BLOB
*blob
;
3705 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3706 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3707 blob
= pvStructInfo
;
3708 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3709 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3710 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3711 &bytesNeeded
, NULL
);
3717 SetLastError(STATUS_ACCESS_VIOLATION
);
3724 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3725 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3728 DWORD bytesNeeded
, dataLen
;
3729 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3731 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3732 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3734 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3736 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3737 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3739 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3741 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3743 *pcbStructInfo
= bytesNeeded
;
3744 else if (*pcbStructInfo
< bytesNeeded
)
3746 *pcbStructInfo
= bytesNeeded
;
3747 SetLastError(ERROR_MORE_DATA
);
3752 CRYPT_BIT_BLOB
*blob
;
3754 *pcbStructInfo
= bytesNeeded
;
3755 blob
= pvStructInfo
;
3756 blob
->cbData
= dataLen
- 1;
3757 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3758 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3760 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3764 assert(blob
->pbData
);
3767 BYTE mask
= 0xff << blob
->cUnusedBits
;
3769 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3771 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3779 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3780 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3781 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3785 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3786 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3794 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3797 else if (pbEncoded
[0] != ASN_BITSTRING
)
3799 SetLastError(CRYPT_E_ASN1_BADTAG
);
3802 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3803 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3806 *pcbStructInfo
= bytesNeeded
;
3807 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3808 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3810 CRYPT_BIT_BLOB
*blob
;
3812 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3813 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3814 blob
= pvStructInfo
;
3815 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3816 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3817 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3818 &bytesNeeded
, NULL
);
3824 SetLastError(STATUS_ACCESS_VIOLATION
);
3828 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3832 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3833 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3834 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3837 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3838 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3839 DWORD size
= sizeof(buf
);
3841 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3842 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
3847 *pcbStructInfo
= sizeof(int);
3848 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3852 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3854 /* initialize to a negative value to sign-extend */
3859 for (i
= 0; i
< blob
->cbData
; i
++)
3862 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3864 memcpy(pvStructInfo
, &val
, sizeof(int));
3867 else if (GetLastError() == ERROR_MORE_DATA
)
3868 SetLastError(CRYPT_E_ASN1_LARGE
);
3872 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3873 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3874 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3884 SetLastError(CRYPT_E_ASN1_EOD
);
3887 else if (pbEncoded
[0] != ASN_INTEGER
)
3889 SetLastError(CRYPT_E_ASN1_BADTAG
);
3893 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3894 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3898 *pcbStructInfo
= bytesNeeded
;
3899 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3900 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3902 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3903 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3904 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3905 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3906 &bytesNeeded
, NULL
);
3912 SetLastError(STATUS_ACCESS_VIOLATION
);
3919 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
3920 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3924 DWORD bytesNeeded
, dataLen
;
3926 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3928 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3930 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3932 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3934 *pcbStructInfo
= bytesNeeded
;
3935 else if (*pcbStructInfo
< bytesNeeded
)
3937 *pcbStructInfo
= bytesNeeded
;
3938 SetLastError(ERROR_MORE_DATA
);
3943 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
3945 *pcbStructInfo
= bytesNeeded
;
3946 blob
->cbData
= dataLen
;
3947 assert(blob
->pbData
);
3952 for (i
= 0; i
< blob
->cbData
; i
++)
3954 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3963 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3964 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3965 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3973 if (pbEncoded
[0] != ASN_INTEGER
)
3975 SetLastError(CRYPT_E_ASN1_BADTAG
);
3979 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3980 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3984 *pcbStructInfo
= bytesNeeded
;
3985 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3986 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3988 CRYPT_INTEGER_BLOB
*blob
;
3990 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3991 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3992 blob
= pvStructInfo
;
3993 blob
->pbData
= (BYTE
*)pvStructInfo
+
3994 sizeof(CRYPT_INTEGER_BLOB
);
3995 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3996 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3997 &bytesNeeded
, NULL
);
4003 SetLastError(STATUS_ACCESS_VIOLATION
);
4010 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4011 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4016 if (pbEncoded
[0] == ASN_INTEGER
)
4018 DWORD bytesNeeded
, dataLen
;
4020 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4022 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4025 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4026 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4028 *pcbStructInfo
= bytesNeeded
;
4029 else if (*pcbStructInfo
< bytesNeeded
)
4031 *pcbStructInfo
= bytesNeeded
;
4032 SetLastError(ERROR_MORE_DATA
);
4037 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4039 *pcbStructInfo
= bytesNeeded
;
4040 blob
->cbData
= dataLen
;
4041 assert(blob
->pbData
);
4042 /* remove leading zero byte if it exists */
4043 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4052 for (i
= 0; i
< blob
->cbData
; i
++)
4054 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4063 SetLastError(CRYPT_E_ASN1_BADTAG
);
4069 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4070 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4071 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4079 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4080 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4083 *pcbStructInfo
= bytesNeeded
;
4084 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4085 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4087 CRYPT_INTEGER_BLOB
*blob
;
4089 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4090 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4091 blob
= pvStructInfo
;
4092 blob
->pbData
= (BYTE
*)pvStructInfo
+
4093 sizeof(CRYPT_INTEGER_BLOB
);
4094 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4095 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4096 &bytesNeeded
, NULL
);
4102 SetLastError(STATUS_ACCESS_VIOLATION
);
4109 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4110 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4111 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4117 *pcbStructInfo
= sizeof(int);
4122 if (pbEncoded
[0] == ASN_ENUMERATED
)
4124 unsigned int val
= 0, i
;
4128 SetLastError(CRYPT_E_ASN1_EOD
);
4131 else if (pbEncoded
[1] == 0)
4133 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4138 /* A little strange looking, but we have to accept a sign byte:
4139 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4140 * assuming a small length is okay here, it has to be in short
4143 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4145 SetLastError(CRYPT_E_ASN1_LARGE
);
4148 for (i
= 0; i
< pbEncoded
[1]; i
++)
4151 val
|= pbEncoded
[2 + i
];
4153 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4154 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4156 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4157 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4158 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4164 SetLastError(CRYPT_E_ASN1_BADTAG
);
4170 SetLastError(STATUS_ACCESS_VIOLATION
);
4177 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4180 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4185 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4187 if (!isdigit(*(pbEncoded))) \
4189 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4195 (word) += *(pbEncoded)++ - '0'; \
4200 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4201 SYSTEMTIME
*sysTime
)
4205 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4207 WORD hours
, minutes
= 0;
4208 BYTE sign
= *pbEncoded
++;
4211 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4212 if (ret
&& hours
>= 24)
4214 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4219 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4220 if (ret
&& minutes
>= 60)
4222 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4230 sysTime
->wHour
+= hours
;
4231 sysTime
->wMinute
+= minutes
;
4235 if (hours
> sysTime
->wHour
)
4238 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4241 sysTime
->wHour
-= hours
;
4242 if (minutes
> sysTime
->wMinute
)
4245 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4248 sysTime
->wMinute
-= minutes
;
4255 #define MIN_ENCODED_TIME_LENGTH 10
4257 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4258 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4263 if (pbEncoded
[0] == ASN_UTCTIME
)
4266 SetLastError(CRYPT_E_ASN1_EOD
);
4267 else if (pbEncoded
[1] > 0x7f)
4269 /* long-form date strings really can't be valid */
4270 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4274 SYSTEMTIME sysTime
= { 0 };
4275 BYTE len
= pbEncoded
[1];
4277 if (len
< MIN_ENCODED_TIME_LENGTH
)
4278 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4283 *pcbDecoded
= 2 + len
;
4285 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4286 if (sysTime
.wYear
>= 50)
4287 sysTime
.wYear
+= 1900;
4289 sysTime
.wYear
+= 2000;
4290 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4291 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4292 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4293 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4296 if (len
>= 2 && isdigit(*pbEncoded
) &&
4297 isdigit(*(pbEncoded
+ 1)))
4298 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4300 else if (isdigit(*pbEncoded
))
4301 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4304 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4310 *pcbStructInfo
= sizeof(FILETIME
);
4311 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4313 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4319 SetLastError(CRYPT_E_ASN1_BADTAG
);
4323 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4324 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4325 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4333 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4334 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4338 *pcbStructInfo
= bytesNeeded
;
4339 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4340 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4342 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4343 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4344 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4345 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4346 &bytesNeeded
, NULL
);
4352 SetLastError(STATUS_ACCESS_VIOLATION
);
4358 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4359 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4364 if (pbEncoded
[0] == ASN_GENERALTIME
)
4367 SetLastError(CRYPT_E_ASN1_EOD
);
4368 else if (pbEncoded
[1] > 0x7f)
4370 /* long-form date strings really can't be valid */
4371 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4375 BYTE len
= pbEncoded
[1];
4377 if (len
< MIN_ENCODED_TIME_LENGTH
)
4378 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4381 SYSTEMTIME sysTime
= { 0 };
4385 *pcbDecoded
= 2 + len
;
4387 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4388 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4389 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4390 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4393 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4396 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4398 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4405 /* workaround macro weirdness */
4406 digits
= min(len
, 3);
4407 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4408 sysTime
.wMilliseconds
);
4411 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4417 *pcbStructInfo
= sizeof(FILETIME
);
4418 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4420 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4426 SetLastError(CRYPT_E_ASN1_BADTAG
);
4430 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4431 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4435 InternalDecodeFunc decode
= NULL
;
4437 if (pbEncoded
[0] == ASN_UTCTIME
)
4438 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4439 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4440 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4442 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4443 pcbStructInfo
, pcbDecoded
);
4446 SetLastError(CRYPT_E_ASN1_BADTAG
);
4452 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4453 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4454 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4462 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4463 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4467 *pcbStructInfo
= bytesNeeded
;
4468 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4469 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4471 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4472 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4473 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4474 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4475 &bytesNeeded
, NULL
);
4481 SetLastError(STATUS_ACCESS_VIOLATION
);
4488 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4489 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4490 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4496 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4498 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4500 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4505 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4506 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4508 ptr
= pbEncoded
+ 1 + lenBytes
;
4509 remainingLen
= dataLen
;
4510 while (ret
&& remainingLen
)
4514 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4517 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4519 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4520 ptr
+= 1 + nextLenBytes
+ nextLen
;
4521 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4522 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4523 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4529 CRYPT_SEQUENCE_OF_ANY
*seq
;
4534 *pcbStructInfo
= bytesNeeded
;
4535 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4536 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4538 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4539 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4541 seq
->cValue
= cValue
;
4542 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4544 nextPtr
= (BYTE
*)seq
->rgValue
+
4545 cValue
* sizeof(CRYPT_DER_BLOB
);
4546 ptr
= pbEncoded
+ 1 + lenBytes
;
4547 remainingLen
= dataLen
;
4549 while (ret
&& remainingLen
)
4553 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4556 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4558 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4560 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4561 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4564 seq
->rgValue
[i
].pbData
= nextPtr
;
4565 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4567 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4569 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4570 ptr
+= 1 + nextLenBytes
+ nextLen
;
4580 SetLastError(CRYPT_E_ASN1_BADTAG
);
4586 SetLastError(STATUS_ACCESS_VIOLATION
);
4593 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4594 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4599 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4601 DWORD bytesNeeded
, dataLen
;
4603 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4605 struct AsnArrayDescriptor arrayDesc
= {
4606 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
4607 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4608 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4609 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4614 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4615 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4616 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
4617 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4618 * as the sizeof(struct GenericArray), so don't include it in the
4619 * total bytes needed.
4621 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4622 sizeof(CERT_ALT_NAME_INFO
);
4625 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4627 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4629 *pcbStructInfo
= bytesNeeded
;
4630 else if (*pcbStructInfo
< bytesNeeded
)
4632 *pcbStructInfo
= bytesNeeded
;
4633 SetLastError(ERROR_MORE_DATA
);
4638 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4640 *pcbStructInfo
= bytesNeeded
;
4643 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4644 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4645 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4646 0, NULL
, &name
->u
.FullName
, &nameLen
, NULL
,
4647 name
->u
.FullName
.rgAltEntry
);
4650 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4656 SetLastError(CRYPT_E_ASN1_BADTAG
);
4662 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4663 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4665 struct AsnDecodeSequenceItem items
[] = {
4666 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4667 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4668 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4669 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4670 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4671 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4672 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4673 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4674 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4675 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4677 CRL_DIST_POINT
*point
= pvStructInfo
;
4680 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4681 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4682 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
4686 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4687 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4688 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4692 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4693 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4697 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4698 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4699 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4701 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4702 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4706 SetLastError(STATUS_ACCESS_VIOLATION
);
4713 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
4714 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4715 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4719 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4720 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4724 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4725 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
4727 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4728 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4732 SetLastError(STATUS_ACCESS_VIOLATION
);
4739 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4740 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4741 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4745 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4746 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4750 struct AsnDecodeSequenceItem items
[] = {
4751 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4752 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4753 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4754 offsetof(CRL_ISSUING_DIST_POINT
,
4755 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4756 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4757 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4759 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4760 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4762 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4763 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4764 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4765 OnlySomeReasonFlags
.pbData
), 0 },
4766 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4767 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4770 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4771 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4772 pcbStructInfo
, NULL
, NULL
);
4776 SetLastError(STATUS_ACCESS_VIOLATION
);
4783 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
4784 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4789 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4790 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4794 SetLastError(CRYPT_E_ASN1_EOD
);
4797 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
4799 SetLastError(CRYPT_E_ASN1_BADTAG
);
4802 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4803 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
4804 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
4806 if (ret
&& pvStructInfo
)
4807 *(BOOL
*)pvStructInfo
= TRUE
;
4808 TRACE("returning %d\n", ret
);
4812 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
4813 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4817 struct AsnDecodeSequenceItem items
[] = {
4818 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
4819 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
4820 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
4821 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
4822 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
4823 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
4824 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
4827 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
4829 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4830 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4832 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4833 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4834 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
4837 TRACE("%d\n", *pcbDecoded
);
4838 if (*pcbDecoded
< cbEncoded
)
4839 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
4840 *(pbEncoded
+ *pcbDecoded
+ 1));
4842 TRACE("returning %d\n", ret
);
4846 static BOOL
CRYPT_AsnDecodeSubtreeArray(const BYTE
*pbEncoded
,
4847 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4851 struct AsnArrayDescriptor arrayDesc
= { 0,
4852 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4853 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4854 struct GenericArray
*array
= pvStructInfo
;
4856 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4857 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4859 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4860 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4861 array
? array
->rgItems
: NULL
);
4866 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
4867 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4868 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4872 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4873 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4877 struct AsnDecodeSequenceItem items
[] = {
4878 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4879 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
4880 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4881 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
4882 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
4883 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4884 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4885 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
4888 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4889 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4890 pcbStructInfo
, NULL
, NULL
);
4894 SetLastError(STATUS_ACCESS_VIOLATION
);
4900 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
4901 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4905 struct AsnDecodeSequenceItem items
[] = {
4906 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4907 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4909 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4910 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4911 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4913 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
4915 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4916 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4918 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4919 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4920 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4921 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4923 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4926 TRACE("returning %d\n", ret
);
4930 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4931 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4934 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
4935 struct AsnDecodeSequenceItem items
[] = {
4936 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4937 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4938 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4939 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4940 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4941 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4942 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4943 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4944 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4945 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4946 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4947 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4948 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4949 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4950 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4951 HashEncryptionAlgorithm
.pszObjId
), 0 },
4952 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4953 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4954 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4955 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4956 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4957 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4958 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4962 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4963 pvStructInfo
, *pcbStructInfo
);
4965 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4966 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4967 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
4971 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4972 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4973 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4977 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4978 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4982 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4983 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4984 if (ret
&& pvStructInfo
)
4986 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4987 pcbStructInfo
, *pcbStructInfo
);
4990 CMSG_SIGNER_INFO
*info
;
4992 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4993 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4994 info
= pvStructInfo
;
4995 info
->Issuer
.pbData
= ((BYTE
*)info
+
4996 sizeof(CMSG_SIGNER_INFO
));
4997 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
4998 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4999 pcbStructInfo
, NULL
);
5005 SetLastError(STATUS_ACCESS_VIOLATION
);
5008 TRACE("returning %d\n", ret
);
5012 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5013 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5016 CERT_ID
*id
= pvStructInfo
;
5019 if (*pbEncoded
== ASN_SEQUENCEOF
)
5021 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5022 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5026 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5027 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5028 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5029 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5031 *pcbStructInfo
= sizeof(CERT_ID
);
5034 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5036 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5037 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5041 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5042 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5043 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5044 sizeof(CRYPT_DATA_BLOB
);
5046 *pcbStructInfo
= sizeof(CERT_ID
);
5050 SetLastError(CRYPT_E_ASN1_BADTAG
);
5054 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5055 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5058 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5059 struct AsnDecodeSequenceItem items
[] = {
5060 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5061 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5062 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5063 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5064 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5065 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5066 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5067 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5068 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5069 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5070 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5071 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5072 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5073 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5074 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5075 HashEncryptionAlgorithm
.pszObjId
), 0 },
5076 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5077 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5078 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5079 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5080 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5081 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5082 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5086 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5087 pvStructInfo
, *pcbStructInfo
);
5089 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5090 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5091 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5095 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5096 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5097 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5101 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5102 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5106 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5107 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5108 if (ret
&& pvStructInfo
)
5110 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5111 pcbStructInfo
, *pcbStructInfo
);
5114 CMSG_CMS_SIGNER_INFO
*info
;
5116 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5117 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5118 info
= pvStructInfo
;
5119 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5120 sizeof(CMSG_CMS_SIGNER_INFO
));
5121 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5122 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5123 pcbStructInfo
, NULL
);
5129 SetLastError(STATUS_ACCESS_VIOLATION
);
5132 TRACE("returning %d\n", ret
);
5136 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5137 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5140 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5141 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5142 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5143 struct GenericArray
*array
= pvStructInfo
;
5145 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5146 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5148 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
5149 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
5150 array
? array
->rgItems
: NULL
);
5154 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5155 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5156 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5159 struct AsnDecodeSequenceItem items
[] = {
5160 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5161 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5162 /* Placeholder for the hash algorithms - redundant with those in the
5163 * signers, so just ignore them.
5165 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5166 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5167 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5168 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5169 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5170 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5171 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
5172 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5173 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5174 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
5175 sizeof(struct GenericArray
), TRUE
, TRUE
,
5176 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5177 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5178 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
5179 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5182 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5183 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5185 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5186 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5188 TRACE("returning %d\n", ret
);
5192 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5193 LPCSTR lpszStructType
)
5195 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5197 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5198 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5200 SetLastError(ERROR_FILE_NOT_FOUND
);
5203 if (!HIWORD(lpszStructType
))
5205 switch (LOWORD(lpszStructType
))
5207 case LOWORD(X509_CERT
):
5208 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5210 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5211 decodeFunc
= CRYPT_AsnDecodeCert
;
5213 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5214 decodeFunc
= CRYPT_AsnDecodeCRL
;
5216 case LOWORD(X509_EXTENSIONS
):
5217 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5219 case LOWORD(X509_NAME_VALUE
):
5220 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5222 case LOWORD(X509_NAME
):
5223 decodeFunc
= CRYPT_AsnDecodeName
;
5225 case LOWORD(X509_PUBLIC_KEY_INFO
):
5226 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5228 case LOWORD(X509_AUTHORITY_KEY_ID
):
5229 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5231 case LOWORD(X509_ALTERNATE_NAME
):
5232 decodeFunc
= CRYPT_AsnDecodeAltName
;
5234 case LOWORD(X509_BASIC_CONSTRAINTS
):
5235 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5237 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5238 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5240 case LOWORD(X509_CERT_POLICIES
):
5241 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5243 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5244 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5246 case LOWORD(X509_UNICODE_NAME
):
5247 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5249 case LOWORD(PKCS_ATTRIBUTE
):
5250 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5252 case LOWORD(X509_UNICODE_NAME_VALUE
):
5253 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5255 case LOWORD(X509_OCTET_STRING
):
5256 decodeFunc
= CRYPT_AsnDecodeOctets
;
5258 case LOWORD(X509_BITS
):
5259 case LOWORD(X509_KEY_USAGE
):
5260 decodeFunc
= CRYPT_AsnDecodeBits
;
5262 case LOWORD(X509_INTEGER
):
5263 decodeFunc
= CRYPT_AsnDecodeInt
;
5265 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5266 decodeFunc
= CRYPT_AsnDecodeInteger
;
5268 case LOWORD(X509_MULTI_BYTE_UINT
):
5269 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5271 case LOWORD(X509_ENUMERATED
):
5272 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5274 case LOWORD(X509_CHOICE_OF_TIME
):
5275 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5277 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5278 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5280 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5281 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5283 case LOWORD(PKCS_CONTENT_INFO
):
5284 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5286 case LOWORD(X509_SEQUENCE_OF_ANY
):
5287 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5289 case LOWORD(PKCS_UTC_TIME
):
5290 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5292 case LOWORD(X509_CRL_DIST_POINTS
):
5293 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5295 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5296 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5298 case LOWORD(PKCS_CTL
):
5299 decodeFunc
= CRYPT_AsnDecodeCTL
;
5301 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5302 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5304 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5305 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5307 case LOWORD(PKCS_ATTRIBUTES
):
5308 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5310 case LOWORD(X509_ISSUING_DIST_POINT
):
5311 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5313 case LOWORD(X509_NAME_CONSTRAINTS
):
5314 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5316 case LOWORD(PKCS7_SIGNER_INFO
):
5317 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5319 case LOWORD(CMS_SIGNER_INFO
):
5320 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5324 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5325 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5326 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5327 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5328 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5329 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5330 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5331 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5332 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5333 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5334 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5335 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5336 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5337 decodeFunc
= CRYPT_AsnDecodeBits
;
5338 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5339 decodeFunc
= CRYPT_AsnDecodeOctets
;
5340 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5341 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5342 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5343 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5344 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5345 decodeFunc
= CRYPT_AsnDecodeAltName
;
5346 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5347 decodeFunc
= CRYPT_AsnDecodeAltName
;
5348 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5349 decodeFunc
= CRYPT_AsnDecodeAltName
;
5350 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5351 decodeFunc
= CRYPT_AsnDecodeAltName
;
5352 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5353 decodeFunc
= CRYPT_AsnDecodeAltName
;
5354 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5355 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5356 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5357 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5358 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5359 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5360 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5361 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5362 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5363 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5364 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5365 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5366 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5367 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5368 else if (!strcmp(lpszStructType
, szOID_CTL
))
5369 decodeFunc
= CRYPT_AsnDecodeCTL
;
5373 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5374 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5376 static HCRYPTOIDFUNCSET set
= NULL
;
5377 CryptDecodeObjectFunc decodeFunc
= NULL
;
5380 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5381 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5382 (void **)&decodeFunc
, hFunc
);
5386 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5387 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5389 static HCRYPTOIDFUNCSET set
= NULL
;
5390 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5393 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5394 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5395 (void **)&decodeFunc
, hFunc
);
5399 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5400 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5401 DWORD
*pcbStructInfo
)
5404 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5405 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5406 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5408 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5409 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5410 pvStructInfo
, pcbStructInfo
);
5412 if (!pvStructInfo
&& !pcbStructInfo
)
5414 SetLastError(ERROR_INVALID_PARAMETER
);
5417 if (cbEncoded
> MAX_ENCODED_LEN
)
5419 SetLastError(CRYPT_E_ASN1_LARGE
);
5423 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5426 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5427 debugstr_a(lpszStructType
));
5428 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5429 lpszStructType
, &hFunc
);
5430 if (!pCryptDecodeObject
)
5431 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5432 lpszStructType
, &hFunc
);
5434 if (pCryptDecodeObject
)
5435 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5436 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5437 else if (pCryptDecodeObjectEx
)
5438 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5439 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5440 pvStructInfo
, pcbStructInfo
);
5442 CryptFreeOIDFunctionAddress(hFunc
, 0);
5443 TRACE_(crypt
)("returning %d\n", ret
);
5447 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5448 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5449 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5452 CryptDecodeObjectExFunc decodeFunc
;
5453 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5455 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5456 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5457 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5459 if (!pvStructInfo
&& !pcbStructInfo
)
5461 SetLastError(ERROR_INVALID_PARAMETER
);
5464 if (cbEncoded
> MAX_ENCODED_LEN
)
5466 SetLastError(CRYPT_E_ASN1_LARGE
);
5470 SetLastError(NOERROR
);
5471 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5472 *(BYTE
**)pvStructInfo
= NULL
;
5473 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5476 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5477 debugstr_a(lpszStructType
));
5478 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5482 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5483 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5486 CryptDecodeObjectFunc pCryptDecodeObject
=
5487 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5489 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5490 * directly, as that could cause an infinite loop.
5492 if (pCryptDecodeObject
)
5494 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5496 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5497 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5498 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5499 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5500 ret
= pCryptDecodeObject(dwCertEncodingType
,
5501 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5502 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5505 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5506 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5510 CryptFreeOIDFunctionAddress(hFunc
, 0);
5511 TRACE_(crypt
)("returning %d\n", ret
);