2 * Copyright 2005-2009 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
);
61 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
62 DWORD
, DWORD
, void *, DWORD
*);
63 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
64 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
66 /* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
69 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
70 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
72 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
73 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
75 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
76 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
80 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
81 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
84 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
85 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
86 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
89 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
93 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
94 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
95 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
101 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
102 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
105 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
106 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
108 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
121 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
128 SetLastError(CRYPT_E_ASN1_CORRUPT
);
131 else if (pbEncoded
[1] <= 0x7f)
133 if (pbEncoded
[1] + 1 > cbEncoded
)
135 SetLastError(CRYPT_E_ASN1_EOD
);
144 else if (pbEncoded
[1] == 0x80)
146 *len
= CMSG_INDEFINITE_LENGTH
;
151 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
153 if (lenLen
> sizeof(DWORD
) + 1)
155 SetLastError(CRYPT_E_ASN1_LARGE
);
158 else if (lenLen
+ 2 > cbEncoded
)
160 SetLastError(CRYPT_E_ASN1_CORRUPT
);
173 if (out
+ lenLen
+ 1 > cbEncoded
)
175 SetLastError(CRYPT_E_ASN1_EOD
);
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
193 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
194 *len
== CMSG_INDEFINITE_LENGTH
)
196 SetLastError(CRYPT_E_ASN1_CORRUPT
);
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
207 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
208 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
213 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
215 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
216 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
218 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
219 if (!*(BYTE
**)pvStructInfo
)
222 *pcbStructInfo
= bytesNeeded
;
224 else if (*pcbStructInfo
< bytesNeeded
)
226 *pcbStructInfo
= bytesNeeded
;
227 SetLastError(ERROR_MORE_DATA
);
231 *pcbStructInfo
= bytesNeeded
;
235 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
237 if (pDecodePara
&& pDecodePara
->pfnFree
)
238 pDecodePara
->pfnFree(pv
);
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
246 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
250 if (*pcbStructInfo
< bytesNeeded
)
252 *pcbStructInfo
= bytesNeeded
;
253 SetLastError(ERROR_MORE_DATA
);
258 *pcbStructInfo
= bytesNeeded
;
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
274 * The minimum amount of space occupied after decoding. You must set this.
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
286 struct AsnDecodeSequenceItem
290 InternalDecodeFunc decodeFunc
;
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
309 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
310 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
311 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
314 DWORD i
, decoded
= 0;
315 const BYTE
*ptr
= pbEncoded
;
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
318 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
320 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
322 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
326 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
327 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
329 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
331 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
333 DWORD itemEncodedLen
;
335 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
336 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
338 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
339 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
341 TRACE("Setting next pointer to %p\n",
343 *(BYTE
**)((BYTE
*)pvStructInfo
+
344 items
[i
].pointerOffset
) = nextData
;
346 if (items
[i
].decodeFunc
)
351 TRACE("decoding item %d\n", i
);
353 TRACE("sizing item %d\n", i
);
354 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
356 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
357 : NULL
, &items
[i
].size
, &itemDecoded
);
360 if (items
[i
].size
< items
[i
].minSize
)
361 items
[i
].size
= items
[i
].minSize
;
362 else if (items
[i
].size
> items
[i
].minSize
)
364 /* Account for alignment padding */
365 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
367 TRACE("item %d size: %d\n", i
, items
[i
].size
);
368 if (nextData
&& items
[i
].hasPointer
&&
369 items
[i
].size
> items
[i
].minSize
)
370 nextData
+= items
[i
].size
- items
[i
].minSize
;
371 if (itemDecoded
> itemEncodedLen
)
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded
, itemEncodedLen
);
375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
381 decoded
+= itemDecoded
;
382 TRACE("item %d: decoded %d bytes\n", i
,
386 else if (items
[i
].optional
&&
387 GetLastError() == CRYPT_E_ASN1_BADTAG
)
389 TRACE("skipping optional item %d\n", i
);
390 items
[i
].size
= items
[i
].minSize
;
391 SetLastError(NOERROR
);
395 TRACE("item %d failed: %08x\n", i
,
398 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT
);
406 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
407 ptr
+= itemEncodedLen
;
408 decoded
+= itemEncodedLen
;
409 items
[i
].size
= items
[i
].minSize
;
412 else if (items
[i
].optional
)
414 TRACE("skipping optional item %d\n", i
);
415 items
[i
].size
= items
[i
].minSize
;
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i
, ptr
[0], items
[i
].tag
);
421 SetLastError(CRYPT_E_ASN1_BADTAG
);
426 else if (items
[i
].optional
)
428 TRACE("missing optional item %d, skipping\n", i
);
429 items
[i
].size
= items
[i
].minSize
;
433 TRACE("not enough bytes for item %d, failing\n", i
);
434 SetLastError(CRYPT_E_ASN1_CORRUPT
);
439 *cbDecoded
= decoded
;
440 TRACE("returning %d\n", ret
);
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
451 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
452 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
453 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
454 DWORD
*pcbDecoded
, void *startingPointer
)
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
459 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
464 SetLastError(CRYPT_E_ASN1_EOD
);
467 if (pbEncoded
[0] == ASN_SEQUENCE
)
471 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
473 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
474 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
475 BOOL indefinite
= FALSE
;
477 cbEncoded
-= 1 + lenBytes
;
478 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
483 else if (cbEncoded
< dataLen
)
485 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
487 SetLastError(CRYPT_E_ASN1_CORRUPT
);
492 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
493 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
494 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
496 if (cbDecoded
> cbEncoded
- 2)
498 /* Not enough space for 0 TLV */
499 SetLastError(CRYPT_E_ASN1_CORRUPT
);
502 else if (*(ptr
+ cbDecoded
) != 0 ||
503 *(ptr
+ cbDecoded
+ 1) != 0)
505 TRACE("expected 0 TLV\n");
506 SetLastError(CRYPT_E_ASN1_CORRUPT
);
513 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
515 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
517 SetLastError(CRYPT_E_ASN1_CORRUPT
);
522 DWORD i
, bytesNeeded
= 0, structSize
= 0;
524 for (i
= 0; i
< cItem
; i
++)
526 if (items
[i
].size
> items
[i
].minSize
)
527 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
528 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
530 bytesNeeded
+= structSize
;
532 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
534 *pcbStructInfo
= bytesNeeded
;
535 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
536 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
540 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
541 pvStructInfo
= *(BYTE
**)pvStructInfo
;
543 nextData
= startingPointer
;
545 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
546 memset(pvStructInfo
, 0, structSize
);
547 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
548 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
550 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
551 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
558 SetLastError(CRYPT_E_ASN1_BADTAG
);
561 TRACE("returning %d (%08x)\n", ret
, GetLastError());
566 * The expected tag of the entire encoded array (usually a variant
567 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
568 * regardless of the tag seen.
570 * The offset within the outer structure at which the count exists.
571 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
572 * while CRYPT_ATTRIBUTE has countOffset ==
573 * offsetof(CRYPT_ATTRIBUTE, cValue).
575 * The offset within the outer structure at which the array pointer exists.
576 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
577 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
579 * The minimum size of the decoded array. On WIN32, this is always 8:
580 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
583 * used to decode each item in the array
585 * is the minimum size of each decoded item
587 * indicates whether each item has a dynamic pointer
589 * indicates the offset within itemSize at which the pointer exists
591 struct AsnArrayDescriptor
597 InternalDecodeFunc decodeFunc
;
603 struct AsnArrayItemSize
609 /* Decodes an array of like types into a structure described by a struct
610 * AsnArrayDescriptor.
612 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
613 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
614 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
619 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
620 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
624 SetLastError(CRYPT_E_ASN1_EOD
);
627 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
631 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
633 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
634 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
635 /* There can be arbitrarily many items, but there is often only one.
637 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
639 decoded
= 1 + lenBytes
;
643 BOOL doneDecoding
= FALSE
;
645 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
647 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
654 SetLastError(CRYPT_E_ASN1_CORRUPT
);
661 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
665 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
667 /* Each item decoded may not tolerate extraneous bytes,
668 * so get the length of the next element if known.
670 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
671 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
673 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
674 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
676 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
680 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
681 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
686 if (itemSizes
!= &itemSize
)
687 itemSizes
= CryptMemRealloc(itemSizes
,
688 cItems
* sizeof(struct AsnArrayItemSize
));
693 cItems
* sizeof(struct AsnArrayItemSize
));
695 memcpy(itemSizes
, &itemSize
,
700 decoded
+= itemDecoded
;
701 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
702 itemSizes
[cItems
- 1].size
= size
;
715 *pcbDecoded
= decoded
;
717 *pcbStructInfo
= bytesNeeded
;
718 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
719 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
726 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
727 pvStructInfo
= *(void **)pvStructInfo
;
728 pcItems
= pvStructInfo
;
730 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
732 rgItems
= (BYTE
*)pvStructInfo
+
733 arrayDesc
->minArraySize
;
734 *(void **)((BYTE
*)pcItems
-
735 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
739 rgItems
= *(void **)((BYTE
*)pcItems
-
740 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
741 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
742 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
743 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
748 if (arrayDesc
->hasPointer
)
749 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
750 + arrayDesc
->pointerOffset
) = nextData
;
751 ret
= arrayDesc
->decodeFunc(ptr
,
752 itemSizes
[i
].encodedLen
,
753 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
754 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
755 &itemSizes
[i
].size
, &itemDecoded
);
758 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
764 if (itemSizes
!= &itemSize
)
765 CryptMemFree(itemSizes
);
770 SetLastError(CRYPT_E_ASN1_BADTAG
);
776 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
777 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
778 * to CRYPT_E_ASN1_CORRUPT.
779 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
782 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
783 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
788 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
790 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
791 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
793 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
794 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
797 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
799 *pcbStructInfo
= bytesNeeded
;
800 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
802 CRYPT_DER_BLOB
*blob
;
804 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
805 pvStructInfo
= *(BYTE
**)pvStructInfo
;
807 blob
->cbData
= 1 + lenBytes
+ dataLen
;
810 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
811 blob
->pbData
= (BYTE
*)pbEncoded
;
814 assert(blob
->pbData
);
815 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
820 SetLastError(CRYPT_E_ASN1_CORRUPT
);
828 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
829 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
830 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
835 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
836 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
838 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
841 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
842 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
844 if (ret
&& pvStructInfo
)
846 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
853 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
855 temp
= blob
->pbData
[i
];
856 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
857 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
861 TRACE("returning %d (%08x)\n", ret
, GetLastError());
865 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
866 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
867 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
871 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
872 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
876 struct AsnDecodeSequenceItem items
[] = {
877 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
878 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
879 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
880 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
881 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
882 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
883 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
884 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
885 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
886 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
889 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
890 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
891 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
892 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
893 pcbStructInfo
, NULL
, NULL
);
897 SetLastError(STATUS_ACCESS_VIOLATION
);
902 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
906 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
907 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
912 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
914 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
916 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
917 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
919 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
924 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
925 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
929 struct AsnDecodeSequenceItem items
[] = {
930 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
931 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
933 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
936 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
937 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
942 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
943 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
947 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
948 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
949 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
950 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
951 offsetof(CERT_EXTENSION
, pszObjId
) };
953 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
954 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
956 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
957 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
961 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
962 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
968 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
970 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
972 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
973 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
974 if (ret
&& pcbDecoded
)
975 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
980 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
981 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
982 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
985 struct AsnDecodeSequenceItem items
[] = {
986 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
987 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
988 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
989 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
990 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
991 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
992 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
993 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
994 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
995 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
997 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
998 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1000 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1001 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1003 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1004 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1005 FALSE
, TRUE
, offsetof(CERT_INFO
,
1006 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1007 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1008 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1009 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1010 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1011 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1012 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1013 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1014 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1015 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1018 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1019 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1021 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1022 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1024 if (ret
&& pvStructInfo
)
1028 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1029 info
= *(CERT_INFO
**)pvStructInfo
;
1031 info
= pvStructInfo
;
1032 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1033 !info
->Subject
.cbData
)
1035 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1036 /* Don't need to deallocate, because it should have failed on the
1037 * first pass (and no memory was allocated.)
1043 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1047 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1048 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1049 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1053 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1054 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1060 /* Unless told not to, first try to decode it as a signed cert. */
1061 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1063 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1065 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1066 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1067 &signedCert
, &size
);
1071 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1072 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1073 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1074 pvStructInfo
, pcbStructInfo
);
1075 LocalFree(signedCert
);
1078 /* Failing that, try it as an unsigned cert */
1082 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1083 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1084 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1089 SetLastError(STATUS_ACCESS_VIOLATION
);
1093 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1097 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1098 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1102 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1103 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1104 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1105 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1106 offsetof(CERT_EXTENSION
, pszObjId
) };
1108 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1109 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1111 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1112 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1116 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1117 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1120 struct AsnDecodeSequenceItem items
[] = {
1121 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1122 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1123 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1124 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1125 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1126 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1127 CRYPT_AsnDecodeCRLEntryExtensions
,
1128 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1129 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1131 PCRL_ENTRY entry
= pvStructInfo
;
1133 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1136 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1137 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1138 entry
? entry
->SerialNumber
.pbData
: NULL
);
1139 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1141 WARN("empty CRL entry serial number\n");
1142 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1148 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1149 * whose rgCRLEntry member has been set prior to calling.
1151 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1152 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1155 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1156 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1157 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1158 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1159 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1161 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1162 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1164 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1165 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1166 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1170 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1171 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1175 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1176 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1177 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1178 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1179 offsetof(CERT_EXTENSION
, pszObjId
) };
1181 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1182 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1184 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1185 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1189 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1190 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1196 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1198 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1200 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1201 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1202 if (ret
&& pcbDecoded
)
1203 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1208 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1209 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1210 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1212 struct AsnDecodeSequenceItem items
[] = {
1213 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1214 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1215 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1216 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1217 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1218 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1219 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1221 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1222 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1223 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1224 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1225 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1226 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1227 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1228 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1229 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1230 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1234 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1235 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1237 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1238 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1241 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1245 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1246 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1247 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1251 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1252 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1258 /* Unless told not to, first try to decode it as a signed crl. */
1259 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1261 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1263 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1264 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1269 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1270 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1271 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1272 pvStructInfo
, pcbStructInfo
);
1273 LocalFree(signedCrl
);
1276 /* Failing that, try it as an unsigned crl */
1280 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1281 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1282 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1287 SetLastError(STATUS_ACCESS_VIOLATION
);
1291 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1295 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1296 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1301 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1302 pvStructInfo
, *pcbStructInfo
);
1304 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1306 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1307 DWORD bytesNeeded
= sizeof(LPSTR
);
1311 /* The largest possible string for the first two components
1312 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1317 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1318 pbEncoded
[1 + lenBytes
] / 40,
1319 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1321 bytesNeeded
+= strlen(firstTwo
) + 1;
1322 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1323 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1325 /* large enough for ".4000000" */
1329 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1336 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1339 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1346 snprintf(str
, sizeof(str
), ".%d", val
);
1347 bytesNeeded
+= strlen(str
);
1352 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1354 *pcbStructInfo
= bytesNeeded
;
1355 else if (*pcbStructInfo
< bytesNeeded
)
1357 *pcbStructInfo
= bytesNeeded
;
1358 SetLastError(ERROR_MORE_DATA
);
1366 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1369 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1370 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1372 pszObjId
+= strlen(pszObjId
);
1373 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1374 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1378 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1387 sprintf(pszObjId
, ".%d", val
);
1388 pszObjId
+= strlen(pszObjId
);
1392 *(LPSTR
*)pvStructInfo
= NULL
;
1393 *pcbStructInfo
= bytesNeeded
;
1399 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1400 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1404 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1405 pvStructInfo
, *pcbStructInfo
);
1407 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1408 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1409 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1412 SetLastError(CRYPT_E_ASN1_BADTAG
);
1418 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1419 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1421 struct AsnDecodeSequenceItem items
[] = {
1422 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1423 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1424 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1425 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1426 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1427 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1428 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1429 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1432 PCERT_EXTENSION ext
= pvStructInfo
;
1434 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1438 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1439 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1440 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1441 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1443 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1444 debugstr_a(ext
->pszObjId
));
1445 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1449 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1450 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1451 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1455 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1456 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1460 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1461 offsetof(CERT_EXTENSIONS
, cExtension
),
1462 offsetof(CERT_EXTENSIONS
, rgExtension
),
1463 sizeof(CERT_EXTENSIONS
),
1464 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1465 offsetof(CERT_EXTENSION
, pszObjId
) };
1467 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1468 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1472 SetLastError(STATUS_ACCESS_VIOLATION
);
1479 /* Warning: this assumes the address of value->Value.pbData is already set, in
1480 * order to avoid overwriting memory. (In some cases, it may change it, if it
1481 * doesn't copy anything to memory.) Be sure to set it correctly!
1483 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1484 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1489 CERT_NAME_VALUE
*value
= pvStructInfo
;
1491 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1493 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1494 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1496 switch (pbEncoded
[0])
1498 case ASN_OCTETSTRING
:
1499 valueType
= CERT_RDN_OCTET_STRING
;
1500 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1501 bytesNeeded
+= dataLen
;
1503 case ASN_NUMERICSTRING
:
1504 valueType
= CERT_RDN_NUMERIC_STRING
;
1505 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1506 bytesNeeded
+= dataLen
;
1508 case ASN_PRINTABLESTRING
:
1509 valueType
= CERT_RDN_PRINTABLE_STRING
;
1510 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1511 bytesNeeded
+= dataLen
;
1514 valueType
= CERT_RDN_IA5_STRING
;
1515 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1516 bytesNeeded
+= dataLen
;
1519 valueType
= CERT_RDN_T61_STRING
;
1520 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1521 bytesNeeded
+= dataLen
;
1523 case ASN_VIDEOTEXSTRING
:
1524 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1525 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1526 bytesNeeded
+= dataLen
;
1528 case ASN_GRAPHICSTRING
:
1529 valueType
= CERT_RDN_GRAPHIC_STRING
;
1530 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1531 bytesNeeded
+= dataLen
;
1533 case ASN_VISIBLESTRING
:
1534 valueType
= CERT_RDN_VISIBLE_STRING
;
1535 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1536 bytesNeeded
+= dataLen
;
1538 case ASN_GENERALSTRING
:
1539 valueType
= CERT_RDN_GENERAL_STRING
;
1540 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1541 bytesNeeded
+= dataLen
;
1543 case ASN_UNIVERSALSTRING
:
1544 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545 SetLastError(CRYPT_E_ASN1_BADTAG
);
1548 valueType
= CERT_RDN_BMP_STRING
;
1549 bytesNeeded
+= dataLen
;
1551 case ASN_UTF8STRING
:
1552 valueType
= CERT_RDN_UTF8_STRING
;
1553 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1554 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1557 SetLastError(CRYPT_E_ASN1_BADTAG
);
1562 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1564 *pcbStructInfo
= bytesNeeded
;
1565 else if (*pcbStructInfo
< bytesNeeded
)
1567 *pcbStructInfo
= bytesNeeded
;
1568 SetLastError(ERROR_MORE_DATA
);
1573 *pcbStructInfo
= bytesNeeded
;
1574 value
->dwValueType
= valueType
;
1579 assert(value
->Value
.pbData
);
1580 switch (pbEncoded
[0])
1582 case ASN_OCTETSTRING
:
1583 case ASN_NUMERICSTRING
:
1584 case ASN_PRINTABLESTRING
:
1587 case ASN_VIDEOTEXSTRING
:
1588 case ASN_GRAPHICSTRING
:
1589 case ASN_VISIBLESTRING
:
1590 case ASN_GENERALSTRING
:
1591 value
->Value
.cbData
= dataLen
;
1594 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1595 memcpy(value
->Value
.pbData
,
1596 pbEncoded
+ 1 + lenBytes
, dataLen
);
1598 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1604 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1606 value
->Value
.cbData
= dataLen
;
1607 for (i
= 0; i
< dataLen
/ 2; i
++)
1608 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1609 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1612 case ASN_UTF8STRING
:
1614 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1616 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1617 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1618 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1625 value
->Value
.cbData
= 0;
1626 value
->Value
.pbData
= NULL
;
1633 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1634 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1635 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1641 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1642 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1643 if (ret
&& pvStructInfo
)
1645 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1646 pcbStructInfo
, *pcbStructInfo
);
1649 CERT_NAME_VALUE
*value
;
1651 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1652 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1653 value
= pvStructInfo
;
1654 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1655 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1656 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1657 pcbStructInfo
, NULL
);
1663 SetLastError(STATUS_ACCESS_VIOLATION
);
1670 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1671 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1676 CERT_NAME_VALUE
*value
= pvStructInfo
;
1678 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1680 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1681 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1683 switch (pbEncoded
[0])
1685 case ASN_NUMERICSTRING
:
1686 valueType
= CERT_RDN_NUMERIC_STRING
;
1688 bytesNeeded
+= (dataLen
+ 1) * 2;
1690 case ASN_PRINTABLESTRING
:
1691 valueType
= CERT_RDN_PRINTABLE_STRING
;
1693 bytesNeeded
+= (dataLen
+ 1) * 2;
1696 valueType
= CERT_RDN_IA5_STRING
;
1698 bytesNeeded
+= (dataLen
+ 1) * 2;
1701 valueType
= CERT_RDN_T61_STRING
;
1703 bytesNeeded
+= (dataLen
+ 1) * 2;
1705 case ASN_VIDEOTEXSTRING
:
1706 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1708 bytesNeeded
+= (dataLen
+ 1) * 2;
1710 case ASN_GRAPHICSTRING
:
1711 valueType
= CERT_RDN_GRAPHIC_STRING
;
1713 bytesNeeded
+= (dataLen
+ 1) * 2;
1715 case ASN_VISIBLESTRING
:
1716 valueType
= CERT_RDN_VISIBLE_STRING
;
1718 bytesNeeded
+= (dataLen
+ 1) * 2;
1720 case ASN_GENERALSTRING
:
1721 valueType
= CERT_RDN_GENERAL_STRING
;
1723 bytesNeeded
+= (dataLen
+ 1) * 2;
1725 case ASN_UNIVERSALSTRING
:
1726 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1728 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1731 valueType
= CERT_RDN_BMP_STRING
;
1733 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1735 case ASN_UTF8STRING
:
1736 valueType
= CERT_RDN_UTF8_STRING
;
1738 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1739 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1742 SetLastError(CRYPT_E_ASN1_BADTAG
);
1747 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1749 *pcbStructInfo
= bytesNeeded
;
1750 else if (*pcbStructInfo
< bytesNeeded
)
1752 *pcbStructInfo
= bytesNeeded
;
1753 SetLastError(ERROR_MORE_DATA
);
1758 *pcbStructInfo
= bytesNeeded
;
1759 value
->dwValueType
= valueType
;
1763 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1765 assert(value
->Value
.pbData
);
1766 switch (pbEncoded
[0])
1768 case ASN_NUMERICSTRING
:
1769 case ASN_PRINTABLESTRING
:
1772 case ASN_VIDEOTEXSTRING
:
1773 case ASN_GRAPHICSTRING
:
1774 case ASN_VISIBLESTRING
:
1775 case ASN_GENERALSTRING
:
1776 value
->Value
.cbData
= dataLen
* 2;
1777 for (i
= 0; i
< dataLen
; i
++)
1778 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1781 case ASN_UNIVERSALSTRING
:
1782 value
->Value
.cbData
= dataLen
/ 2;
1783 for (i
= 0; i
< dataLen
/ 4; i
++)
1784 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1785 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1789 value
->Value
.cbData
= dataLen
;
1790 for (i
= 0; i
< dataLen
/ 2; i
++)
1791 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1792 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1795 case ASN_UTF8STRING
:
1796 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1797 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1798 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1799 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1800 value
->Value
.cbData
+= sizeof(WCHAR
);
1806 value
->Value
.cbData
= 0;
1807 value
->Value
.pbData
= NULL
;
1814 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1815 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1816 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1822 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1823 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1824 if (ret
&& pvStructInfo
)
1826 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1827 pcbStructInfo
, *pcbStructInfo
);
1830 CERT_NAME_VALUE
*value
;
1832 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1833 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1834 value
= pvStructInfo
;
1835 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1836 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1837 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1838 pcbStructInfo
, NULL
);
1844 SetLastError(STATUS_ACCESS_VIOLATION
);
1851 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1852 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1855 struct AsnDecodeSequenceItem items
[] = {
1856 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1857 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1858 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1859 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1860 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1861 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1863 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1865 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1866 pvStructInfo
, *pcbStructInfo
);
1869 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1870 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1871 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1872 attr
? attr
->pszObjId
: NULL
);
1875 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1876 debugstr_a(attr
->pszObjId
));
1877 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1879 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1883 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1884 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1887 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1888 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1890 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1891 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1893 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1894 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1898 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1899 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1900 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1906 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1907 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1908 sizeof(CERT_NAME_INFO
),
1909 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1910 offsetof(CERT_RDN
, rgRDNAttr
) };
1913 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1914 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1919 *pcbStructInfo
= bytesNeeded
;
1920 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1921 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1923 CERT_NAME_INFO
*info
;
1925 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1926 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1927 info
= pvStructInfo
;
1928 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1929 sizeof(CERT_NAME_INFO
));
1930 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1931 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1932 &bytesNeeded
, NULL
);
1938 SetLastError(STATUS_ACCESS_VIOLATION
);
1945 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1946 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1950 struct AsnDecodeSequenceItem items
[] = {
1951 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1952 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1953 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1954 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1955 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1956 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1958 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1960 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1961 pvStructInfo
, *pcbStructInfo
);
1964 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1965 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1966 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1967 attr
? attr
->pszObjId
: NULL
);
1970 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1971 debugstr_a(attr
->pszObjId
));
1972 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1974 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1978 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1979 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1982 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1983 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1985 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1986 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1988 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1989 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1993 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1994 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1995 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2001 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2002 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2003 sizeof(CERT_NAME_INFO
),
2004 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2005 offsetof(CERT_RDN
, rgRDNAttr
) };
2008 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2009 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2014 *pcbStructInfo
= bytesNeeded
;
2015 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2016 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2018 CERT_NAME_INFO
*info
;
2020 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2021 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2022 info
= pvStructInfo
;
2023 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2024 sizeof(CERT_NAME_INFO
));
2025 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2026 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2027 &bytesNeeded
, NULL
);
2033 SetLastError(STATUS_ACCESS_VIOLATION
);
2040 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2043 BOOL ret
= TRUE
, done
= FALSE
;
2044 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2046 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2053 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2056 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2058 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2060 indefiniteNestingLevels
++;
2061 pbEncoded
+= 1 + lenBytes
;
2062 cbEncoded
-= 1 + lenBytes
;
2063 decoded
+= 1 + lenBytes
;
2064 TRACE("indefiniteNestingLevels = %d\n",
2065 indefiniteNestingLevels
);
2069 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2070 indefiniteNestingLevels
)
2072 indefiniteNestingLevels
--;
2073 TRACE("indefiniteNestingLevels = %d\n",
2074 indefiniteNestingLevels
);
2076 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2077 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2078 decoded
+= 1 + lenBytes
+ dataLen
;
2079 if (!indefiniteNestingLevels
)
2083 } while (ret
&& !done
);
2084 /* If we haven't found all 0 TLVs, we haven't found the end */
2085 if (ret
&& indefiniteNestingLevels
)
2087 SetLastError(CRYPT_E_ASN1_EOD
);
2091 *pcbDecoded
= decoded
;
2092 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2096 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2097 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2101 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2103 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2104 pvStructInfo
, *pcbStructInfo
);
2106 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2108 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2109 bytesNeeded
+= encodedLen
;
2111 *pcbStructInfo
= bytesNeeded
;
2112 else if (*pcbStructInfo
< bytesNeeded
)
2114 SetLastError(ERROR_MORE_DATA
);
2115 *pcbStructInfo
= bytesNeeded
;
2120 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2122 *pcbStructInfo
= bytesNeeded
;
2123 blob
->cbData
= encodedLen
;
2126 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2127 blob
->pbData
= (LPBYTE
)pbEncoded
;
2130 assert(blob
->pbData
);
2131 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2135 blob
->pbData
= NULL
;
2138 *pcbDecoded
= encodedLen
;
2143 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2144 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2147 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2148 offsetof(CTL_USAGE
, cUsageIdentifier
),
2149 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2151 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2153 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2154 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2158 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2159 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2162 struct AsnArrayDescriptor arrayDesc
= { 0,
2163 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2164 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2165 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2166 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2169 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2170 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2174 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2175 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2177 struct AsnDecodeSequenceItem items
[] = {
2178 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2179 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2180 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2181 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2182 CRYPT_AsnDecodeCTLEntryAttributes
,
2183 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2184 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2187 CTL_ENTRY
*entry
= pvStructInfo
;
2189 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2192 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2193 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2194 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2198 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2199 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2202 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2203 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2204 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2205 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2206 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2208 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2209 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2211 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2212 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2216 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2217 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2221 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2222 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2223 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2224 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2225 offsetof(CERT_EXTENSION
, pszObjId
) };
2227 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2228 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2230 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2231 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2235 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2236 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2242 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2244 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2246 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2247 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2248 if (ret
&& pcbDecoded
)
2249 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2254 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2255 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2256 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2260 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2261 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2265 struct AsnDecodeSequenceItem items
[] = {
2266 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2267 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2268 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2269 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2270 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2271 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2272 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2273 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2274 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2275 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2276 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2277 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2278 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2280 { 0, offsetof(CTL_INFO
, NextUpdate
),
2281 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2283 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2284 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2285 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2286 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2287 CRYPT_AsnDecodeCTLEntries
,
2288 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2289 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2290 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2291 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2292 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2295 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2296 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2297 pcbStructInfo
, NULL
, NULL
);
2301 SetLastError(STATUS_ACCESS_VIOLATION
);
2307 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2308 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2312 struct AsnDecodeSequenceItem items
[] = {
2313 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2314 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2315 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2316 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2317 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2318 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2320 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2322 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2323 pvStructInfo
, *pcbStructInfo
);
2325 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2326 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2327 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2328 TRACE("returning %d\n", ret
);
2332 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2333 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2334 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2339 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2343 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2344 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2345 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2346 sizeof(CRYPT_SMIME_CAPABILITIES
),
2347 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2348 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2350 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2351 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2355 SetLastError(STATUS_ACCESS_VIOLATION
);
2358 TRACE("returning %d\n", ret
);
2362 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2363 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2368 LPSTR
*pStr
= pvStructInfo
;
2370 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2372 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2373 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2375 if (pbEncoded
[0] != ASN_IA5STRING
)
2377 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2382 bytesNeeded
+= dataLen
;
2384 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2386 *pcbStructInfo
= bytesNeeded
;
2387 else if (*pcbStructInfo
< bytesNeeded
)
2389 *pcbStructInfo
= bytesNeeded
;
2390 SetLastError(ERROR_MORE_DATA
);
2395 *pcbStructInfo
= bytesNeeded
;
2401 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2412 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2413 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2416 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2417 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2418 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2419 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2420 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2423 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2424 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2426 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2427 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2428 TRACE("returning %d\n", ret
);
2432 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2433 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2437 struct AsnDecodeSequenceItem items
[] = {
2438 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2439 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2440 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2441 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2442 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2443 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2444 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2445 rgNoticeNumbers
), 0 },
2449 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2450 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2452 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2453 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2457 /* The caller is expecting a pointer to a
2458 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2459 * CRYPT_AsnDecodeSequence is decoding a
2460 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2461 * needed, and decode again if the requisite space is available.
2463 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2465 *pcbStructInfo
= bytesNeeded
;
2466 else if (*pcbStructInfo
< bytesNeeded
)
2468 *pcbStructInfo
= bytesNeeded
;
2469 SetLastError(ERROR_MORE_DATA
);
2474 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2476 *pcbStructInfo
= bytesNeeded
;
2477 /* The pointer (pvStructInfo) passed in points to the first dynamic
2478 * pointer, so use it as the pointer to the
2479 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2480 * appropriate offset for the first dynamic pointer within the
2481 * notice reference by pointing to the first memory location past
2482 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2485 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2486 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2487 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2488 ret
= CRYPT_AsnDecodeSequence(items
,
2489 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2490 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2491 noticeRef
->pszOrganization
);
2494 TRACE("returning %d\n", ret
);
2498 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2499 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2505 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2507 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2508 DWORD bytesNeeded
= sizeof(LPWSTR
);
2510 switch (pbEncoded
[0])
2512 case ASN_NUMERICSTRING
:
2514 bytesNeeded
+= (dataLen
+ 1) * 2;
2516 case ASN_PRINTABLESTRING
:
2518 bytesNeeded
+= (dataLen
+ 1) * 2;
2522 bytesNeeded
+= (dataLen
+ 1) * 2;
2526 bytesNeeded
+= (dataLen
+ 1) * 2;
2528 case ASN_VIDEOTEXSTRING
:
2530 bytesNeeded
+= (dataLen
+ 1) * 2;
2532 case ASN_GRAPHICSTRING
:
2534 bytesNeeded
+= (dataLen
+ 1) * 2;
2536 case ASN_VISIBLESTRING
:
2538 bytesNeeded
+= (dataLen
+ 1) * 2;
2540 case ASN_GENERALSTRING
:
2542 bytesNeeded
+= (dataLen
+ 1) * 2;
2544 case ASN_UNIVERSALSTRING
:
2546 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2550 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2552 case ASN_UTF8STRING
:
2554 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2555 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2558 SetLastError(CRYPT_E_ASN1_BADTAG
);
2563 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2565 *pcbStructInfo
= bytesNeeded
;
2566 else if (*pcbStructInfo
< bytesNeeded
)
2568 *pcbStructInfo
= bytesNeeded
;
2569 SetLastError(ERROR_MORE_DATA
);
2574 LPWSTR
*pStr
= pvStructInfo
;
2576 *pcbStructInfo
= bytesNeeded
;
2580 LPWSTR str
= *(LPWSTR
*)pStr
;
2583 switch (pbEncoded
[0])
2585 case ASN_NUMERICSTRING
:
2586 case ASN_PRINTABLESTRING
:
2589 case ASN_VIDEOTEXSTRING
:
2590 case ASN_GRAPHICSTRING
:
2591 case ASN_VISIBLESTRING
:
2592 case ASN_GENERALSTRING
:
2593 for (i
= 0; i
< dataLen
; i
++)
2594 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2597 case ASN_UNIVERSALSTRING
:
2598 for (i
= 0; i
< dataLen
/ 4; i
++)
2599 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2600 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2604 for (i
= 0; i
< dataLen
/ 2; i
++)
2605 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2606 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2609 case ASN_UTF8STRING
:
2611 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2612 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2613 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2626 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2627 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2628 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2631 struct AsnDecodeSequenceItem items
[] = {
2632 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2633 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2634 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2635 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2636 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2637 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2638 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2640 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2642 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2643 pvStructInfo
, *pcbStructInfo
);
2645 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2646 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2647 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2648 TRACE("returning %d\n", ret
);
2652 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2653 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2654 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2655 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2659 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2660 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2666 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2667 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2672 *pcbStructInfo
= bytesNeeded
;
2673 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2674 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2676 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2678 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2679 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2680 notice
= pvStructInfo
;
2681 notice
->pNoticeReference
=
2682 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2683 ((BYTE
*)pvStructInfo
+
2684 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2685 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2686 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2687 pvStructInfo
, &bytesNeeded
, NULL
);
2693 SetLastError(STATUS_ACCESS_VIOLATION
);
2696 TRACE("returning %d\n", ret
);
2700 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2701 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2705 struct AsnArrayDescriptor arrayDesc
= { 0,
2706 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2707 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2708 CRYPT_AsnDecodeCopyBytes
,
2709 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2711 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2712 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2714 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2715 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2719 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2720 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2724 struct AsnDecodeSequenceItem items
[] = {
2725 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2726 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2727 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2728 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2729 CRYPT_AsnDecodePKCSAttributeValue
,
2730 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2731 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2733 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2735 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2736 pvStructInfo
, *pcbStructInfo
);
2738 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2739 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2740 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2741 TRACE("returning %d\n", ret
);
2745 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2746 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2747 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2751 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2752 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2758 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2759 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2763 *pcbStructInfo
= bytesNeeded
;
2764 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2765 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2767 PCRYPT_ATTRIBUTE attr
;
2769 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2770 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2771 attr
= pvStructInfo
;
2772 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2773 sizeof(CRYPT_ATTRIBUTE
));
2774 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2775 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2782 SetLastError(STATUS_ACCESS_VIOLATION
);
2785 TRACE("returning %d\n", ret
);
2789 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2790 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2793 struct AsnArrayDescriptor arrayDesc
= { 0,
2794 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2795 sizeof(CRYPT_ATTRIBUTES
),
2796 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2797 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2800 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2801 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2805 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2806 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2807 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2811 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2812 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2816 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2817 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2818 sizeof(CRYPT_ATTRIBUTES
),
2819 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2820 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2822 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2823 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2827 SetLastError(STATUS_ACCESS_VIOLATION
);
2830 TRACE("returning %d\n", ret
);
2834 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2835 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2837 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2839 struct AsnDecodeSequenceItem items
[] = {
2840 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2841 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2842 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2843 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2844 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2845 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2848 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2849 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2851 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2852 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2853 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2854 if (ret
&& pvStructInfo
)
2856 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2857 debugstr_a(algo
->pszObjId
));
2862 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2863 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2867 struct AsnDecodeSequenceItem items
[] = {
2868 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2869 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2870 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2871 Algorithm
.pszObjId
) },
2872 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2873 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2874 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2876 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2878 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2879 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2880 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2884 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2885 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2886 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2894 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2895 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2898 *pcbStructInfo
= bytesNeeded
;
2899 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2900 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2902 PCERT_PUBLIC_KEY_INFO info
;
2904 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2905 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2906 info
= pvStructInfo
;
2907 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2908 sizeof(CERT_PUBLIC_KEY_INFO
);
2909 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2910 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2911 &bytesNeeded
, NULL
);
2917 SetLastError(STATUS_ACCESS_VIOLATION
);
2924 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2925 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2931 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2934 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2936 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2939 if (pbEncoded
[1] > 1)
2941 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2948 *pcbStructInfo
= sizeof(BOOL
);
2951 else if (*pcbStructInfo
< sizeof(BOOL
))
2953 *pcbStructInfo
= sizeof(BOOL
);
2954 SetLastError(ERROR_MORE_DATA
);
2959 *pcbStructInfo
= sizeof(BOOL
);
2960 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2963 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2967 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2968 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2970 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2971 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2974 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2975 pvStructInfo
, *pcbStructInfo
);
2979 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2982 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2983 if (1 + lenBytes
> cbEncoded
)
2985 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2988 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2990 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2992 case 1: /* rfc822Name */
2993 case 2: /* dNSName */
2994 case 6: /* uniformResourceIdentifier */
2995 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
2997 SetLastError(CRYPT_E_ASN1_RULE
);
3001 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3003 case 4: /* directoryName */
3004 case 7: /* iPAddress */
3005 bytesNeeded
+= dataLen
;
3007 case 8: /* registeredID */
3008 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3012 /* FIXME: ugly, shouldn't need to know internals of OID decode
3013 * function to use it.
3015 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3018 case 0: /* otherName */
3019 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3020 SetLastError(CRYPT_E_ASN1_BADTAG
);
3023 case 3: /* x400Address, unimplemented */
3024 case 5: /* ediPartyName, unimplemented */
3025 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3026 SetLastError(CRYPT_E_ASN1_BADTAG
);
3030 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3031 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3037 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3039 *pcbStructInfo
= bytesNeeded
;
3040 else if (*pcbStructInfo
< bytesNeeded
)
3042 *pcbStructInfo
= bytesNeeded
;
3043 SetLastError(ERROR_MORE_DATA
);
3048 *pcbStructInfo
= bytesNeeded
;
3049 /* MS used values one greater than the asn1 ones.. sigh */
3050 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3051 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3053 case 1: /* rfc822Name */
3054 case 2: /* dNSName */
3055 case 6: /* uniformResourceIdentifier */
3059 for (i
= 0; i
< dataLen
; i
++)
3060 entry
->u
.pwszURL
[i
] =
3061 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3062 entry
->u
.pwszURL
[i
] = 0;
3063 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3064 debugstr_w(entry
->u
.pwszURL
));
3067 case 4: /* directoryName */
3068 /* The data are memory-equivalent with the IPAddress case,
3071 case 7: /* iPAddress */
3072 /* The next data pointer is in the pwszURL spot, that is,
3073 * the first 4 bytes. Need to move it to the next spot.
3075 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3076 entry
->u
.IPAddress
.cbData
= dataLen
;
3077 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3080 case 8: /* registeredID */
3081 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3082 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3091 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3092 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3096 struct AsnArrayDescriptor arrayDesc
= { 0,
3097 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3098 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3099 sizeof(CERT_ALT_NAME_INFO
),
3100 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3101 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3103 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3104 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3106 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3107 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3111 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3112 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3113 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3119 struct AsnDecodeSequenceItem items
[] = {
3120 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3121 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3122 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3123 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3124 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3125 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3126 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3127 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3128 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3129 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3130 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3133 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3134 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3135 pcbStructInfo
, NULL
, NULL
);
3139 SetLastError(STATUS_ACCESS_VIOLATION
);
3146 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3147 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3148 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3154 struct AsnDecodeSequenceItem items
[] = {
3155 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3156 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3157 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3158 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3159 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3160 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3161 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3162 AuthorityCertIssuer
.rgAltEntry
), 0 },
3163 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3164 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3165 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3166 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3167 AuthorityCertSerialNumber
.pbData
), 0 },
3170 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3171 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3172 pcbStructInfo
, NULL
, NULL
);
3176 SetLastError(STATUS_ACCESS_VIOLATION
);
3183 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3184 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3187 struct AsnDecodeSequenceItem items
[] = {
3188 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3189 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3190 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3191 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3192 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3193 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3195 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3197 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3198 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3199 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3202 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3203 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3204 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3208 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3209 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3213 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3214 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3215 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3216 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3217 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3218 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3220 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3221 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3225 SetLastError(STATUS_ACCESS_VIOLATION
);
3232 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3233 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3238 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3239 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3241 /* The caller has already checked the tag, no need to check it again.
3242 * Check the outer length is valid:
3244 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3246 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3249 pbEncoded
+= 1 + lenBytes
;
3250 cbEncoded
-= 1 + lenBytes
;
3251 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3252 cbEncoded
-= 2; /* space for 0 TLV */
3253 /* Check the inner length is valid: */
3254 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3258 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3259 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3260 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3262 if (*(pbEncoded
+ decodedLen
) != 0 ||
3263 *(pbEncoded
+ decodedLen
+ 1) != 0)
3265 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3266 *(pbEncoded
+ decodedLen
),
3267 *(pbEncoded
+ decodedLen
+ 1));
3268 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3274 if (ret
&& pcbDecoded
)
3276 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3277 TRACE("decoded %d bytes\n", *pcbDecoded
);
3284 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3285 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3288 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3289 struct AsnDecodeSequenceItem items
[] = {
3290 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3291 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3292 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3293 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3294 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3295 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3296 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3300 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3301 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3303 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3304 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3305 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3309 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3310 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3311 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3315 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3316 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3320 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3321 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3322 if (ret
&& pvStructInfo
)
3324 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3325 pcbStructInfo
, *pcbStructInfo
);
3328 CRYPT_CONTENT_INFO
*info
;
3330 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3331 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3332 info
= pvStructInfo
;
3333 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3334 sizeof(CRYPT_CONTENT_INFO
));
3335 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3336 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3337 pcbStructInfo
, NULL
);
3343 SetLastError(STATUS_ACCESS_VIOLATION
);
3349 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3350 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3351 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3354 struct AsnDecodeSequenceItem items
[] = {
3355 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3356 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3357 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3358 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3359 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3361 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3362 CRYPT_AsnDecodePKCSContentInfoInternal
,
3363 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3364 ContentInfo
.pszObjId
), 0 },
3365 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3366 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3367 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3370 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3371 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3376 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3377 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3378 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3382 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3383 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3389 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3390 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3393 *pcbStructInfo
= bytesNeeded
;
3394 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3395 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3397 CERT_ALT_NAME_INFO
*name
;
3399 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3400 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3401 name
= pvStructInfo
;
3402 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3403 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3404 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3405 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3406 &bytesNeeded
, NULL
);
3412 SetLastError(STATUS_ACCESS_VIOLATION
);
3419 struct PATH_LEN_CONSTRAINT
3421 BOOL fPathLenConstraint
;
3422 DWORD dwPathLenConstraint
;
3425 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3426 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3430 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3432 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3433 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3437 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3439 *pcbStructInfo
= bytesNeeded
;
3441 else if (*pcbStructInfo
< bytesNeeded
)
3443 SetLastError(ERROR_MORE_DATA
);
3444 *pcbStructInfo
= bytesNeeded
;
3449 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3451 *pcbStructInfo
= bytesNeeded
;
3452 size
= sizeof(constraint
->dwPathLenConstraint
);
3453 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3454 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3456 constraint
->fPathLenConstraint
= TRUE
;
3457 TRACE("got an int, dwPathLenConstraint is %d\n",
3458 constraint
->dwPathLenConstraint
);
3460 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3464 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3465 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3469 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3470 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3471 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3472 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3473 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3474 offsetof(CERT_NAME_BLOB
, pbData
) };
3476 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3477 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3479 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3480 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3481 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3485 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3486 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3487 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3493 struct AsnDecodeSequenceItem items
[] = {
3494 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3495 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3496 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3497 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3498 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3499 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3500 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3501 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3502 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3504 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3507 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3508 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3509 pcbStructInfo
, NULL
, NULL
);
3513 SetLastError(STATUS_ACCESS_VIOLATION
);
3520 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3521 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3522 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3528 struct AsnDecodeSequenceItem items
[] = {
3529 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3530 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3531 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3532 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3533 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3536 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3537 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3538 pcbStructInfo
, NULL
, NULL
);
3542 SetLastError(STATUS_ACCESS_VIOLATION
);
3549 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3550 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3553 struct AsnDecodeSequenceItem items
[] = {
3554 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3555 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3556 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3558 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3559 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3560 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3563 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3565 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3566 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3568 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3569 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3570 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3574 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3575 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3579 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3580 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3581 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3582 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3583 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3584 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3586 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3587 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3589 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3590 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3591 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3595 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3596 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3598 struct AsnDecodeSequenceItem items
[] = {
3599 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3600 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3601 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3602 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3603 CRYPT_AsnDecodePolicyQualifiers
,
3604 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3605 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3607 CERT_POLICY_INFO
*info
= pvStructInfo
;
3610 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3611 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3613 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3614 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3615 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3619 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3620 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3621 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3625 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3626 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3630 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3631 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3632 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3633 sizeof(CERT_POLICIES_INFO
),
3634 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3635 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3637 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3638 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3642 SetLastError(STATUS_ACCESS_VIOLATION
);
3648 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3649 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3652 struct AsnDecodeSequenceItem items
[] = {
3653 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3654 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3655 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3656 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3657 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3658 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3660 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3663 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3664 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3666 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3667 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3668 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3672 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(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
, pvStructInfo
? *pcbStructInfo
: 0);
3683 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3684 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3685 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3686 sizeof(CERT_POLICY_MAPPING
),
3687 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3688 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3690 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3691 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3695 SetLastError(STATUS_ACCESS_VIOLATION
);
3701 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3702 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3706 DWORD skip
, size
= sizeof(skip
);
3710 SetLastError(CRYPT_E_ASN1_EOD
);
3713 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3715 SetLastError(CRYPT_E_ASN1_BADTAG
);
3718 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3719 &skip
, &size
, pcbDecoded
)))
3721 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3722 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3725 *pcbStructInfo
= bytesNeeded
;
3726 else if (*pcbStructInfo
< bytesNeeded
)
3728 *pcbStructInfo
= bytesNeeded
;
3729 SetLastError(ERROR_MORE_DATA
);
3734 CERT_POLICY_CONSTRAINTS_INFO
*info
=
3735 (CERT_POLICY_CONSTRAINTS_INFO
*)((BYTE
*)pvStructInfo
-
3736 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
));
3738 *pcbStructInfo
= bytesNeeded
;
3739 /* The BOOL is implicit: if the integer is present, then it's
3742 info
->fRequireExplicitPolicy
= TRUE
;
3743 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3749 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3750 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3754 DWORD skip
, size
= sizeof(skip
);
3758 SetLastError(CRYPT_E_ASN1_EOD
);
3761 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3763 SetLastError(CRYPT_E_ASN1_BADTAG
);
3766 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3767 &skip
, &size
, pcbDecoded
)))
3769 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3770 fInhibitPolicyMapping
);
3773 *pcbStructInfo
= bytesNeeded
;
3774 else if (*pcbStructInfo
< bytesNeeded
)
3776 *pcbStructInfo
= bytesNeeded
;
3777 SetLastError(ERROR_MORE_DATA
);
3782 CERT_POLICY_CONSTRAINTS_INFO
*info
=
3783 (CERT_POLICY_CONSTRAINTS_INFO
*)((BYTE
*)pvStructInfo
-
3784 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
));
3786 *pcbStructInfo
= bytesNeeded
;
3787 /* The BOOL is implicit: if the integer is present, then it's
3790 info
->fInhibitPolicyMapping
= TRUE
;
3791 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3797 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3798 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3799 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3800 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3804 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3805 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3809 struct AsnDecodeSequenceItem items
[] = {
3811 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3812 CRYPT_AsnDecodeRequireExplicit
,
3813 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3814 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3816 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3817 CRYPT_AsnDecodeInhibitMapping
,
3818 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3819 TRUE
, FALSE
, 0, 0 },
3822 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3823 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3824 pcbStructInfo
, NULL
, NULL
);
3828 SetLastError(STATUS_ACCESS_VIOLATION
);
3834 #define RSA1_MAGIC 0x31415352
3836 struct DECODED_RSA_PUB_KEY
3839 CRYPT_INTEGER_BLOB modulus
;
3842 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3843 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3844 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3850 struct AsnDecodeSequenceItem items
[] = {
3851 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3852 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3853 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3855 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3856 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3858 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3861 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3862 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3866 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3867 decodedKey
->modulus
.cbData
;
3871 *pcbStructInfo
= bytesNeeded
;
3874 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3875 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3878 RSAPUBKEY
*rsaPubKey
;
3880 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3881 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3883 hdr
->bType
= PUBLICKEYBLOB
;
3884 hdr
->bVersion
= CUR_BLOB_VERSION
;
3886 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3887 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3888 sizeof(BLOBHEADER
));
3889 rsaPubKey
->magic
= RSA1_MAGIC
;
3890 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3891 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3892 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3893 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3894 decodedKey
->modulus
.cbData
);
3896 LocalFree(decodedKey
);
3901 SetLastError(STATUS_ACCESS_VIOLATION
);
3908 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3909 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3913 DWORD bytesNeeded
, dataLen
;
3915 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3916 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3918 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3920 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3922 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3923 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3925 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3927 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3929 *pcbStructInfo
= bytesNeeded
;
3930 else if (*pcbStructInfo
< bytesNeeded
)
3932 SetLastError(ERROR_MORE_DATA
);
3933 *pcbStructInfo
= bytesNeeded
;
3938 CRYPT_DATA_BLOB
*blob
;
3940 *pcbStructInfo
= bytesNeeded
;
3941 blob
= pvStructInfo
;
3942 blob
->cbData
= dataLen
;
3943 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3944 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3947 assert(blob
->pbData
);
3949 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3957 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3958 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3959 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3963 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3964 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3972 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3975 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3977 SetLastError(CRYPT_E_ASN1_BADTAG
);
3980 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3981 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3984 *pcbStructInfo
= bytesNeeded
;
3985 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3986 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3988 CRYPT_DATA_BLOB
*blob
;
3990 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3991 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3992 blob
= pvStructInfo
;
3993 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3994 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3995 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3996 &bytesNeeded
, NULL
);
4002 SetLastError(STATUS_ACCESS_VIOLATION
);
4009 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4010 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4013 DWORD bytesNeeded
, dataLen
;
4014 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4016 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4017 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4019 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4021 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4022 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4024 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4026 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4028 *pcbStructInfo
= bytesNeeded
;
4029 else if (*pcbStructInfo
< bytesNeeded
)
4031 *pcbStructInfo
= bytesNeeded
;
4032 SetLastError(ERROR_MORE_DATA
);
4037 CRYPT_BIT_BLOB
*blob
;
4039 *pcbStructInfo
= bytesNeeded
;
4040 blob
= pvStructInfo
;
4041 blob
->cbData
= dataLen
- 1;
4042 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4043 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4045 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4049 assert(blob
->pbData
);
4052 BYTE mask
= 0xff << blob
->cUnusedBits
;
4054 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4056 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4064 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4065 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4066 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4070 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4071 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4079 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4082 else if (pbEncoded
[0] != ASN_BITSTRING
)
4084 SetLastError(CRYPT_E_ASN1_BADTAG
);
4087 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4088 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4091 *pcbStructInfo
= bytesNeeded
;
4092 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4093 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4095 CRYPT_BIT_BLOB
*blob
;
4097 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4098 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4099 blob
= pvStructInfo
;
4100 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4101 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4102 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4103 &bytesNeeded
, NULL
);
4109 SetLastError(STATUS_ACCESS_VIOLATION
);
4113 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4117 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4118 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4119 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4124 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4126 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4129 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4130 if (dataLen
> sizeof(int))
4132 SetLastError(CRYPT_E_ASN1_LARGE
);
4135 else if (!pvStructInfo
)
4136 *pcbStructInfo
= sizeof(int);
4137 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4141 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4143 /* initialize to a negative value to sign-extend */
4148 for (i
= 0; i
< dataLen
; i
++)
4151 val
|= pbEncoded
[1 + lenBytes
+ i
];
4153 memcpy(pvStructInfo
, &val
, sizeof(int));
4159 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4160 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4161 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4171 SetLastError(CRYPT_E_ASN1_EOD
);
4174 else if (pbEncoded
[0] != ASN_INTEGER
)
4176 SetLastError(CRYPT_E_ASN1_BADTAG
);
4180 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4181 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4185 *pcbStructInfo
= bytesNeeded
;
4186 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4187 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4189 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4190 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4191 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4192 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4193 &bytesNeeded
, NULL
);
4199 SetLastError(STATUS_ACCESS_VIOLATION
);
4206 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4207 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4211 DWORD bytesNeeded
, dataLen
;
4213 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4215 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4217 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4219 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4221 *pcbStructInfo
= bytesNeeded
;
4222 else if (*pcbStructInfo
< bytesNeeded
)
4224 *pcbStructInfo
= bytesNeeded
;
4225 SetLastError(ERROR_MORE_DATA
);
4230 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4232 *pcbStructInfo
= bytesNeeded
;
4233 blob
->cbData
= dataLen
;
4234 assert(blob
->pbData
);
4239 for (i
= 0; i
< blob
->cbData
; i
++)
4241 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4250 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4251 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4252 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4260 if (pbEncoded
[0] != ASN_INTEGER
)
4262 SetLastError(CRYPT_E_ASN1_BADTAG
);
4266 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4267 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4271 *pcbStructInfo
= bytesNeeded
;
4272 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4273 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4275 CRYPT_INTEGER_BLOB
*blob
;
4277 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4278 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4279 blob
= pvStructInfo
;
4280 blob
->pbData
= (BYTE
*)pvStructInfo
+
4281 sizeof(CRYPT_INTEGER_BLOB
);
4282 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4283 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4284 &bytesNeeded
, NULL
);
4290 SetLastError(STATUS_ACCESS_VIOLATION
);
4297 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4298 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4303 if (pbEncoded
[0] == ASN_INTEGER
)
4305 DWORD bytesNeeded
, dataLen
;
4307 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4309 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4312 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4313 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4315 *pcbStructInfo
= bytesNeeded
;
4316 else if (*pcbStructInfo
< bytesNeeded
)
4318 *pcbStructInfo
= bytesNeeded
;
4319 SetLastError(ERROR_MORE_DATA
);
4324 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4326 *pcbStructInfo
= bytesNeeded
;
4327 blob
->cbData
= dataLen
;
4328 assert(blob
->pbData
);
4329 /* remove leading zero byte if it exists */
4330 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4339 for (i
= 0; i
< blob
->cbData
; i
++)
4341 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4350 SetLastError(CRYPT_E_ASN1_BADTAG
);
4356 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4357 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4358 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4366 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4367 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4370 *pcbStructInfo
= bytesNeeded
;
4371 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4372 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4374 CRYPT_INTEGER_BLOB
*blob
;
4376 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4377 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4378 blob
= pvStructInfo
;
4379 blob
->pbData
= (BYTE
*)pvStructInfo
+
4380 sizeof(CRYPT_INTEGER_BLOB
);
4381 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4382 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4383 &bytesNeeded
, NULL
);
4389 SetLastError(STATUS_ACCESS_VIOLATION
);
4396 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4397 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4398 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4404 *pcbStructInfo
= sizeof(int);
4409 if (pbEncoded
[0] == ASN_ENUMERATED
)
4411 unsigned int val
= 0, i
;
4415 SetLastError(CRYPT_E_ASN1_EOD
);
4418 else if (pbEncoded
[1] == 0)
4420 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4425 /* A little strange looking, but we have to accept a sign byte:
4426 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4427 * assuming a small length is okay here, it has to be in short
4430 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4432 SetLastError(CRYPT_E_ASN1_LARGE
);
4435 for (i
= 0; i
< pbEncoded
[1]; i
++)
4438 val
|= pbEncoded
[2 + i
];
4440 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4441 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4443 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4444 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4445 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4451 SetLastError(CRYPT_E_ASN1_BADTAG
);
4457 SetLastError(STATUS_ACCESS_VIOLATION
);
4464 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4467 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4472 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4474 if (!isdigit(*(pbEncoded))) \
4476 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4482 (word) += *(pbEncoded)++ - '0'; \
4487 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4488 SYSTEMTIME
*sysTime
)
4492 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4494 WORD hours
, minutes
= 0;
4495 BYTE sign
= *pbEncoded
++;
4498 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4499 if (ret
&& hours
>= 24)
4501 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4506 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4507 if (ret
&& minutes
>= 60)
4509 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4517 sysTime
->wHour
+= hours
;
4518 sysTime
->wMinute
+= minutes
;
4522 if (hours
> sysTime
->wHour
)
4525 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4528 sysTime
->wHour
-= hours
;
4529 if (minutes
> sysTime
->wMinute
)
4532 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4535 sysTime
->wMinute
-= minutes
;
4542 #define MIN_ENCODED_TIME_LENGTH 10
4544 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4545 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4550 if (pbEncoded
[0] == ASN_UTCTIME
)
4553 SetLastError(CRYPT_E_ASN1_EOD
);
4554 else if (pbEncoded
[1] > 0x7f)
4556 /* long-form date strings really can't be valid */
4557 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4561 SYSTEMTIME sysTime
= { 0 };
4562 BYTE len
= pbEncoded
[1];
4564 if (len
< MIN_ENCODED_TIME_LENGTH
)
4565 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4570 *pcbDecoded
= 2 + len
;
4572 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4573 if (sysTime
.wYear
>= 50)
4574 sysTime
.wYear
+= 1900;
4576 sysTime
.wYear
+= 2000;
4577 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4578 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4579 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4580 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4583 if (len
>= 2 && isdigit(*pbEncoded
) &&
4584 isdigit(*(pbEncoded
+ 1)))
4585 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4587 else if (isdigit(*pbEncoded
))
4588 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4591 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4597 *pcbStructInfo
= sizeof(FILETIME
);
4598 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4600 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4606 SetLastError(CRYPT_E_ASN1_BADTAG
);
4610 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4611 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4612 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4620 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4621 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4625 *pcbStructInfo
= bytesNeeded
;
4626 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4627 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4629 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4630 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4631 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4632 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4633 &bytesNeeded
, NULL
);
4639 SetLastError(STATUS_ACCESS_VIOLATION
);
4645 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4646 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4651 if (pbEncoded
[0] == ASN_GENERALTIME
)
4654 SetLastError(CRYPT_E_ASN1_EOD
);
4655 else if (pbEncoded
[1] > 0x7f)
4657 /* long-form date strings really can't be valid */
4658 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4662 BYTE len
= pbEncoded
[1];
4664 if (len
< MIN_ENCODED_TIME_LENGTH
)
4665 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4668 SYSTEMTIME sysTime
= { 0 };
4672 *pcbDecoded
= 2 + len
;
4674 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4675 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4676 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4677 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4680 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4683 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4685 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4692 /* workaround macro weirdness */
4693 digits
= min(len
, 3);
4694 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4695 sysTime
.wMilliseconds
);
4698 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4704 *pcbStructInfo
= sizeof(FILETIME
);
4705 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4707 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4713 SetLastError(CRYPT_E_ASN1_BADTAG
);
4717 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4718 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4722 InternalDecodeFunc decode
= NULL
;
4724 if (pbEncoded
[0] == ASN_UTCTIME
)
4725 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4726 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4727 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4729 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4730 pcbStructInfo
, pcbDecoded
);
4733 SetLastError(CRYPT_E_ASN1_BADTAG
);
4739 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4740 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4741 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4749 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4750 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4754 *pcbStructInfo
= bytesNeeded
;
4755 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4756 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4758 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4759 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4760 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4761 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4762 &bytesNeeded
, NULL
);
4768 SetLastError(STATUS_ACCESS_VIOLATION
);
4775 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4776 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4777 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4783 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4785 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4787 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4792 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4793 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4795 ptr
= pbEncoded
+ 1 + lenBytes
;
4796 remainingLen
= dataLen
;
4797 while (ret
&& remainingLen
)
4801 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4804 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4806 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4807 ptr
+= 1 + nextLenBytes
+ nextLen
;
4808 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4809 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4810 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4816 CRYPT_SEQUENCE_OF_ANY
*seq
;
4821 *pcbStructInfo
= bytesNeeded
;
4822 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4823 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4825 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4826 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4828 seq
->cValue
= cValue
;
4829 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4831 nextPtr
= (BYTE
*)seq
->rgValue
+
4832 cValue
* sizeof(CRYPT_DER_BLOB
);
4833 ptr
= pbEncoded
+ 1 + lenBytes
;
4834 remainingLen
= dataLen
;
4836 while (ret
&& remainingLen
)
4840 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4843 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4845 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4847 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4848 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4851 seq
->rgValue
[i
].pbData
= nextPtr
;
4852 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4854 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4856 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4857 ptr
+= 1 + nextLenBytes
+ nextLen
;
4867 SetLastError(CRYPT_E_ASN1_BADTAG
);
4873 SetLastError(STATUS_ACCESS_VIOLATION
);
4880 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4881 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4886 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4888 DWORD bytesNeeded
, dataLen
;
4890 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4892 struct AsnArrayDescriptor arrayDesc
= {
4893 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4894 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
4895 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
4896 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
4897 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4898 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4899 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4904 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4905 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4906 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
4907 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4908 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
4911 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4913 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4915 *pcbStructInfo
= bytesNeeded
;
4916 else if (*pcbStructInfo
< bytesNeeded
)
4918 *pcbStructInfo
= bytesNeeded
;
4919 SetLastError(ERROR_MORE_DATA
);
4924 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4926 *pcbStructInfo
= bytesNeeded
;
4929 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4930 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4931 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4932 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
4936 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4942 SetLastError(CRYPT_E_ASN1_BADTAG
);
4948 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4949 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4951 struct AsnDecodeSequenceItem items
[] = {
4952 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4953 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4954 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4955 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4956 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4957 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4958 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4959 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4960 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4961 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4963 CRL_DIST_POINT
*point
= pvStructInfo
;
4966 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4967 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4968 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
4972 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4973 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4974 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4978 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4979 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4983 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4984 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
4985 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
4986 sizeof(CRL_DIST_POINTS_INFO
),
4987 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4988 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4990 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
4991 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
4995 SetLastError(STATUS_ACCESS_VIOLATION
);
5002 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5003 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5004 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5008 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5009 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5013 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5014 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5015 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5016 sizeof(CERT_ENHKEY_USAGE
),
5017 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5019 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5020 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5024 SetLastError(STATUS_ACCESS_VIOLATION
);
5031 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5032 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5033 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5037 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5038 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5042 struct AsnDecodeSequenceItem items
[] = {
5043 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5044 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5045 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5046 offsetof(CRL_ISSUING_DIST_POINT
,
5047 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5048 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5049 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5051 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5052 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5054 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5055 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5056 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5057 OnlySomeReasonFlags
.pbData
), 0 },
5058 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5059 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5062 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5063 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5064 pcbStructInfo
, NULL
, NULL
);
5068 SetLastError(STATUS_ACCESS_VIOLATION
);
5075 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5076 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5080 DWORD max
, size
= sizeof(max
);
5082 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5083 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5087 SetLastError(CRYPT_E_ASN1_EOD
);
5090 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5092 SetLastError(CRYPT_E_ASN1_BADTAG
);
5095 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5096 &max
, &size
, pcbDecoded
)))
5098 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5101 *pcbStructInfo
= bytesNeeded
;
5102 else if (*pcbStructInfo
< bytesNeeded
)
5104 *pcbStructInfo
= bytesNeeded
;
5105 SetLastError(ERROR_MORE_DATA
);
5110 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)
5111 ((BYTE
*)pvStructInfo
- offsetof(CERT_GENERAL_SUBTREE
, fMaximum
));
5113 *pcbStructInfo
= bytesNeeded
;
5114 /* The BOOL is implicit: if the integer is present, then it's
5117 subtree
->fMaximum
= TRUE
;
5118 subtree
->dwMaximum
= max
;
5121 TRACE("returning %d\n", ret
);
5125 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5126 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5130 struct AsnDecodeSequenceItem items
[] = {
5131 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5132 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5133 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5134 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5135 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5136 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5137 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5138 TRUE
, FALSE
, 0, 0 },
5140 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5142 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5143 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5145 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5146 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5147 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5150 TRACE("%d\n", *pcbDecoded
);
5151 if (*pcbDecoded
< cbEncoded
)
5152 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5153 *(pbEncoded
+ *pcbDecoded
+ 1));
5155 TRACE("returning %d\n", ret
);
5159 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5160 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5164 struct AsnArrayDescriptor arrayDesc
= { 0,
5165 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5166 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5167 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5169 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5170 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5172 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5173 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5175 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5176 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5180 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5181 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5185 struct AsnArrayDescriptor arrayDesc
= { 0,
5186 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5187 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5188 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5189 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5190 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5192 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5193 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5195 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5196 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5200 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5201 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5202 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5206 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5207 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5211 struct AsnDecodeSequenceItem items
[] = {
5212 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5213 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5214 CRYPT_AsnDecodePermittedSubtree
,
5215 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5216 cExcludedSubtree
), TRUE
, TRUE
,
5217 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5218 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5219 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5220 CRYPT_AsnDecodeExcludedSubtree
,
5221 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5223 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5226 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5227 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5228 pcbStructInfo
, NULL
, NULL
);
5232 SetLastError(STATUS_ACCESS_VIOLATION
);
5238 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5239 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5243 struct AsnDecodeSequenceItem items
[] = {
5244 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5245 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5247 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5248 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5249 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5251 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5253 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5254 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5256 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5257 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5258 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5259 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5261 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5264 TRACE("returning %d\n", ret
);
5268 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5269 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5272 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5273 struct AsnDecodeSequenceItem items
[] = {
5274 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5275 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5276 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5277 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5278 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5279 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5280 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5281 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5282 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5283 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5284 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5285 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5286 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5287 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5288 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5289 HashEncryptionAlgorithm
.pszObjId
), 0 },
5290 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5291 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5292 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5293 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5294 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5295 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5296 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5300 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5301 pvStructInfo
, *pcbStructInfo
);
5303 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5304 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5305 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5309 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5310 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5311 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5315 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5316 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5320 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5321 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5322 if (ret
&& pvStructInfo
)
5324 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5325 pcbStructInfo
, *pcbStructInfo
);
5328 CMSG_SIGNER_INFO
*info
;
5330 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5331 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5332 info
= pvStructInfo
;
5333 info
->Issuer
.pbData
= ((BYTE
*)info
+
5334 sizeof(CMSG_SIGNER_INFO
));
5335 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5336 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5337 pcbStructInfo
, NULL
);
5343 SetLastError(STATUS_ACCESS_VIOLATION
);
5346 TRACE("returning %d\n", ret
);
5350 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5351 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5355 struct AsnArrayDescriptor arrayDesc
= { 0,
5356 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5357 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5358 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5359 CRYPT_AsnDecodeCopyBytes
,
5360 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5362 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5363 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5365 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5366 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5370 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5371 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5375 struct AsnArrayDescriptor arrayDesc
= { 0,
5376 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5377 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5378 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5379 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5380 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5382 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5383 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5385 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5386 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5390 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5391 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5394 CERT_ID
*id
= pvStructInfo
;
5397 if (*pbEncoded
== ASN_SEQUENCEOF
)
5399 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5400 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5404 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5405 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5406 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5407 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5409 *pcbStructInfo
= sizeof(CERT_ID
);
5412 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5414 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5415 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5419 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5420 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5421 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5422 sizeof(CRYPT_DATA_BLOB
);
5424 *pcbStructInfo
= sizeof(CERT_ID
);
5428 SetLastError(CRYPT_E_ASN1_BADTAG
);
5432 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5433 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5436 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5437 struct AsnDecodeSequenceItem items
[] = {
5438 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5439 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5440 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5441 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5442 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5443 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5444 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5445 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5446 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5447 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5448 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5449 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5450 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5451 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5452 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5453 HashEncryptionAlgorithm
.pszObjId
), 0 },
5454 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5455 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5456 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5457 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5458 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5459 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5460 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5464 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5465 pvStructInfo
, *pcbStructInfo
);
5467 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5468 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5469 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5473 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5474 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5475 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5479 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5480 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5484 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5485 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5486 if (ret
&& pvStructInfo
)
5488 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5489 pcbStructInfo
, *pcbStructInfo
);
5492 CMSG_CMS_SIGNER_INFO
*info
;
5494 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5495 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5496 info
= pvStructInfo
;
5497 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5498 sizeof(CMSG_CMS_SIGNER_INFO
));
5499 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5500 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5501 pcbStructInfo
, NULL
);
5507 SetLastError(STATUS_ACCESS_VIOLATION
);
5510 TRACE("returning %d\n", ret
);
5514 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5515 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5518 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5519 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5520 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5521 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5522 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5523 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5525 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5526 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5528 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5529 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5533 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5534 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5535 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5538 struct AsnDecodeSequenceItem items
[] = {
5539 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5540 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5541 /* Placeholder for the hash algorithms - redundant with those in the
5542 * signers, so just ignore them.
5544 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5545 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5546 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5547 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5548 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5549 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5550 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5551 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5552 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5553 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5554 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5555 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5556 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5557 CRYPT_DecodeSignerArray
,
5558 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5559 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5562 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5563 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5565 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5566 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5568 TRACE("returning %d\n", ret
);
5572 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5573 LPCSTR lpszStructType
)
5575 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5577 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5578 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5580 SetLastError(ERROR_FILE_NOT_FOUND
);
5583 if (IS_INTOID(lpszStructType
))
5585 switch (LOWORD(lpszStructType
))
5587 case LOWORD(X509_CERT
):
5588 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5590 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5591 decodeFunc
= CRYPT_AsnDecodeCert
;
5593 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5594 decodeFunc
= CRYPT_AsnDecodeCRL
;
5596 case LOWORD(X509_EXTENSIONS
):
5597 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5599 case LOWORD(X509_NAME_VALUE
):
5600 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5602 case LOWORD(X509_NAME
):
5603 decodeFunc
= CRYPT_AsnDecodeName
;
5605 case LOWORD(X509_PUBLIC_KEY_INFO
):
5606 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5608 case LOWORD(X509_AUTHORITY_KEY_ID
):
5609 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5611 case LOWORD(X509_ALTERNATE_NAME
):
5612 decodeFunc
= CRYPT_AsnDecodeAltName
;
5614 case LOWORD(X509_BASIC_CONSTRAINTS
):
5615 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5617 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5618 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5620 case LOWORD(X509_CERT_POLICIES
):
5621 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5623 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5624 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5626 case LOWORD(X509_UNICODE_NAME
):
5627 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5629 case LOWORD(PKCS_ATTRIBUTE
):
5630 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5632 case LOWORD(X509_UNICODE_NAME_VALUE
):
5633 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5635 case LOWORD(X509_OCTET_STRING
):
5636 decodeFunc
= CRYPT_AsnDecodeOctets
;
5638 case LOWORD(X509_BITS
):
5639 case LOWORD(X509_KEY_USAGE
):
5640 decodeFunc
= CRYPT_AsnDecodeBits
;
5642 case LOWORD(X509_INTEGER
):
5643 decodeFunc
= CRYPT_AsnDecodeInt
;
5645 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5646 decodeFunc
= CRYPT_AsnDecodeInteger
;
5648 case LOWORD(X509_MULTI_BYTE_UINT
):
5649 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5651 case LOWORD(X509_ENUMERATED
):
5652 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5654 case LOWORD(X509_CHOICE_OF_TIME
):
5655 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5657 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5658 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5660 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5661 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5663 case LOWORD(PKCS_CONTENT_INFO
):
5664 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5666 case LOWORD(X509_SEQUENCE_OF_ANY
):
5667 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5669 case LOWORD(PKCS_UTC_TIME
):
5670 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5672 case LOWORD(X509_CRL_DIST_POINTS
):
5673 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5675 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5676 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5678 case LOWORD(PKCS_CTL
):
5679 decodeFunc
= CRYPT_AsnDecodeCTL
;
5681 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5682 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5684 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5685 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5687 case LOWORD(PKCS_ATTRIBUTES
):
5688 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5690 case LOWORD(X509_ISSUING_DIST_POINT
):
5691 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5693 case LOWORD(X509_NAME_CONSTRAINTS
):
5694 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5696 case LOWORD(X509_POLICY_MAPPINGS
):
5697 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5699 case LOWORD(X509_POLICY_CONSTRAINTS
):
5700 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5702 case LOWORD(PKCS7_SIGNER_INFO
):
5703 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5705 case LOWORD(CMS_SIGNER_INFO
):
5706 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5710 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5711 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5712 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5713 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5714 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5715 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5716 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5717 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5718 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
5719 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5720 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5721 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5722 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5723 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5724 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5725 decodeFunc
= CRYPT_AsnDecodeBits
;
5726 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5727 decodeFunc
= CRYPT_AsnDecodeOctets
;
5728 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5729 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5730 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5731 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5732 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5733 decodeFunc
= CRYPT_AsnDecodeAltName
;
5734 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5735 decodeFunc
= CRYPT_AsnDecodeAltName
;
5736 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5737 decodeFunc
= CRYPT_AsnDecodeAltName
;
5738 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5739 decodeFunc
= CRYPT_AsnDecodeAltName
;
5740 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5741 decodeFunc
= CRYPT_AsnDecodeAltName
;
5742 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5743 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5744 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5745 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5746 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
5747 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5748 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
5749 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5750 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5751 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5752 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5753 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5754 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5755 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5756 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5757 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5758 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5759 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5760 else if (!strcmp(lpszStructType
, szOID_CTL
))
5761 decodeFunc
= CRYPT_AsnDecodeCTL
;
5765 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5766 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5768 static HCRYPTOIDFUNCSET set
= NULL
;
5769 CryptDecodeObjectFunc decodeFunc
= NULL
;
5772 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5773 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5774 (void **)&decodeFunc
, hFunc
);
5778 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5779 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5781 static HCRYPTOIDFUNCSET set
= NULL
;
5782 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5785 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5786 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5787 (void **)&decodeFunc
, hFunc
);
5791 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5792 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5793 DWORD
*pcbStructInfo
)
5796 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5797 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5798 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5800 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5801 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5802 pvStructInfo
, pcbStructInfo
);
5804 if (!pvStructInfo
&& !pcbStructInfo
)
5806 SetLastError(ERROR_INVALID_PARAMETER
);
5809 if (cbEncoded
> MAX_ENCODED_LEN
)
5811 SetLastError(CRYPT_E_ASN1_LARGE
);
5815 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5818 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5819 debugstr_a(lpszStructType
));
5820 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5821 lpszStructType
, &hFunc
);
5822 if (!pCryptDecodeObject
)
5823 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5824 lpszStructType
, &hFunc
);
5826 if (pCryptDecodeObject
)
5827 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5828 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5829 else if (pCryptDecodeObjectEx
)
5830 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5831 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5832 pvStructInfo
, pcbStructInfo
);
5834 CryptFreeOIDFunctionAddress(hFunc
, 0);
5835 TRACE_(crypt
)("returning %d\n", ret
);
5839 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5840 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5841 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5844 CryptDecodeObjectExFunc decodeFunc
;
5845 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5847 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5848 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5849 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5851 if (!pvStructInfo
&& !pcbStructInfo
)
5853 SetLastError(ERROR_INVALID_PARAMETER
);
5856 if (cbEncoded
> MAX_ENCODED_LEN
)
5858 SetLastError(CRYPT_E_ASN1_LARGE
);
5862 SetLastError(NOERROR
);
5863 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5864 *(BYTE
**)pvStructInfo
= NULL
;
5865 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5868 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5869 debugstr_a(lpszStructType
));
5870 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5874 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5875 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5878 CryptDecodeObjectFunc pCryptDecodeObject
=
5879 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5881 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5882 * directly, as that could cause an infinite loop.
5884 if (pCryptDecodeObject
)
5886 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5888 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5889 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5890 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5891 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5892 ret
= pCryptDecodeObject(dwCertEncodingType
,
5893 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5894 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5897 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5898 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5902 CryptFreeOIDFunctionAddress(hFunc
, 0);
5903 TRACE_(crypt
)("returning %d\n", ret
);
5907 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
5911 TRACE_(crypt
)("(%p)\n", pPFX
);
5913 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5914 * version integer of length 1 (3 encoded byes) and at least one other
5915 * datum (two encoded bytes), plus at least two bytes for the outer
5916 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5918 if (pPFX
->cbData
< 7)
5920 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
5924 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
5926 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
5928 /* Need at least three bytes for the integer version */
5929 if (pPFX
->cbData
< 1 + lenLen
+ 3)
5931 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
5932 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
5933 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
5942 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
5945 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);