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 const CRYPT_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(const CRYPT_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 const CRYPT_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 *itemSizes
= itemSize
;
699 decoded
+= itemDecoded
;
700 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
701 itemSizes
[cItems
- 1].size
= size
;
714 *pcbDecoded
= decoded
;
716 *pcbStructInfo
= bytesNeeded
;
717 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
718 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
725 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
726 pvStructInfo
= *(void **)pvStructInfo
;
727 pcItems
= pvStructInfo
;
729 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
731 rgItems
= (BYTE
*)pvStructInfo
+
732 arrayDesc
->minArraySize
;
733 *(void **)((BYTE
*)pcItems
-
734 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
738 rgItems
= *(void **)((BYTE
*)pcItems
-
739 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
740 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
741 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
742 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
747 if (arrayDesc
->hasPointer
)
748 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
749 + arrayDesc
->pointerOffset
) = nextData
;
750 ret
= arrayDesc
->decodeFunc(ptr
,
751 itemSizes
[i
].encodedLen
,
752 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
753 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
754 &itemSizes
[i
].size
, &itemDecoded
);
757 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
761 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
762 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
765 if (itemSizes
!= &itemSize
)
766 CryptMemFree(itemSizes
);
771 SetLastError(CRYPT_E_ASN1_BADTAG
);
777 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
778 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
779 * to CRYPT_E_ASN1_CORRUPT.
780 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
783 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
784 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
789 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
791 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
792 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
794 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
795 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
798 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
800 *pcbStructInfo
= bytesNeeded
;
801 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
803 CRYPT_DER_BLOB
*blob
;
805 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
806 pvStructInfo
= *(BYTE
**)pvStructInfo
;
808 blob
->cbData
= 1 + lenBytes
+ dataLen
;
811 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
812 blob
->pbData
= (BYTE
*)pbEncoded
;
815 assert(blob
->pbData
);
816 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
821 SetLastError(CRYPT_E_ASN1_CORRUPT
);
829 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
830 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
831 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
836 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
837 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
839 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
842 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
843 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
845 if (ret
&& pvStructInfo
)
847 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
854 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
856 temp
= blob
->pbData
[i
];
857 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
858 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
862 TRACE("returning %d (%08x)\n", ret
, GetLastError());
866 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
867 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
868 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
872 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
873 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
877 struct AsnDecodeSequenceItem items
[] = {
878 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
879 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
880 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
881 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
882 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
883 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
884 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
885 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
886 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
887 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
890 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
891 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
892 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
893 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
894 pcbStructInfo
, NULL
, NULL
);
898 SetLastError(STATUS_ACCESS_VIOLATION
);
903 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
907 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
908 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
913 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
915 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
917 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
918 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
920 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
925 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
926 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
930 struct AsnDecodeSequenceItem items
[] = {
931 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
932 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
933 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
934 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
937 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
938 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
943 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
944 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
948 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
949 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
950 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
951 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
952 offsetof(CERT_EXTENSION
, pszObjId
) };
954 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
955 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
957 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
958 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
962 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
963 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
969 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
971 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
973 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
974 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
975 if (ret
&& pcbDecoded
)
976 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
981 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
982 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
983 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
986 struct AsnDecodeSequenceItem items
[] = {
987 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
988 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
989 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
990 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
991 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
992 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
993 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
994 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
995 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
996 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
998 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
999 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1001 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1002 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1004 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1005 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1006 FALSE
, TRUE
, offsetof(CERT_INFO
,
1007 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1008 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1009 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1010 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1011 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1012 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1013 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1014 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1015 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1016 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1019 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1020 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1022 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1023 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1025 if (ret
&& pvStructInfo
)
1029 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1030 info
= *(CERT_INFO
**)pvStructInfo
;
1032 info
= pvStructInfo
;
1033 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1034 !info
->Subject
.cbData
)
1036 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1037 /* Don't need to deallocate, because it should have failed on the
1038 * first pass (and no memory was allocated.)
1044 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1048 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1049 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1050 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1054 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1055 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1061 /* Unless told not to, first try to decode it as a signed cert. */
1062 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1064 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1066 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1067 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1068 &signedCert
, &size
);
1072 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1073 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1074 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1075 pvStructInfo
, pcbStructInfo
);
1076 LocalFree(signedCert
);
1079 /* Failing that, try it as an unsigned cert */
1083 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1084 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1085 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1090 SetLastError(STATUS_ACCESS_VIOLATION
);
1094 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1098 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1099 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1103 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1104 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1105 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1106 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1107 offsetof(CERT_EXTENSION
, pszObjId
) };
1109 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1110 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1112 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1113 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1117 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1118 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1121 struct AsnDecodeSequenceItem items
[] = {
1122 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1123 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1124 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1125 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1126 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1127 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1128 CRYPT_AsnDecodeCRLEntryExtensions
,
1129 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1130 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1132 PCRL_ENTRY entry
= pvStructInfo
;
1134 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1137 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1138 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1139 entry
? entry
->SerialNumber
.pbData
: NULL
);
1140 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1142 WARN("empty CRL entry serial number\n");
1143 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1149 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1150 * whose rgCRLEntry member has been set prior to calling.
1152 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1153 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1156 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1157 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1158 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1159 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1160 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1162 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1163 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1165 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1166 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1167 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1171 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1172 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1176 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1177 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1178 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1179 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1180 offsetof(CERT_EXTENSION
, pszObjId
) };
1182 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1183 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1185 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1186 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1190 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1191 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1197 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1199 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1201 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1202 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1203 if (ret
&& pcbDecoded
)
1204 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1209 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1210 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1211 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1213 struct AsnDecodeSequenceItem items
[] = {
1214 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1215 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1216 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1217 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1218 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1219 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1220 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1222 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1223 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1224 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1225 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1226 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1227 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1228 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1229 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1230 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1231 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1235 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1236 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1238 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1239 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1242 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1246 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1247 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1248 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1253 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1259 /* Unless told not to, first try to decode it as a signed crl. */
1260 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1262 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1264 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1265 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1270 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1271 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1272 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1273 pvStructInfo
, pcbStructInfo
);
1274 LocalFree(signedCrl
);
1277 /* Failing that, try it as an unsigned crl */
1281 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1282 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1283 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1288 SetLastError(STATUS_ACCESS_VIOLATION
);
1292 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1296 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1297 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1302 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1303 pvStructInfo
, *pcbStructInfo
);
1305 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1307 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1308 DWORD bytesNeeded
= sizeof(LPSTR
);
1315 snprintf(str
, sizeof(str
), "%d.%d",
1316 pbEncoded
[1 + lenBytes
] / 40,
1317 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1319 bytesNeeded
+= strlen(str
) + 1;
1320 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1321 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1325 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1332 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1335 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1342 snprintf(str
, sizeof(str
), ".%d", val
);
1343 bytesNeeded
+= strlen(str
);
1348 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1350 *pcbStructInfo
= bytesNeeded
;
1351 else if (*pcbStructInfo
< bytesNeeded
)
1353 *pcbStructInfo
= bytesNeeded
;
1354 SetLastError(ERROR_MORE_DATA
);
1362 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1365 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1366 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1368 pszObjId
+= strlen(pszObjId
);
1369 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1370 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1374 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1383 sprintf(pszObjId
, ".%d", val
);
1384 pszObjId
+= strlen(pszObjId
);
1388 *(LPSTR
*)pvStructInfo
= NULL
;
1389 *pcbStructInfo
= bytesNeeded
;
1395 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1396 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1400 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1401 pvStructInfo
, *pcbStructInfo
);
1403 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1404 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1405 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1408 SetLastError(CRYPT_E_ASN1_BADTAG
);
1414 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1415 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1417 struct AsnDecodeSequenceItem items
[] = {
1418 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1419 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1420 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1421 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1422 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1423 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1424 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1425 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1428 PCERT_EXTENSION ext
= pvStructInfo
;
1430 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1434 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1435 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1436 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1437 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1439 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1440 debugstr_a(ext
->pszObjId
));
1441 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1445 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1446 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1447 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1451 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1452 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1456 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1457 offsetof(CERT_EXTENSIONS
, cExtension
),
1458 offsetof(CERT_EXTENSIONS
, rgExtension
),
1459 sizeof(CERT_EXTENSIONS
),
1460 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1461 offsetof(CERT_EXTENSION
, pszObjId
) };
1462 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1464 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1465 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1466 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1467 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1471 SetLastError(STATUS_ACCESS_VIOLATION
);
1478 /* Warning: this assumes the address of value->Value.pbData is already set, in
1479 * order to avoid overwriting memory. (In some cases, it may change it, if it
1480 * doesn't copy anything to memory.) Be sure to set it correctly!
1482 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1483 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1488 CERT_NAME_VALUE
*value
= pvStructInfo
;
1490 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1492 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1493 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1495 switch (pbEncoded
[0])
1497 case ASN_OCTETSTRING
:
1498 valueType
= CERT_RDN_OCTET_STRING
;
1499 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1500 bytesNeeded
+= dataLen
;
1502 case ASN_NUMERICSTRING
:
1503 valueType
= CERT_RDN_NUMERIC_STRING
;
1504 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1505 bytesNeeded
+= dataLen
;
1507 case ASN_PRINTABLESTRING
:
1508 valueType
= CERT_RDN_PRINTABLE_STRING
;
1509 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1510 bytesNeeded
+= dataLen
;
1513 valueType
= CERT_RDN_IA5_STRING
;
1514 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1515 bytesNeeded
+= dataLen
;
1518 valueType
= CERT_RDN_T61_STRING
;
1519 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1520 bytesNeeded
+= dataLen
;
1522 case ASN_VIDEOTEXSTRING
:
1523 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1524 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1525 bytesNeeded
+= dataLen
;
1527 case ASN_GRAPHICSTRING
:
1528 valueType
= CERT_RDN_GRAPHIC_STRING
;
1529 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1530 bytesNeeded
+= dataLen
;
1532 case ASN_VISIBLESTRING
:
1533 valueType
= CERT_RDN_VISIBLE_STRING
;
1534 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1535 bytesNeeded
+= dataLen
;
1537 case ASN_GENERALSTRING
:
1538 valueType
= CERT_RDN_GENERAL_STRING
;
1539 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1540 bytesNeeded
+= dataLen
;
1542 case ASN_UNIVERSALSTRING
:
1543 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1544 SetLastError(CRYPT_E_ASN1_BADTAG
);
1547 valueType
= CERT_RDN_BMP_STRING
;
1548 bytesNeeded
+= dataLen
;
1550 case ASN_UTF8STRING
:
1551 valueType
= CERT_RDN_UTF8_STRING
;
1552 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1553 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1556 SetLastError(CRYPT_E_ASN1_BADTAG
);
1561 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1563 *pcbStructInfo
= bytesNeeded
;
1564 else if (*pcbStructInfo
< bytesNeeded
)
1566 *pcbStructInfo
= bytesNeeded
;
1567 SetLastError(ERROR_MORE_DATA
);
1572 *pcbStructInfo
= bytesNeeded
;
1573 value
->dwValueType
= valueType
;
1578 assert(value
->Value
.pbData
);
1579 switch (pbEncoded
[0])
1581 case ASN_OCTETSTRING
:
1582 case ASN_NUMERICSTRING
:
1583 case ASN_PRINTABLESTRING
:
1586 case ASN_VIDEOTEXSTRING
:
1587 case ASN_GRAPHICSTRING
:
1588 case ASN_VISIBLESTRING
:
1589 case ASN_GENERALSTRING
:
1590 value
->Value
.cbData
= dataLen
;
1593 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1594 memcpy(value
->Value
.pbData
,
1595 pbEncoded
+ 1 + lenBytes
, dataLen
);
1597 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1603 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1605 value
->Value
.cbData
= dataLen
;
1606 for (i
= 0; i
< dataLen
/ 2; i
++)
1607 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1608 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1611 case ASN_UTF8STRING
:
1613 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1615 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1616 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1617 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1624 value
->Value
.cbData
= 0;
1625 value
->Value
.pbData
= NULL
;
1632 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1633 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1634 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1640 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1641 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1642 if (ret
&& pvStructInfo
)
1644 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1645 pcbStructInfo
, *pcbStructInfo
);
1648 CERT_NAME_VALUE
*value
;
1650 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1651 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1652 value
= pvStructInfo
;
1653 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1654 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1655 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1656 pcbStructInfo
, NULL
);
1657 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1658 CRYPT_FreeSpace(pDecodePara
, value
);
1664 SetLastError(STATUS_ACCESS_VIOLATION
);
1671 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1672 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1677 CERT_NAME_VALUE
*value
= pvStructInfo
;
1679 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1681 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1682 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1684 switch (pbEncoded
[0])
1686 case ASN_NUMERICSTRING
:
1687 valueType
= CERT_RDN_NUMERIC_STRING
;
1689 bytesNeeded
+= (dataLen
+ 1) * 2;
1691 case ASN_PRINTABLESTRING
:
1692 valueType
= CERT_RDN_PRINTABLE_STRING
;
1694 bytesNeeded
+= (dataLen
+ 1) * 2;
1697 valueType
= CERT_RDN_IA5_STRING
;
1699 bytesNeeded
+= (dataLen
+ 1) * 2;
1702 valueType
= CERT_RDN_T61_STRING
;
1704 bytesNeeded
+= (dataLen
+ 1) * 2;
1706 case ASN_VIDEOTEXSTRING
:
1707 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1709 bytesNeeded
+= (dataLen
+ 1) * 2;
1711 case ASN_GRAPHICSTRING
:
1712 valueType
= CERT_RDN_GRAPHIC_STRING
;
1714 bytesNeeded
+= (dataLen
+ 1) * 2;
1716 case ASN_VISIBLESTRING
:
1717 valueType
= CERT_RDN_VISIBLE_STRING
;
1719 bytesNeeded
+= (dataLen
+ 1) * 2;
1721 case ASN_GENERALSTRING
:
1722 valueType
= CERT_RDN_GENERAL_STRING
;
1724 bytesNeeded
+= (dataLen
+ 1) * 2;
1726 case ASN_UNIVERSALSTRING
:
1727 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1729 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1732 valueType
= CERT_RDN_BMP_STRING
;
1734 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1736 case ASN_UTF8STRING
:
1737 valueType
= CERT_RDN_UTF8_STRING
;
1739 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1740 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1743 SetLastError(CRYPT_E_ASN1_BADTAG
);
1748 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1750 *pcbStructInfo
= bytesNeeded
;
1751 else if (*pcbStructInfo
< bytesNeeded
)
1753 *pcbStructInfo
= bytesNeeded
;
1754 SetLastError(ERROR_MORE_DATA
);
1759 *pcbStructInfo
= bytesNeeded
;
1760 value
->dwValueType
= valueType
;
1764 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1766 assert(value
->Value
.pbData
);
1767 switch (pbEncoded
[0])
1769 case ASN_NUMERICSTRING
:
1770 case ASN_PRINTABLESTRING
:
1773 case ASN_VIDEOTEXSTRING
:
1774 case ASN_GRAPHICSTRING
:
1775 case ASN_VISIBLESTRING
:
1776 case ASN_GENERALSTRING
:
1777 value
->Value
.cbData
= dataLen
* 2;
1778 for (i
= 0; i
< dataLen
; i
++)
1779 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1782 case ASN_UNIVERSALSTRING
:
1783 value
->Value
.cbData
= dataLen
/ 2;
1784 for (i
= 0; i
< dataLen
/ 4; i
++)
1785 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1786 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1790 value
->Value
.cbData
= dataLen
;
1791 for (i
= 0; i
< dataLen
/ 2; i
++)
1792 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1793 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1796 case ASN_UTF8STRING
:
1797 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1798 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1799 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1800 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1801 value
->Value
.cbData
+= sizeof(WCHAR
);
1807 value
->Value
.cbData
= 0;
1808 value
->Value
.pbData
= NULL
;
1815 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1816 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1817 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1823 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1824 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1825 if (ret
&& pvStructInfo
)
1827 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1828 pcbStructInfo
, *pcbStructInfo
);
1831 CERT_NAME_VALUE
*value
;
1833 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1834 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1835 value
= pvStructInfo
;
1836 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1837 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1838 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1839 pcbStructInfo
, NULL
);
1840 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1841 CRYPT_FreeSpace(pDecodePara
, value
);
1847 SetLastError(STATUS_ACCESS_VIOLATION
);
1854 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1855 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1858 struct AsnDecodeSequenceItem items
[] = {
1859 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1860 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1861 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1862 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1863 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1864 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1866 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1868 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1869 pvStructInfo
, *pcbStructInfo
);
1872 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1873 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1874 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1875 attr
? attr
->pszObjId
: NULL
);
1878 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1879 debugstr_a(attr
->pszObjId
));
1880 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1882 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1886 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1887 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1890 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1891 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1893 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1894 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1896 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1897 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1901 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1902 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1903 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1909 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1910 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1911 sizeof(CERT_NAME_INFO
),
1912 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1913 offsetof(CERT_RDN
, rgRDNAttr
) };
1914 DWORD bytesNeeded
= 0;
1916 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1917 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1922 *pcbStructInfo
= bytesNeeded
;
1923 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1924 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1926 CERT_NAME_INFO
*info
;
1928 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1929 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1930 info
= pvStructInfo
;
1931 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1932 sizeof(CERT_NAME_INFO
));
1933 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1934 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1935 &bytesNeeded
, NULL
);
1936 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1937 CRYPT_FreeSpace(pDecodePara
, info
);
1943 SetLastError(STATUS_ACCESS_VIOLATION
);
1950 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1951 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1955 struct AsnDecodeSequenceItem items
[] = {
1956 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1957 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1958 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1959 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1960 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1961 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1963 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1965 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1966 pvStructInfo
, *pcbStructInfo
);
1969 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1970 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1971 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1972 attr
? attr
->pszObjId
: NULL
);
1975 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1976 debugstr_a(attr
->pszObjId
));
1977 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1979 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1983 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1984 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1987 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1988 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1990 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1991 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1993 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1994 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1998 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1999 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2000 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2006 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2007 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2008 sizeof(CERT_NAME_INFO
),
2009 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2010 offsetof(CERT_RDN
, rgRDNAttr
) };
2011 DWORD bytesNeeded
= 0;
2013 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2014 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2019 *pcbStructInfo
= bytesNeeded
;
2020 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2021 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2023 CERT_NAME_INFO
*info
;
2025 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2026 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2027 info
= pvStructInfo
;
2028 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2029 sizeof(CERT_NAME_INFO
));
2030 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2031 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2032 &bytesNeeded
, NULL
);
2033 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2034 CRYPT_FreeSpace(pDecodePara
, info
);
2040 SetLastError(STATUS_ACCESS_VIOLATION
);
2047 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2050 BOOL ret
= TRUE
, done
= FALSE
;
2051 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2053 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2060 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2063 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2065 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2067 indefiniteNestingLevels
++;
2068 pbEncoded
+= 1 + lenBytes
;
2069 cbEncoded
-= 1 + lenBytes
;
2070 decoded
+= 1 + lenBytes
;
2071 TRACE("indefiniteNestingLevels = %d\n",
2072 indefiniteNestingLevels
);
2076 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2077 indefiniteNestingLevels
)
2079 indefiniteNestingLevels
--;
2080 TRACE("indefiniteNestingLevels = %d\n",
2081 indefiniteNestingLevels
);
2083 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2084 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2085 decoded
+= 1 + lenBytes
+ dataLen
;
2086 if (!indefiniteNestingLevels
)
2090 } while (ret
&& !done
);
2091 /* If we haven't found all 0 TLVs, we haven't found the end */
2092 if (ret
&& indefiniteNestingLevels
)
2094 SetLastError(CRYPT_E_ASN1_EOD
);
2098 *pcbDecoded
= decoded
;
2099 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2103 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2104 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2108 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2110 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2111 pvStructInfo
, *pcbStructInfo
);
2113 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2115 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2116 bytesNeeded
+= encodedLen
;
2118 *pcbStructInfo
= bytesNeeded
;
2119 else if (*pcbStructInfo
< bytesNeeded
)
2121 SetLastError(ERROR_MORE_DATA
);
2122 *pcbStructInfo
= bytesNeeded
;
2127 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2129 *pcbStructInfo
= bytesNeeded
;
2130 blob
->cbData
= encodedLen
;
2133 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2134 blob
->pbData
= (LPBYTE
)pbEncoded
;
2137 assert(blob
->pbData
);
2138 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2142 blob
->pbData
= NULL
;
2145 *pcbDecoded
= encodedLen
;
2150 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2151 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2154 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2155 offsetof(CTL_USAGE
, cUsageIdentifier
),
2156 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2158 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2160 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2161 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2165 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2166 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2169 struct AsnArrayDescriptor arrayDesc
= { 0,
2170 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2171 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2172 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2173 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2176 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2177 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2181 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2182 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2184 struct AsnDecodeSequenceItem items
[] = {
2185 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2186 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2187 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2188 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2189 CRYPT_AsnDecodeCTLEntryAttributes
,
2190 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2191 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2194 CTL_ENTRY
*entry
= pvStructInfo
;
2196 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2199 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2200 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2201 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2205 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2206 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2209 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2210 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2211 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2212 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2213 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2215 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2216 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2218 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2219 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2223 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2224 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2228 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2229 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2230 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2231 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2232 offsetof(CERT_EXTENSION
, pszObjId
) };
2234 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2235 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2237 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2238 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2242 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2243 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2249 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2251 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2253 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2254 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2255 if (ret
&& pcbDecoded
)
2256 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2261 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2262 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2263 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2267 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2268 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2272 struct AsnDecodeSequenceItem items
[] = {
2273 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2274 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2275 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2276 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2277 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2278 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2279 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2280 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2281 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2282 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2283 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2284 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2285 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2287 { 0, offsetof(CTL_INFO
, NextUpdate
),
2288 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2290 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2291 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2292 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2293 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2294 CRYPT_AsnDecodeCTLEntries
,
2295 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2296 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2297 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2298 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2299 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2302 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2303 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2304 pcbStructInfo
, NULL
, NULL
);
2308 SetLastError(STATUS_ACCESS_VIOLATION
);
2314 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2315 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2319 struct AsnDecodeSequenceItem items
[] = {
2320 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2321 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2322 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2323 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2324 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2325 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2327 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2329 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2330 pvStructInfo
, *pcbStructInfo
);
2332 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2333 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2334 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2335 TRACE("returning %d\n", ret
);
2339 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2340 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2341 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2345 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2346 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2350 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2351 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2352 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2353 sizeof(CRYPT_SMIME_CAPABILITIES
),
2354 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2355 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2356 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2358 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2359 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2360 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2361 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2365 SetLastError(STATUS_ACCESS_VIOLATION
);
2368 TRACE("returning %d\n", ret
);
2372 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2373 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2378 LPSTR
*pStr
= pvStructInfo
;
2380 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2382 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2383 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2385 if (pbEncoded
[0] != ASN_IA5STRING
)
2387 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2392 bytesNeeded
+= dataLen
;
2394 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2396 *pcbStructInfo
= bytesNeeded
;
2397 else if (*pcbStructInfo
< bytesNeeded
)
2399 *pcbStructInfo
= bytesNeeded
;
2400 SetLastError(ERROR_MORE_DATA
);
2405 *pcbStructInfo
= bytesNeeded
;
2411 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2422 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2423 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2426 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2427 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2429 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2430 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2433 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2434 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2436 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2437 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2438 TRACE("returning %d\n", ret
);
2442 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2443 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2447 struct AsnDecodeSequenceItem items
[] = {
2448 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2449 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2450 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2451 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2452 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2453 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2454 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2455 rgNoticeNumbers
), 0 },
2457 DWORD bytesNeeded
= 0;
2459 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2460 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2462 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2463 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2467 /* The caller is expecting a pointer to a
2468 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2469 * CRYPT_AsnDecodeSequence is decoding a
2470 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2471 * needed, and decode again if the requisite space is available.
2473 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2475 *pcbStructInfo
= bytesNeeded
;
2476 else if (*pcbStructInfo
< bytesNeeded
)
2478 *pcbStructInfo
= bytesNeeded
;
2479 SetLastError(ERROR_MORE_DATA
);
2484 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2486 *pcbStructInfo
= bytesNeeded
;
2487 /* The pointer (pvStructInfo) passed in points to the first dynamic
2488 * pointer, so use it as the pointer to the
2489 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2490 * appropriate offset for the first dynamic pointer within the
2491 * notice reference by pointing to the first memory location past
2492 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2495 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2496 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2497 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2498 ret
= CRYPT_AsnDecodeSequence(items
,
2499 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2500 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2501 noticeRef
->pszOrganization
);
2504 TRACE("returning %d\n", ret
);
2508 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2509 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2515 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2517 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2518 DWORD bytesNeeded
= sizeof(LPWSTR
);
2520 switch (pbEncoded
[0])
2522 case ASN_NUMERICSTRING
:
2524 bytesNeeded
+= (dataLen
+ 1) * 2;
2526 case ASN_PRINTABLESTRING
:
2528 bytesNeeded
+= (dataLen
+ 1) * 2;
2532 bytesNeeded
+= (dataLen
+ 1) * 2;
2536 bytesNeeded
+= (dataLen
+ 1) * 2;
2538 case ASN_VIDEOTEXSTRING
:
2540 bytesNeeded
+= (dataLen
+ 1) * 2;
2542 case ASN_GRAPHICSTRING
:
2544 bytesNeeded
+= (dataLen
+ 1) * 2;
2546 case ASN_VISIBLESTRING
:
2548 bytesNeeded
+= (dataLen
+ 1) * 2;
2550 case ASN_GENERALSTRING
:
2552 bytesNeeded
+= (dataLen
+ 1) * 2;
2554 case ASN_UNIVERSALSTRING
:
2556 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2560 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2562 case ASN_UTF8STRING
:
2564 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2565 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2568 SetLastError(CRYPT_E_ASN1_BADTAG
);
2573 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2575 *pcbStructInfo
= bytesNeeded
;
2576 else if (*pcbStructInfo
< bytesNeeded
)
2578 *pcbStructInfo
= bytesNeeded
;
2579 SetLastError(ERROR_MORE_DATA
);
2584 LPWSTR
*pStr
= pvStructInfo
;
2586 *pcbStructInfo
= bytesNeeded
;
2590 LPWSTR str
= *(LPWSTR
*)pStr
;
2593 switch (pbEncoded
[0])
2595 case ASN_NUMERICSTRING
:
2596 case ASN_PRINTABLESTRING
:
2599 case ASN_VIDEOTEXSTRING
:
2600 case ASN_GRAPHICSTRING
:
2601 case ASN_VISIBLESTRING
:
2602 case ASN_GENERALSTRING
:
2603 for (i
= 0; i
< dataLen
; i
++)
2604 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2607 case ASN_UNIVERSALSTRING
:
2608 for (i
= 0; i
< dataLen
/ 4; i
++)
2609 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2610 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2614 for (i
= 0; i
< dataLen
/ 2; i
++)
2615 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2616 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2619 case ASN_UTF8STRING
:
2621 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2622 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2623 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2636 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2637 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2638 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2641 struct AsnDecodeSequenceItem items
[] = {
2642 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2643 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2644 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2645 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2646 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2647 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2648 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2650 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2652 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2653 pvStructInfo
, *pcbStructInfo
);
2655 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2656 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2657 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2658 TRACE("returning %d\n", ret
);
2662 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2663 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2664 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2665 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2669 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2670 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2674 DWORD bytesNeeded
= 0;
2676 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2677 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2682 *pcbStructInfo
= bytesNeeded
;
2683 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2684 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2686 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2688 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2689 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2690 notice
= pvStructInfo
;
2691 notice
->pNoticeReference
=
2692 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2693 ((BYTE
*)pvStructInfo
+
2694 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2695 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2696 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2697 pvStructInfo
, &bytesNeeded
, NULL
);
2698 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2699 CRYPT_FreeSpace(pDecodePara
, notice
);
2705 SetLastError(STATUS_ACCESS_VIOLATION
);
2708 TRACE("returning %d\n", ret
);
2712 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2713 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2717 struct AsnArrayDescriptor arrayDesc
= { 0,
2718 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2719 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2720 CRYPT_AsnDecodeCopyBytes
,
2721 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2723 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2724 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2726 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2727 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2731 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2732 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2736 struct AsnDecodeSequenceItem items
[] = {
2737 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2738 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2739 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2740 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2741 CRYPT_AsnDecodePKCSAttributeValue
,
2742 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2743 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2745 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2747 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2748 pvStructInfo
, *pcbStructInfo
);
2750 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2751 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2752 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2753 TRACE("returning %d\n", ret
);
2757 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2758 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2759 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2763 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2764 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2768 DWORD bytesNeeded
= 0;
2770 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2771 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2775 *pcbStructInfo
= bytesNeeded
;
2776 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2777 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2779 PCRYPT_ATTRIBUTE attr
;
2781 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2782 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2783 attr
= pvStructInfo
;
2784 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2785 sizeof(CRYPT_ATTRIBUTE
));
2786 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2787 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2789 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2790 CRYPT_FreeSpace(pDecodePara
, attr
);
2796 SetLastError(STATUS_ACCESS_VIOLATION
);
2799 TRACE("returning %d\n", ret
);
2803 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2804 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2807 struct AsnArrayDescriptor arrayDesc
= { 0,
2808 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2809 sizeof(CRYPT_ATTRIBUTES
),
2810 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2811 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2814 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2815 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2819 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2820 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2821 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2825 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2826 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2830 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2831 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2832 sizeof(CRYPT_ATTRIBUTES
),
2833 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2834 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2835 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2837 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2838 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2839 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2840 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2844 SetLastError(STATUS_ACCESS_VIOLATION
);
2847 TRACE("returning %d\n", ret
);
2851 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2852 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2854 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2856 struct AsnDecodeSequenceItem items
[] = {
2857 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2858 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2859 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2860 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2861 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2862 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2865 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2866 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2868 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2869 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2870 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2871 if (ret
&& pvStructInfo
)
2873 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2874 debugstr_a(algo
->pszObjId
));
2879 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2880 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2884 struct AsnDecodeSequenceItem items
[] = {
2885 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2886 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2887 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2888 Algorithm
.pszObjId
) },
2889 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2890 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2891 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2893 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2895 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2896 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2897 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2901 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2902 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2903 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2909 DWORD bytesNeeded
= 0;
2911 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2912 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2915 *pcbStructInfo
= bytesNeeded
;
2916 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2917 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2919 PCERT_PUBLIC_KEY_INFO info
;
2921 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2922 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2923 info
= pvStructInfo
;
2924 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2925 sizeof(CERT_PUBLIC_KEY_INFO
);
2926 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2927 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2928 &bytesNeeded
, NULL
);
2929 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2930 CRYPT_FreeSpace(pDecodePara
, info
);
2936 SetLastError(STATUS_ACCESS_VIOLATION
);
2943 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2944 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2950 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2953 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2955 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2958 if (pbEncoded
[1] > 1)
2960 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2967 *pcbStructInfo
= sizeof(BOOL
);
2970 else if (*pcbStructInfo
< sizeof(BOOL
))
2972 *pcbStructInfo
= sizeof(BOOL
);
2973 SetLastError(ERROR_MORE_DATA
);
2978 *pcbStructInfo
= sizeof(BOOL
);
2979 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2982 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2986 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2987 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2989 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2990 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2993 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2994 pvStructInfo
, *pcbStructInfo
);
2998 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3001 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3002 if (1 + lenBytes
> cbEncoded
)
3004 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3007 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3009 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3011 case 1: /* rfc822Name */
3012 case 2: /* dNSName */
3013 case 6: /* uniformResourceIdentifier */
3014 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3016 SetLastError(CRYPT_E_ASN1_RULE
);
3020 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3022 case 4: /* directoryName */
3023 case 7: /* iPAddress */
3024 bytesNeeded
+= dataLen
;
3026 case 8: /* registeredID */
3027 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3031 /* FIXME: ugly, shouldn't need to know internals of OID decode
3032 * function to use it.
3034 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3037 case 0: /* otherName */
3038 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3039 SetLastError(CRYPT_E_ASN1_BADTAG
);
3042 case 3: /* x400Address, unimplemented */
3043 case 5: /* ediPartyName, unimplemented */
3044 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3045 SetLastError(CRYPT_E_ASN1_BADTAG
);
3049 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3050 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3056 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3058 *pcbStructInfo
= bytesNeeded
;
3059 else if (*pcbStructInfo
< bytesNeeded
)
3061 *pcbStructInfo
= bytesNeeded
;
3062 SetLastError(ERROR_MORE_DATA
);
3067 *pcbStructInfo
= bytesNeeded
;
3068 /* MS used values one greater than the asn1 ones.. sigh */
3069 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3070 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3072 case 1: /* rfc822Name */
3073 case 2: /* dNSName */
3074 case 6: /* uniformResourceIdentifier */
3078 for (i
= 0; i
< dataLen
; i
++)
3079 entry
->u
.pwszURL
[i
] =
3080 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3081 entry
->u
.pwszURL
[i
] = 0;
3082 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3083 debugstr_w(entry
->u
.pwszURL
));
3086 case 4: /* directoryName */
3087 /* The data are memory-equivalent with the IPAddress case,
3090 case 7: /* iPAddress */
3091 /* The next data pointer is in the pwszURL spot, that is,
3092 * the first 4 bytes. Need to move it to the next spot.
3094 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3095 entry
->u
.IPAddress
.cbData
= dataLen
;
3096 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3099 case 8: /* registeredID */
3100 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3101 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3110 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3111 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3115 struct AsnArrayDescriptor arrayDesc
= { 0,
3116 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3117 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3118 sizeof(CERT_ALT_NAME_INFO
),
3119 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3120 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3122 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3123 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3125 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3126 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3130 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3131 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3132 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3138 struct AsnDecodeSequenceItem items
[] = {
3139 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3140 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3141 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3142 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3143 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3144 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3145 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3146 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3147 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3148 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3149 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3152 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3153 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3154 pcbStructInfo
, NULL
, NULL
);
3158 SetLastError(STATUS_ACCESS_VIOLATION
);
3165 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3166 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3167 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3173 struct AsnDecodeSequenceItem items
[] = {
3174 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3175 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3176 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3177 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3178 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3179 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3180 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3181 AuthorityCertIssuer
.rgAltEntry
), 0 },
3182 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3183 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3184 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3185 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3186 AuthorityCertSerialNumber
.pbData
), 0 },
3189 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3190 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3191 pcbStructInfo
, NULL
, NULL
);
3195 SetLastError(STATUS_ACCESS_VIOLATION
);
3202 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3203 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3206 struct AsnDecodeSequenceItem items
[] = {
3207 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3208 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3209 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3210 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3211 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3212 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3214 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3216 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3217 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3218 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3221 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3222 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3223 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3227 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3228 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3232 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3233 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3234 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3235 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3236 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3237 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3238 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3240 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3241 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3242 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3243 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3247 SetLastError(STATUS_ACCESS_VIOLATION
);
3254 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3255 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3260 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3261 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3263 /* The caller has already checked the tag, no need to check it again.
3264 * Check the outer length is valid:
3266 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3268 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3271 pbEncoded
+= 1 + lenBytes
;
3272 cbEncoded
-= 1 + lenBytes
;
3273 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3274 cbEncoded
-= 2; /* space for 0 TLV */
3275 /* Check the inner length is valid: */
3276 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3280 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3281 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3282 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3284 if (*(pbEncoded
+ decodedLen
) != 0 ||
3285 *(pbEncoded
+ decodedLen
+ 1) != 0)
3287 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3288 *(pbEncoded
+ decodedLen
),
3289 *(pbEncoded
+ decodedLen
+ 1));
3290 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3296 if (ret
&& pcbDecoded
)
3298 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3299 TRACE("decoded %d bytes\n", *pcbDecoded
);
3306 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3307 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3310 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3311 struct AsnDecodeSequenceItem items
[] = {
3312 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3313 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3314 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3315 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3316 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3317 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3318 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3322 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3323 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3325 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3326 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3327 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3331 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3332 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3333 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3337 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3338 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3342 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3343 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3344 if (ret
&& pvStructInfo
)
3346 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3347 pcbStructInfo
, *pcbStructInfo
);
3350 CRYPT_CONTENT_INFO
*info
;
3352 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3353 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3354 info
= pvStructInfo
;
3355 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3356 sizeof(CRYPT_CONTENT_INFO
));
3357 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3358 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3359 pcbStructInfo
, NULL
);
3360 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3361 CRYPT_FreeSpace(pDecodePara
, info
);
3367 SetLastError(STATUS_ACCESS_VIOLATION
);
3373 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3374 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3375 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3378 struct AsnDecodeSequenceItem items
[] = {
3379 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3380 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3381 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3382 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3383 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3385 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3386 CRYPT_AsnDecodePKCSContentInfoInternal
,
3387 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3388 ContentInfo
.pszObjId
), 0 },
3389 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3390 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3391 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3394 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3395 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3400 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3401 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3402 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3406 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3407 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3411 DWORD bytesNeeded
= 0;
3413 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3414 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3417 *pcbStructInfo
= bytesNeeded
;
3418 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3419 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3421 CERT_ALT_NAME_INFO
*name
;
3423 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3424 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3425 name
= pvStructInfo
;
3426 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3427 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3428 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3429 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3430 &bytesNeeded
, NULL
);
3431 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3432 CRYPT_FreeSpace(pDecodePara
, name
);
3438 SetLastError(STATUS_ACCESS_VIOLATION
);
3445 struct PATH_LEN_CONSTRAINT
3447 BOOL fPathLenConstraint
;
3448 DWORD dwPathLenConstraint
;
3451 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3452 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3456 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3458 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3459 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3463 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3465 *pcbStructInfo
= bytesNeeded
;
3467 else if (*pcbStructInfo
< bytesNeeded
)
3469 SetLastError(ERROR_MORE_DATA
);
3470 *pcbStructInfo
= bytesNeeded
;
3475 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3477 *pcbStructInfo
= bytesNeeded
;
3478 size
= sizeof(constraint
->dwPathLenConstraint
);
3479 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3480 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3482 constraint
->fPathLenConstraint
= TRUE
;
3483 TRACE("got an int, dwPathLenConstraint is %d\n",
3484 constraint
->dwPathLenConstraint
);
3486 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3490 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3491 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3495 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3496 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3497 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3498 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3499 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3500 offsetof(CERT_NAME_BLOB
, pbData
) };
3502 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3503 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3505 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3506 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3507 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3511 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3512 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3513 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3519 struct AsnDecodeSequenceItem items
[] = {
3520 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3521 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3522 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3523 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3524 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3525 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3526 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3527 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3528 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3530 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3533 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3534 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3535 pcbStructInfo
, NULL
, NULL
);
3539 SetLastError(STATUS_ACCESS_VIOLATION
);
3546 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3547 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3548 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3554 struct AsnDecodeSequenceItem items
[] = {
3555 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3556 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3557 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3558 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3559 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3562 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3563 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3564 pcbStructInfo
, NULL
, NULL
);
3568 SetLastError(STATUS_ACCESS_VIOLATION
);
3575 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3576 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3579 struct AsnDecodeSequenceItem items
[] = {
3580 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3581 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3582 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3584 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3585 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3586 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3589 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3591 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3592 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3594 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3595 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3596 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3600 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3601 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3605 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3606 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3607 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3608 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3609 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3610 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3612 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3613 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3615 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3616 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3617 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3621 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3622 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3624 struct AsnDecodeSequenceItem items
[] = {
3625 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3626 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3627 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3628 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3629 CRYPT_AsnDecodePolicyQualifiers
,
3630 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3631 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3633 CERT_POLICY_INFO
*info
= pvStructInfo
;
3636 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3637 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3639 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3640 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3641 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3645 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3646 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3647 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3651 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3652 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3656 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3657 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3658 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3659 sizeof(CERT_POLICIES_INFO
),
3660 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3661 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3662 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3664 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3665 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3667 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3668 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3672 SetLastError(STATUS_ACCESS_VIOLATION
);
3678 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3679 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3682 struct AsnDecodeSequenceItem items
[] = {
3683 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3684 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3685 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3686 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3687 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3688 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3690 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3693 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3694 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3696 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3697 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3698 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3702 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3703 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3704 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3708 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3709 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3713 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3714 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3715 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3716 sizeof(CERT_POLICY_MAPPING
),
3717 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3718 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3719 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3721 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3722 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3723 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3724 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3728 SetLastError(STATUS_ACCESS_VIOLATION
);
3734 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3735 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3739 DWORD skip
, size
= sizeof(skip
);
3743 SetLastError(CRYPT_E_ASN1_EOD
);
3746 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3748 SetLastError(CRYPT_E_ASN1_BADTAG
);
3751 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3752 &skip
, &size
, pcbDecoded
)))
3754 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3755 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3758 *pcbStructInfo
= bytesNeeded
;
3759 else if (*pcbStructInfo
< bytesNeeded
)
3761 *pcbStructInfo
= bytesNeeded
;
3762 SetLastError(ERROR_MORE_DATA
);
3767 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3768 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3770 *pcbStructInfo
= bytesNeeded
;
3771 /* The BOOL is implicit: if the integer is present, then it's
3774 info
->fRequireExplicitPolicy
= TRUE
;
3775 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3781 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3782 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3786 DWORD skip
, size
= sizeof(skip
);
3790 SetLastError(CRYPT_E_ASN1_EOD
);
3793 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3795 SetLastError(CRYPT_E_ASN1_BADTAG
);
3798 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3799 &skip
, &size
, pcbDecoded
)))
3801 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3802 fInhibitPolicyMapping
);
3805 *pcbStructInfo
= bytesNeeded
;
3806 else if (*pcbStructInfo
< bytesNeeded
)
3808 *pcbStructInfo
= bytesNeeded
;
3809 SetLastError(ERROR_MORE_DATA
);
3814 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3815 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3817 *pcbStructInfo
= bytesNeeded
;
3818 /* The BOOL is implicit: if the integer is present, then it's
3821 info
->fInhibitPolicyMapping
= TRUE
;
3822 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3828 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3829 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3830 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3831 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3835 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3836 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3840 struct AsnDecodeSequenceItem items
[] = {
3842 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3843 CRYPT_AsnDecodeRequireExplicit
,
3844 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3845 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3847 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3848 CRYPT_AsnDecodeInhibitMapping
,
3849 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3850 TRUE
, FALSE
, 0, 0 },
3853 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3854 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3855 pcbStructInfo
, NULL
, NULL
);
3859 SetLastError(STATUS_ACCESS_VIOLATION
);
3865 #define RSA1_MAGIC 0x31415352
3867 struct DECODED_RSA_PUB_KEY
3870 CRYPT_INTEGER_BLOB modulus
;
3873 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3874 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3875 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3881 struct AsnDecodeSequenceItem items
[] = {
3882 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3883 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3884 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3886 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3887 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3889 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3892 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3893 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3897 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3898 decodedKey
->modulus
.cbData
;
3902 *pcbStructInfo
= bytesNeeded
;
3905 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3906 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3909 RSAPUBKEY
*rsaPubKey
;
3911 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3912 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3914 hdr
->bType
= PUBLICKEYBLOB
;
3915 hdr
->bVersion
= CUR_BLOB_VERSION
;
3917 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3918 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3919 sizeof(BLOBHEADER
));
3920 rsaPubKey
->magic
= RSA1_MAGIC
;
3921 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3922 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3923 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3924 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3925 decodedKey
->modulus
.cbData
);
3927 LocalFree(decodedKey
);
3932 SetLastError(STATUS_ACCESS_VIOLATION
);
3939 #define RSA2_MAGIC 0x32415352
3941 struct DECODED_RSA_PRIV_KEY
3945 CRYPT_INTEGER_BLOB modulus
;
3946 CRYPT_INTEGER_BLOB privexp
;
3947 CRYPT_INTEGER_BLOB prime1
;
3948 CRYPT_INTEGER_BLOB prime2
;
3949 CRYPT_INTEGER_BLOB exponent1
;
3950 CRYPT_INTEGER_BLOB exponent2
;
3951 CRYPT_INTEGER_BLOB coefficient
;
3954 static BOOL WINAPI
CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType
,
3955 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3956 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3963 struct AsnDecodeSequenceItem items
[] = {
3964 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, version
),
3965 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3966 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
),
3967 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3968 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
.pbData
),
3970 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, pubexp
),
3971 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3972 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
),
3973 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3974 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
.pbData
),
3976 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
),
3977 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3978 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
.pbData
),
3980 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
),
3981 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3982 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
.pbData
),
3984 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
),
3985 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3986 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
.pbData
),
3988 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
),
3989 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3990 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
.pbData
),
3992 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
),
3993 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3994 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
.pbData
),
3997 struct DECODED_RSA_PRIV_KEY
*decodedKey
= NULL
;
4000 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4001 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
4005 halflen
= decodedKey
->prime1
.cbData
;
4006 if (halflen
< decodedKey
->prime2
.cbData
)
4007 halflen
= decodedKey
->prime2
.cbData
;
4008 if (halflen
< decodedKey
->exponent1
.cbData
)
4009 halflen
= decodedKey
->exponent1
.cbData
;
4010 if (halflen
< decodedKey
->exponent2
.cbData
)
4011 halflen
= decodedKey
->exponent2
.cbData
;
4012 if (halflen
< decodedKey
->coefficient
.cbData
)
4013 halflen
= decodedKey
->coefficient
.cbData
;
4014 if (halflen
* 2 < decodedKey
->modulus
.cbData
)
4015 halflen
= decodedKey
->modulus
.cbData
/ 2 + decodedKey
->modulus
.cbData
% 2;
4016 if (halflen
* 2 < decodedKey
->privexp
.cbData
)
4017 halflen
= decodedKey
->privexp
.cbData
/ 2 + decodedKey
->privexp
.cbData
% 2;
4021 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
4026 *pcbStructInfo
= bytesNeeded
;
4029 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4030 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4033 RSAPUBKEY
*rsaPubKey
;
4036 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4037 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4040 hdr
->bType
= PRIVATEKEYBLOB
;
4041 hdr
->bVersion
= CUR_BLOB_VERSION
;
4043 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4045 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4046 sizeof(BLOBHEADER
));
4047 rsaPubKey
->magic
= RSA2_MAGIC
;
4048 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4049 rsaPubKey
->bitlen
= halflen
* 16;
4051 vardata
= (BYTE
*)(rsaPubKey
+ 1);
4052 memset(vardata
, 0, halflen
* 9);
4054 decodedKey
->modulus
.pbData
, decodedKey
->modulus
.cbData
);
4055 memcpy(vardata
+ halflen
* 2,
4056 decodedKey
->prime1
.pbData
, decodedKey
->prime1
.cbData
);
4057 memcpy(vardata
+ halflen
* 3,
4058 decodedKey
->prime2
.pbData
, decodedKey
->prime2
.cbData
);
4059 memcpy(vardata
+ halflen
* 4,
4060 decodedKey
->exponent1
.pbData
, decodedKey
->exponent1
.cbData
);
4061 memcpy(vardata
+ halflen
* 5,
4062 decodedKey
->exponent2
.pbData
, decodedKey
->exponent2
.cbData
);
4063 memcpy(vardata
+ halflen
* 6,
4064 decodedKey
->coefficient
.pbData
, decodedKey
->coefficient
.cbData
);
4065 memcpy(vardata
+ halflen
* 7,
4066 decodedKey
->privexp
.pbData
, decodedKey
->privexp
.cbData
);
4070 LocalFree(decodedKey
);
4075 SetLastError(STATUS_ACCESS_VIOLATION
);
4082 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
4083 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4087 DWORD bytesNeeded
, dataLen
;
4089 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4090 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4092 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4094 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4096 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4097 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4099 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4101 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4103 *pcbStructInfo
= bytesNeeded
;
4104 else if (*pcbStructInfo
< bytesNeeded
)
4106 SetLastError(ERROR_MORE_DATA
);
4107 *pcbStructInfo
= bytesNeeded
;
4112 CRYPT_DATA_BLOB
*blob
;
4114 *pcbStructInfo
= bytesNeeded
;
4115 blob
= pvStructInfo
;
4116 blob
->cbData
= dataLen
;
4117 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4118 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4121 assert(blob
->pbData
);
4123 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4131 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
4132 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4133 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4137 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4138 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4142 DWORD bytesNeeded
= 0;
4146 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4149 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
4151 SetLastError(CRYPT_E_ASN1_BADTAG
);
4154 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4155 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4158 *pcbStructInfo
= bytesNeeded
;
4159 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4160 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4162 CRYPT_DATA_BLOB
*blob
;
4164 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4165 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4166 blob
= pvStructInfo
;
4167 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4168 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4169 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4170 &bytesNeeded
, NULL
);
4171 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4172 CRYPT_FreeSpace(pDecodePara
, blob
);
4178 SetLastError(STATUS_ACCESS_VIOLATION
);
4185 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4186 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4189 DWORD bytesNeeded
, dataLen
;
4190 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4192 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4193 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4195 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4197 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4198 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4200 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4202 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4204 *pcbStructInfo
= bytesNeeded
;
4205 else if (*pcbStructInfo
< bytesNeeded
)
4207 *pcbStructInfo
= bytesNeeded
;
4208 SetLastError(ERROR_MORE_DATA
);
4213 CRYPT_BIT_BLOB
*blob
;
4215 *pcbStructInfo
= bytesNeeded
;
4216 blob
= pvStructInfo
;
4217 blob
->cbData
= dataLen
- 1;
4218 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4219 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4221 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4225 assert(blob
->pbData
);
4228 BYTE mask
= 0xff << blob
->cUnusedBits
;
4230 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4232 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4240 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4241 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4242 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4246 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4247 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4251 DWORD bytesNeeded
= 0;
4255 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4258 else if (pbEncoded
[0] != ASN_BITSTRING
)
4260 SetLastError(CRYPT_E_ASN1_BADTAG
);
4263 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4264 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4267 *pcbStructInfo
= bytesNeeded
;
4268 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4269 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4271 CRYPT_BIT_BLOB
*blob
;
4273 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4274 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4275 blob
= pvStructInfo
;
4276 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4277 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4278 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4279 &bytesNeeded
, NULL
);
4280 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4281 CRYPT_FreeSpace(pDecodePara
, blob
);
4287 SetLastError(STATUS_ACCESS_VIOLATION
);
4291 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4295 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4296 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4297 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4302 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4304 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4307 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4308 if (dataLen
> sizeof(int))
4310 SetLastError(CRYPT_E_ASN1_LARGE
);
4313 else if (!pvStructInfo
)
4314 *pcbStructInfo
= sizeof(int);
4315 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4319 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4321 /* initialize to a negative value to sign-extend */
4326 for (i
= 0; i
< dataLen
; i
++)
4329 val
|= pbEncoded
[1 + lenBytes
+ i
];
4331 memcpy(pvStructInfo
, &val
, sizeof(int));
4337 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4338 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4339 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4345 DWORD bytesNeeded
= 0;
4349 SetLastError(CRYPT_E_ASN1_EOD
);
4352 else if (pbEncoded
[0] != ASN_INTEGER
)
4354 SetLastError(CRYPT_E_ASN1_BADTAG
);
4358 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4359 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4363 *pcbStructInfo
= bytesNeeded
;
4364 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4365 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4367 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4368 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4369 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4370 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4371 &bytesNeeded
, NULL
);
4372 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4373 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4379 SetLastError(STATUS_ACCESS_VIOLATION
);
4386 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4387 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4391 DWORD bytesNeeded
, dataLen
;
4393 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4395 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4397 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4399 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4401 *pcbStructInfo
= bytesNeeded
;
4402 else if (*pcbStructInfo
< bytesNeeded
)
4404 *pcbStructInfo
= bytesNeeded
;
4405 SetLastError(ERROR_MORE_DATA
);
4410 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4412 *pcbStructInfo
= bytesNeeded
;
4413 blob
->cbData
= dataLen
;
4414 assert(blob
->pbData
);
4419 for (i
= 0; i
< blob
->cbData
; i
++)
4421 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4430 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4431 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4432 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4438 DWORD bytesNeeded
= 0;
4440 if (pbEncoded
[0] != ASN_INTEGER
)
4442 SetLastError(CRYPT_E_ASN1_BADTAG
);
4446 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4447 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4451 *pcbStructInfo
= bytesNeeded
;
4452 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4453 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4455 CRYPT_INTEGER_BLOB
*blob
;
4457 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4458 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4459 blob
= pvStructInfo
;
4460 blob
->pbData
= (BYTE
*)pvStructInfo
+
4461 sizeof(CRYPT_INTEGER_BLOB
);
4462 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4463 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4464 &bytesNeeded
, NULL
);
4465 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4466 CRYPT_FreeSpace(pDecodePara
, blob
);
4472 SetLastError(STATUS_ACCESS_VIOLATION
);
4479 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4480 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4485 if (pbEncoded
[0] == ASN_INTEGER
)
4487 DWORD bytesNeeded
, dataLen
;
4489 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4491 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4494 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4495 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4497 *pcbStructInfo
= bytesNeeded
;
4498 else if (*pcbStructInfo
< bytesNeeded
)
4500 *pcbStructInfo
= bytesNeeded
;
4501 SetLastError(ERROR_MORE_DATA
);
4506 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4508 *pcbStructInfo
= bytesNeeded
;
4509 blob
->cbData
= dataLen
;
4510 assert(blob
->pbData
);
4511 /* remove leading zero byte if it exists */
4512 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4521 for (i
= 0; i
< blob
->cbData
; i
++)
4523 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4532 SetLastError(CRYPT_E_ASN1_BADTAG
);
4538 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4539 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4540 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4546 DWORD bytesNeeded
= 0;
4548 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4549 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4552 *pcbStructInfo
= bytesNeeded
;
4553 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4554 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4556 CRYPT_INTEGER_BLOB
*blob
;
4558 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4559 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4560 blob
= pvStructInfo
;
4561 blob
->pbData
= (BYTE
*)pvStructInfo
+
4562 sizeof(CRYPT_INTEGER_BLOB
);
4563 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4564 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4565 &bytesNeeded
, NULL
);
4566 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4567 CRYPT_FreeSpace(pDecodePara
, blob
);
4573 SetLastError(STATUS_ACCESS_VIOLATION
);
4580 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4581 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4582 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4588 *pcbStructInfo
= sizeof(int);
4593 if (pbEncoded
[0] == ASN_ENUMERATED
)
4595 unsigned int val
= 0, i
;
4599 SetLastError(CRYPT_E_ASN1_EOD
);
4602 else if (pbEncoded
[1] == 0)
4604 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4609 /* A little strange looking, but we have to accept a sign byte:
4610 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4611 * assuming a small length is okay here, it has to be in short
4614 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4616 SetLastError(CRYPT_E_ASN1_LARGE
);
4619 for (i
= 0; i
< pbEncoded
[1]; i
++)
4622 val
|= pbEncoded
[2 + i
];
4624 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4625 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4627 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4628 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4629 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4635 SetLastError(CRYPT_E_ASN1_BADTAG
);
4641 SetLastError(STATUS_ACCESS_VIOLATION
);
4648 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4651 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4656 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4658 if (!isdigit(*(pbEncoded))) \
4660 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4666 (word) += *(pbEncoded)++ - '0'; \
4671 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4672 SYSTEMTIME
*sysTime
)
4676 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4678 WORD hours
, minutes
= 0;
4679 BYTE sign
= *pbEncoded
++;
4682 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4683 if (ret
&& hours
>= 24)
4685 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4690 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4691 if (ret
&& minutes
>= 60)
4693 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4701 sysTime
->wHour
+= hours
;
4702 sysTime
->wMinute
+= minutes
;
4706 if (hours
> sysTime
->wHour
)
4709 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4712 sysTime
->wHour
-= hours
;
4713 if (minutes
> sysTime
->wMinute
)
4716 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4719 sysTime
->wMinute
-= minutes
;
4726 #define MIN_ENCODED_TIME_LENGTH 10
4728 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4729 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4734 if (pbEncoded
[0] == ASN_UTCTIME
)
4737 SetLastError(CRYPT_E_ASN1_EOD
);
4738 else if (pbEncoded
[1] > 0x7f)
4740 /* long-form date strings really can't be valid */
4741 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4745 SYSTEMTIME sysTime
= { 0 };
4746 BYTE len
= pbEncoded
[1];
4748 if (len
< MIN_ENCODED_TIME_LENGTH
)
4749 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4754 *pcbDecoded
= 2 + len
;
4756 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4757 if (sysTime
.wYear
>= 50)
4758 sysTime
.wYear
+= 1900;
4760 sysTime
.wYear
+= 2000;
4761 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4762 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4763 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4764 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4767 if (len
>= 2 && isdigit(*pbEncoded
) &&
4768 isdigit(*(pbEncoded
+ 1)))
4769 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4771 else if (isdigit(*pbEncoded
))
4772 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4775 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4781 *pcbStructInfo
= sizeof(FILETIME
);
4782 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4784 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4790 SetLastError(CRYPT_E_ASN1_BADTAG
);
4794 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4795 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4796 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4802 DWORD bytesNeeded
= 0;
4804 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4805 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4809 *pcbStructInfo
= bytesNeeded
;
4810 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4811 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4813 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4814 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4815 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4816 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4817 &bytesNeeded
, NULL
);
4818 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4819 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4825 SetLastError(STATUS_ACCESS_VIOLATION
);
4831 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4832 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4837 if (pbEncoded
[0] == ASN_GENERALTIME
)
4840 SetLastError(CRYPT_E_ASN1_EOD
);
4841 else if (pbEncoded
[1] > 0x7f)
4843 /* long-form date strings really can't be valid */
4844 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4848 BYTE len
= pbEncoded
[1];
4850 if (len
< MIN_ENCODED_TIME_LENGTH
)
4851 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4854 SYSTEMTIME sysTime
= { 0 };
4858 *pcbDecoded
= 2 + len
;
4860 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4861 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4862 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4863 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4866 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4869 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4871 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4878 /* workaround macro weirdness */
4879 digits
= min(len
, 3);
4880 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4881 sysTime
.wMilliseconds
);
4884 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4890 *pcbStructInfo
= sizeof(FILETIME
);
4891 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4893 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4899 SetLastError(CRYPT_E_ASN1_BADTAG
);
4903 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4904 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4908 InternalDecodeFunc decode
= NULL
;
4910 if (pbEncoded
[0] == ASN_UTCTIME
)
4911 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4912 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4913 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4915 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4916 pcbStructInfo
, pcbDecoded
);
4919 SetLastError(CRYPT_E_ASN1_BADTAG
);
4925 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4926 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4927 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4933 DWORD bytesNeeded
= 0;
4935 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4936 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4940 *pcbStructInfo
= bytesNeeded
;
4941 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4942 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4944 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4945 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4946 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4947 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4948 &bytesNeeded
, NULL
);
4949 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4950 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4956 SetLastError(STATUS_ACCESS_VIOLATION
);
4963 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4964 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4965 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4971 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4973 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4975 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4980 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4981 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4983 ptr
= pbEncoded
+ 1 + lenBytes
;
4984 remainingLen
= dataLen
;
4985 while (ret
&& remainingLen
)
4989 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4992 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4994 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4995 ptr
+= 1 + nextLenBytes
+ nextLen
;
4996 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4997 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4998 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
5004 CRYPT_SEQUENCE_OF_ANY
*seq
;
5009 *pcbStructInfo
= bytesNeeded
;
5010 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5011 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5013 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5014 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5016 seq
->cValue
= cValue
;
5017 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
5019 nextPtr
= (BYTE
*)seq
->rgValue
+
5020 cValue
* sizeof(CRYPT_DER_BLOB
);
5021 ptr
= pbEncoded
+ 1 + lenBytes
;
5022 remainingLen
= dataLen
;
5024 while (ret
&& remainingLen
)
5028 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5031 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5033 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
5035 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
5036 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
5039 seq
->rgValue
[i
].pbData
= nextPtr
;
5040 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
5042 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
5044 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5045 ptr
+= 1 + nextLenBytes
+ nextLen
;
5049 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5050 CRYPT_FreeSpace(pDecodePara
, seq
);
5057 SetLastError(CRYPT_E_ASN1_BADTAG
);
5063 SetLastError(STATUS_ACCESS_VIOLATION
);
5070 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
5071 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5076 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5078 DWORD bytesNeeded
= 0, dataLen
;
5080 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5082 struct AsnArrayDescriptor arrayDesc
= {
5083 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5084 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
5085 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
5086 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
5087 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5088 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
5089 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5094 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5095 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5096 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
5097 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
5098 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
5101 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5103 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5105 *pcbStructInfo
= bytesNeeded
;
5106 else if (*pcbStructInfo
< bytesNeeded
)
5108 *pcbStructInfo
= bytesNeeded
;
5109 SetLastError(ERROR_MORE_DATA
);
5114 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5116 *pcbStructInfo
= bytesNeeded
;
5119 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5120 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5121 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5122 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
5126 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5132 SetLastError(CRYPT_E_ASN1_BADTAG
);
5138 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5139 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5141 struct AsnDecodeSequenceItem items
[] = {
5142 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5143 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5144 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5145 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5146 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5147 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5148 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5149 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5150 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5151 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5153 CRL_DIST_POINT
*point
= pvStructInfo
;
5156 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5157 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5158 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5162 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5163 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5164 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5168 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5169 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5173 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5174 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5175 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5176 sizeof(CRL_DIST_POINTS_INFO
),
5177 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5178 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5179 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5181 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5182 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5183 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5184 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5188 SetLastError(STATUS_ACCESS_VIOLATION
);
5195 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5196 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5197 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5201 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5202 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5206 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5207 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5208 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5209 sizeof(CERT_ENHKEY_USAGE
),
5210 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5211 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5213 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5214 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5215 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5216 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5220 SetLastError(STATUS_ACCESS_VIOLATION
);
5227 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5228 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5229 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5233 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5234 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5238 struct AsnDecodeSequenceItem items
[] = {
5239 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5240 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5241 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5242 offsetof(CRL_ISSUING_DIST_POINT
,
5243 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5244 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5245 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5247 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5248 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5250 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5251 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5252 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5253 OnlySomeReasonFlags
.pbData
), 0 },
5254 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5255 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5258 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5259 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5260 pcbStructInfo
, NULL
, NULL
);
5264 SetLastError(STATUS_ACCESS_VIOLATION
);
5271 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5272 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5276 DWORD max
, size
= sizeof(max
);
5278 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5279 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5283 SetLastError(CRYPT_E_ASN1_EOD
);
5286 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5288 SetLastError(CRYPT_E_ASN1_BADTAG
);
5291 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5292 &max
, &size
, pcbDecoded
)))
5294 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5297 *pcbStructInfo
= bytesNeeded
;
5298 else if (*pcbStructInfo
< bytesNeeded
)
5300 *pcbStructInfo
= bytesNeeded
;
5301 SetLastError(ERROR_MORE_DATA
);
5306 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5307 CERT_GENERAL_SUBTREE
, fMaximum
);
5309 *pcbStructInfo
= bytesNeeded
;
5310 /* The BOOL is implicit: if the integer is present, then it's
5313 subtree
->fMaximum
= TRUE
;
5314 subtree
->dwMaximum
= max
;
5317 TRACE("returning %d\n", ret
);
5321 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5322 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5326 struct AsnDecodeSequenceItem items
[] = {
5327 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5328 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5329 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5330 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5331 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5332 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5333 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5334 TRUE
, FALSE
, 0, 0 },
5336 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5338 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5339 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5341 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5342 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5343 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5346 TRACE("%d\n", *pcbDecoded
);
5347 if (*pcbDecoded
< cbEncoded
)
5348 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5349 *(pbEncoded
+ *pcbDecoded
+ 1));
5351 TRACE("returning %d\n", ret
);
5355 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5356 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5360 struct AsnArrayDescriptor arrayDesc
= { 0,
5361 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5362 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5363 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5365 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5366 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5368 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5369 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5371 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5372 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5376 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5377 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5381 struct AsnArrayDescriptor arrayDesc
= { 0,
5382 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5383 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5384 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5385 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5386 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5388 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5389 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5391 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5392 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5396 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5397 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5398 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5402 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5403 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5407 struct AsnDecodeSequenceItem items
[] = {
5408 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5409 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5410 CRYPT_AsnDecodePermittedSubtree
,
5411 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5412 cExcludedSubtree
), TRUE
, TRUE
,
5413 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5414 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5415 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5416 CRYPT_AsnDecodeExcludedSubtree
,
5417 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5419 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5422 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5423 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5424 pcbStructInfo
, NULL
, NULL
);
5428 SetLastError(STATUS_ACCESS_VIOLATION
);
5434 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5435 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5439 struct AsnDecodeSequenceItem items
[] = {
5440 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5441 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5443 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5444 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5445 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5447 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5449 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5450 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5452 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5453 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5454 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5455 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5457 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5460 TRACE("returning %d\n", ret
);
5464 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5465 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5468 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5469 struct AsnDecodeSequenceItem items
[] = {
5470 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5471 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5472 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5473 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5474 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5475 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5476 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5477 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5478 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5479 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5480 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5481 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5482 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5483 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5484 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5485 HashEncryptionAlgorithm
.pszObjId
), 0 },
5486 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5487 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5488 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5489 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5490 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5491 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5492 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5496 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5497 pvStructInfo
, *pcbStructInfo
);
5499 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5500 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5501 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5505 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5506 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5507 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5511 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5512 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5516 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5517 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5518 if (ret
&& pvStructInfo
)
5520 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5521 pcbStructInfo
, *pcbStructInfo
);
5524 CMSG_SIGNER_INFO
*info
;
5526 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5527 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5528 info
= pvStructInfo
;
5529 info
->Issuer
.pbData
= ((BYTE
*)info
+
5530 sizeof(CMSG_SIGNER_INFO
));
5531 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5532 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5533 pcbStructInfo
, NULL
);
5534 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5535 CRYPT_FreeSpace(pDecodePara
, info
);
5541 SetLastError(STATUS_ACCESS_VIOLATION
);
5544 TRACE("returning %d\n", ret
);
5548 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5549 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5553 struct AsnArrayDescriptor arrayDesc
= { 0,
5554 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5555 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5556 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5557 CRYPT_AsnDecodeCopyBytes
,
5558 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5560 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5561 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5563 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5564 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5568 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5569 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5573 struct AsnArrayDescriptor arrayDesc
= { 0,
5574 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5575 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5576 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5577 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5578 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5580 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5581 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5583 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5584 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5588 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5589 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5592 CERT_ID
*id
= pvStructInfo
;
5595 if (*pbEncoded
== ASN_SEQUENCEOF
)
5597 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5598 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5602 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5603 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5604 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5605 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5607 *pcbStructInfo
= sizeof(CERT_ID
);
5610 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5612 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5613 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5617 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5618 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5619 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5620 sizeof(CRYPT_DATA_BLOB
);
5622 *pcbStructInfo
= sizeof(CERT_ID
);
5626 SetLastError(CRYPT_E_ASN1_BADTAG
);
5630 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5631 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5634 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5635 struct AsnDecodeSequenceItem items
[] = {
5636 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5637 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5638 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5639 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5640 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5641 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5642 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5643 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5644 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5645 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5646 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5647 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5648 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5649 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5650 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5651 HashEncryptionAlgorithm
.pszObjId
), 0 },
5652 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5653 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5654 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5655 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5656 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5657 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5658 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5662 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5663 pvStructInfo
, *pcbStructInfo
);
5665 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5666 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5667 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5671 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5672 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5673 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5677 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5678 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5682 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5683 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5684 if (ret
&& pvStructInfo
)
5686 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5687 pcbStructInfo
, *pcbStructInfo
);
5690 CMSG_CMS_SIGNER_INFO
*info
;
5692 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5693 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5694 info
= pvStructInfo
;
5695 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5696 sizeof(CMSG_CMS_SIGNER_INFO
));
5697 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5698 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5699 pcbStructInfo
, NULL
);
5700 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5701 CRYPT_FreeSpace(pDecodePara
, info
);
5707 SetLastError(STATUS_ACCESS_VIOLATION
);
5710 TRACE("returning %d\n", ret
);
5714 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5715 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5718 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5719 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5720 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5721 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5722 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5723 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5725 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5726 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5728 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5729 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5733 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5734 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5735 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5738 struct AsnDecodeSequenceItem items
[] = {
5739 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5740 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5741 /* Placeholder for the hash algorithms - redundant with those in the
5742 * signers, so just ignore them.
5744 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5745 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5746 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5747 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5748 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5749 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5750 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5751 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5752 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5753 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5754 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5755 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5756 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5757 CRYPT_DecodeSignerArray
,
5758 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5759 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5762 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5763 pDecodePara
, signedInfo
, pcbSignedInfo
);
5765 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5766 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5768 TRACE("returning %d\n", ret
);
5772 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5773 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5776 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5777 struct AsnDecodeSequenceItem items
[] = {
5778 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5779 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5780 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5781 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5782 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5783 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5784 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5785 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5786 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5787 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5788 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5789 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5790 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5791 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5792 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5795 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5796 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5798 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5799 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5800 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5803 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5804 TRACE("returning %d\n", ret
);
5808 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5809 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5813 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5814 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5815 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5816 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5817 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5818 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5819 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5821 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5822 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5824 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5825 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5826 TRACE("returning %d\n", ret
);
5830 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5831 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5835 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5836 struct AsnDecodeSequenceItem items
[] = {
5837 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5838 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5839 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5841 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5842 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5843 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5844 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5845 contentEncryptionAlgorithm
.pszObjId
), 0 },
5846 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5847 encryptedContent
), CRYPT_AsnDecodeOctetsInternal
,
5848 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5849 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5852 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5853 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5855 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5856 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5857 pcbDecoded
, info
? info
->contentType
: NULL
);
5858 TRACE("returning %d\n", ret
);
5862 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5863 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5864 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5867 struct AsnDecodeSequenceItem items
[] = {
5868 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5869 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5870 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5871 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5872 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5873 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5874 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5875 CRYPT_AsnDecodeEncryptedContentInfo
,
5876 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5877 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5880 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5881 pDecodePara
, envelopedData
, pcbEnvelopedData
);
5883 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5884 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5885 pcbEnvelopedData
, NULL
, NULL
);
5886 TRACE("returning %d\n", ret
);
5890 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5891 LPCSTR lpszStructType
)
5893 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5895 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5896 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5898 SetLastError(ERROR_FILE_NOT_FOUND
);
5901 if (IS_INTOID(lpszStructType
))
5903 switch (LOWORD(lpszStructType
))
5905 case LOWORD(X509_CERT
):
5906 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5908 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5909 decodeFunc
= CRYPT_AsnDecodeCert
;
5911 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5912 decodeFunc
= CRYPT_AsnDecodeCRL
;
5914 case LOWORD(X509_EXTENSIONS
):
5915 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5917 case LOWORD(X509_NAME_VALUE
):
5918 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5920 case LOWORD(X509_NAME
):
5921 decodeFunc
= CRYPT_AsnDecodeName
;
5923 case LOWORD(X509_PUBLIC_KEY_INFO
):
5924 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5926 case LOWORD(X509_AUTHORITY_KEY_ID
):
5927 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5929 case LOWORD(X509_ALTERNATE_NAME
):
5930 decodeFunc
= CRYPT_AsnDecodeAltName
;
5932 case LOWORD(X509_BASIC_CONSTRAINTS
):
5933 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5935 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5936 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5938 case LOWORD(X509_CERT_POLICIES
):
5939 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5941 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5942 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5944 case LOWORD(PKCS_RSA_PRIVATE_KEY
):
5945 decodeFunc
= CRYPT_AsnDecodeRsaPrivKey
;
5947 case LOWORD(X509_UNICODE_NAME
):
5948 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5950 case LOWORD(PKCS_ATTRIBUTE
):
5951 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5953 case LOWORD(X509_UNICODE_NAME_VALUE
):
5954 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5956 case LOWORD(X509_OCTET_STRING
):
5957 decodeFunc
= CRYPT_AsnDecodeOctets
;
5959 case LOWORD(X509_BITS
):
5960 case LOWORD(X509_KEY_USAGE
):
5961 decodeFunc
= CRYPT_AsnDecodeBits
;
5963 case LOWORD(X509_INTEGER
):
5964 decodeFunc
= CRYPT_AsnDecodeInt
;
5966 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5967 decodeFunc
= CRYPT_AsnDecodeInteger
;
5969 case LOWORD(X509_MULTI_BYTE_UINT
):
5970 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5972 case LOWORD(X509_ENUMERATED
):
5973 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5975 case LOWORD(X509_CHOICE_OF_TIME
):
5976 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5978 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5979 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5981 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5982 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5984 case LOWORD(PKCS_CONTENT_INFO
):
5985 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5987 case LOWORD(X509_SEQUENCE_OF_ANY
):
5988 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5990 case LOWORD(PKCS_UTC_TIME
):
5991 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5993 case LOWORD(X509_CRL_DIST_POINTS
):
5994 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5996 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5997 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5999 case LOWORD(PKCS_CTL
):
6000 decodeFunc
= CRYPT_AsnDecodeCTL
;
6002 case LOWORD(PKCS_SMIME_CAPABILITIES
):
6003 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6005 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
6006 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6008 case LOWORD(PKCS_ATTRIBUTES
):
6009 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
6011 case LOWORD(X509_ISSUING_DIST_POINT
):
6012 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6014 case LOWORD(X509_NAME_CONSTRAINTS
):
6015 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6017 case LOWORD(X509_POLICY_MAPPINGS
):
6018 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6020 case LOWORD(X509_POLICY_CONSTRAINTS
):
6021 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6023 case LOWORD(PKCS7_SIGNER_INFO
):
6024 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
6026 case LOWORD(CMS_SIGNER_INFO
):
6027 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
6031 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
6032 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6033 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
6034 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6035 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
6036 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6037 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
6038 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6039 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
6040 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6041 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
6042 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6043 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
6044 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6045 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
6046 decodeFunc
= CRYPT_AsnDecodeBits
;
6047 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
6048 decodeFunc
= CRYPT_AsnDecodeOctets
;
6049 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
6050 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6051 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
6052 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6053 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
6054 decodeFunc
= CRYPT_AsnDecodeAltName
;
6055 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
6056 decodeFunc
= CRYPT_AsnDecodeAltName
;
6057 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
6058 decodeFunc
= CRYPT_AsnDecodeAltName
;
6059 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
6060 decodeFunc
= CRYPT_AsnDecodeAltName
;
6061 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
6062 decodeFunc
= CRYPT_AsnDecodeAltName
;
6063 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
6064 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6065 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
6066 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6067 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
6068 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6069 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
6070 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6071 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
6072 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6073 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
6074 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6075 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
6076 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6077 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
6078 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6079 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
6080 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6081 else if (!strcmp(lpszStructType
, szOID_CTL
))
6082 decodeFunc
= CRYPT_AsnDecodeCTL
;
6086 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
6087 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6089 static HCRYPTOIDFUNCSET set
= NULL
;
6090 CryptDecodeObjectFunc decodeFunc
= NULL
;
6093 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
6094 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6095 (void **)&decodeFunc
, hFunc
);
6099 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
6100 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6102 static HCRYPTOIDFUNCSET set
= NULL
;
6103 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6106 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
6107 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6108 (void **)&decodeFunc
, hFunc
);
6112 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6113 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
6114 DWORD
*pcbStructInfo
)
6117 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
6118 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
6119 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6121 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
6122 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
6123 pvStructInfo
, pcbStructInfo
);
6125 if (!pvStructInfo
&& !pcbStructInfo
)
6127 SetLastError(ERROR_INVALID_PARAMETER
);
6130 if (cbEncoded
> MAX_ENCODED_LEN
)
6132 SetLastError(CRYPT_E_ASN1_LARGE
);
6136 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
6139 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6140 debugstr_a(lpszStructType
));
6141 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
6142 lpszStructType
, &hFunc
);
6143 if (!pCryptDecodeObject
)
6144 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
6145 lpszStructType
, &hFunc
);
6147 if (pCryptDecodeObject
)
6148 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6149 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6150 else if (pCryptDecodeObjectEx
)
6151 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6152 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6153 pvStructInfo
, pcbStructInfo
);
6155 CryptFreeOIDFunctionAddress(hFunc
, 0);
6156 TRACE_(crypt
)("returning %d\n", ret
);
6160 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6161 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6162 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6165 CryptDecodeObjectExFunc decodeFunc
;
6166 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6168 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6169 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6170 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6172 if (!pvStructInfo
&& !pcbStructInfo
)
6174 SetLastError(ERROR_INVALID_PARAMETER
);
6177 if (cbEncoded
> MAX_ENCODED_LEN
)
6179 SetLastError(CRYPT_E_ASN1_LARGE
);
6183 SetLastError(NOERROR
);
6184 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6188 SetLastError(ERROR_INVALID_PARAMETER
);
6191 *(BYTE
**)pvStructInfo
= NULL
;
6193 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6196 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6197 debugstr_a(lpszStructType
));
6198 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6202 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6203 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6206 CryptDecodeObjectFunc pCryptDecodeObject
=
6207 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6209 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6210 * directly, as that could cause an infinite loop.
6212 if (pCryptDecodeObject
)
6214 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6216 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6217 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6218 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6219 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6221 ret
= pCryptDecodeObject(dwCertEncodingType
,
6222 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6223 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6225 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6229 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6230 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6234 CryptFreeOIDFunctionAddress(hFunc
, 0);
6235 TRACE_(crypt
)("returning %d\n", ret
);
6239 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6243 TRACE_(crypt
)("(%p)\n", pPFX
);
6245 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6246 * version integer of length 1 (3 encoded byes) and at least one other
6247 * datum (two encoded bytes), plus at least two bytes for the outer
6248 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6250 if (pPFX
->cbData
< 7)
6252 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6256 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6258 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6260 /* Need at least three bytes for the integer version */
6261 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6263 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6264 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6265 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6274 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6277 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);
6281 BOOL WINAPI
PFXVerifyPassword(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6284 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);