2 * Copyright 2005-2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
67 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
68 DWORD
, DWORD
, void *, DWORD
*);
69 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
70 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
76 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
78 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
82 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
84 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
86 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
87 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
88 /* Assumes algo->Parameters.pbData is set ahead of time. */
89 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
90 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
91 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
92 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
93 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
94 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
95 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
97 /* Doesn't check the tag, assumes the caller does so */
98 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
99 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
100 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
101 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
102 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
103 * member has been initialized, doesn't do exception handling, and doesn't do
104 * memory allocation. Also doesn't check tag, assumes the caller has checked
107 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
108 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
110 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
111 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
112 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
114 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
115 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
118 /* Gets the number of length bytes from the given (leading) length byte */
119 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
121 /* Helper function to get the encoded length of the data starting at pbEncoded,
122 * where pbEncoded[0] is the tag. If the data are too short to contain a
123 * length or if the length is too large for cbEncoded, sets an appropriate
124 * error code and returns FALSE. If the encoded length is unknown due to
125 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
127 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
134 SetLastError(CRYPT_E_ASN1_CORRUPT
);
137 else if (pbEncoded
[1] <= 0x7f)
139 if (pbEncoded
[1] + 1 > cbEncoded
)
141 SetLastError(CRYPT_E_ASN1_EOD
);
150 else if (pbEncoded
[1] == 0x80)
152 *len
= CMSG_INDEFINITE_LENGTH
;
157 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
159 if (lenLen
> sizeof(DWORD
) + 1)
161 SetLastError(CRYPT_E_ASN1_LARGE
);
164 else if (lenLen
+ 2 > cbEncoded
)
166 SetLastError(CRYPT_E_ASN1_CORRUPT
);
179 if (out
+ lenLen
+ 1 > cbEncoded
)
181 SetLastError(CRYPT_E_ASN1_EOD
);
194 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
195 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
199 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
200 *len
== CMSG_INDEFINITE_LENGTH
)
202 SetLastError(CRYPT_E_ASN1_CORRUPT
);
208 /* Helper function to check *pcbStructInfo, set it to the required size, and
209 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
210 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
211 * pointer to the newly allocated memory.
213 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
214 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
219 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
221 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
222 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
224 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
225 if (!*(BYTE
**)pvStructInfo
)
228 *pcbStructInfo
= bytesNeeded
;
230 else if (*pcbStructInfo
< bytesNeeded
)
232 *pcbStructInfo
= bytesNeeded
;
233 SetLastError(ERROR_MORE_DATA
);
237 *pcbStructInfo
= bytesNeeded
;
241 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
243 if (pDecodePara
&& pDecodePara
->pfnFree
)
244 pDecodePara
->pfnFree(pv
);
249 /* Helper function to check *pcbStructInfo and set it to the required size.
250 * Assumes pvStructInfo is not NULL.
252 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
256 if (*pcbStructInfo
< bytesNeeded
)
258 *pcbStructInfo
= bytesNeeded
;
259 SetLastError(ERROR_MORE_DATA
);
264 *pcbStructInfo
= bytesNeeded
;
271 * The expected tag of the item. If tag is 0, decodeFunc is called
272 * regardless of the tag value seen.
274 * A sequence is decoded into a struct. The offset member is the
275 * offset of this item within that struct.
277 * The decoder function to use. If this is NULL, then the member isn't
278 * decoded, but minSize space is reserved for it.
280 * The minimum amount of space occupied after decoding. You must set this.
282 * If true, and the tag doesn't match the expected tag for this item,
283 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
284 * filled with 0 for this member.
285 * hasPointer, pointerOffset:
286 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
287 * the offset within the struct of the data pointer (or to the
288 * first data pointer, if more than one exist).
290 * Used by CRYPT_AsnDecodeSequence, not for your use.
292 struct AsnDecodeSequenceItem
296 InternalDecodeFunc decodeFunc
;
304 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
305 #define MEMBERSIZE(s, member, nextmember) \
306 (offsetof(s, nextmember) - offsetof(s, member))
308 /* Decodes the items in a sequence, where the items are described in items,
309 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
310 * pvStructInfo. nextData is a pointer to the memory location at which the
311 * first decoded item with a dynamic pointer should point.
312 * Upon decoding, *cbDecoded is the total number of bytes decoded.
313 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
315 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
316 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
317 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
320 DWORD i
, decoded
= 0;
321 const BYTE
*ptr
= pbEncoded
;
323 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
324 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
326 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
328 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
332 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
333 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
335 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
337 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
339 DWORD itemEncodedLen
;
341 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
342 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
344 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
345 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
347 TRACE("Setting next pointer to %p\n",
349 *(BYTE
**)((BYTE
*)pvStructInfo
+
350 items
[i
].pointerOffset
) = nextData
;
352 if (items
[i
].decodeFunc
)
357 TRACE("decoding item %d\n", i
);
359 TRACE("sizing item %d\n", i
);
360 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
361 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
362 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
363 : NULL
, &items
[i
].size
, &itemDecoded
);
366 /* Account for alignment padding */
367 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
368 TRACE("item %d size: %d\n", i
, items
[i
].size
);
369 if (nextData
&& items
[i
].hasPointer
&&
370 items
[i
].size
> items
[i
].minSize
)
371 nextData
+= items
[i
].size
- items
[i
].minSize
;
372 if (itemDecoded
> itemEncodedLen
)
374 WARN("decoded length %d exceeds encoded %d\n",
375 itemDecoded
, itemEncodedLen
);
376 SetLastError(CRYPT_E_ASN1_CORRUPT
);
382 decoded
+= itemDecoded
;
383 TRACE("item %d: decoded %d bytes\n", i
,
387 else if (items
[i
].optional
&&
388 GetLastError() == CRYPT_E_ASN1_BADTAG
)
390 TRACE("skipping optional item %d\n", i
);
391 items
[i
].size
= items
[i
].minSize
;
392 SetLastError(NOERROR
);
396 TRACE("item %d failed: %08x\n", i
,
399 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
401 ERR("can't use indefinite length encoding without a decoder\n");
402 SetLastError(CRYPT_E_ASN1_CORRUPT
);
407 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
408 ptr
+= itemEncodedLen
;
409 decoded
+= itemEncodedLen
;
410 items
[i
].size
= items
[i
].minSize
;
413 else if (items
[i
].optional
)
415 TRACE("skipping optional item %d\n", i
);
416 items
[i
].size
= items
[i
].minSize
;
420 TRACE("item %d: tag %02x doesn't match expected %02x\n",
421 i
, ptr
[0], items
[i
].tag
);
422 SetLastError(CRYPT_E_ASN1_BADTAG
);
427 else if (items
[i
].optional
)
429 TRACE("missing optional item %d, skipping\n", i
);
430 items
[i
].size
= items
[i
].minSize
;
434 TRACE("not enough bytes for item %d, failing\n", i
);
435 SetLastError(CRYPT_E_ASN1_CORRUPT
);
440 *cbDecoded
= decoded
;
441 TRACE("returning %d\n", ret
);
445 /* This decodes an arbitrary sequence into a contiguous block of memory
446 * (basically, a struct.) Each element being decoded is described by a struct
447 * AsnDecodeSequenceItem, see above.
448 * startingPointer is an optional pointer to the first place where dynamic
449 * data will be stored. If you know the starting offset, you may pass it
450 * here. Otherwise, pass NULL, and one will be inferred from the items.
452 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
453 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
454 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
455 DWORD
*pcbDecoded
, void *startingPointer
)
459 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
460 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
465 SetLastError(CRYPT_E_ASN1_EOD
);
468 if (pbEncoded
[0] == ASN_SEQUENCE
)
472 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
474 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
475 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
476 BOOL indefinite
= FALSE
;
478 cbEncoded
-= 1 + lenBytes
;
479 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
484 else if (cbEncoded
< dataLen
)
486 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
488 SetLastError(CRYPT_E_ASN1_CORRUPT
);
493 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
494 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
495 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
497 if (cbDecoded
> cbEncoded
- 2)
499 /* Not enough space for 0 TLV */
500 SetLastError(CRYPT_E_ASN1_CORRUPT
);
503 else if (*(ptr
+ cbDecoded
) != 0 ||
504 *(ptr
+ cbDecoded
+ 1) != 0)
506 TRACE("expected 0 TLV\n");
507 SetLastError(CRYPT_E_ASN1_CORRUPT
);
514 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
516 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
518 SetLastError(CRYPT_E_ASN1_CORRUPT
);
523 DWORD i
, bytesNeeded
= 0, structSize
= 0;
525 for (i
= 0; i
< cItem
; i
++)
527 bytesNeeded
+= items
[i
].size
;
528 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
531 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
533 *pcbStructInfo
= bytesNeeded
;
534 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
535 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
539 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
540 pvStructInfo
= *(BYTE
**)pvStructInfo
;
542 nextData
= startingPointer
;
544 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
545 memset(pvStructInfo
, 0, structSize
);
546 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
547 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
549 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
550 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
557 SetLastError(CRYPT_E_ASN1_BADTAG
);
560 TRACE("returning %d (%08x)\n", ret
, GetLastError());
565 * The expected tag of the entire encoded array (usually a variant
566 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
567 * regardless of the tag seen.
569 * used to decode each item in the array
571 * is the minimum size of each decoded item
573 * indicates whether each item has a dynamic pointer
575 * indicates the offset within itemSize at which the pointer exists
577 struct AsnArrayDescriptor
580 InternalDecodeFunc decodeFunc
;
586 struct AsnArrayItemSize
592 /* Decodes an array of like types into a struct GenericArray.
593 * The layout and decoding of the array are described by a struct
594 * AsnArrayDescriptor.
596 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
597 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
598 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
599 DWORD
*pcbDecoded
, void *startingPointer
)
603 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
604 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
609 SetLastError(CRYPT_E_ASN1_EOD
);
612 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
616 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
618 DWORD bytesNeeded
, cItems
= 0, decoded
;
619 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
620 /* There can be arbitrarily many items, but there is often only one.
622 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
624 decoded
= 1 + lenBytes
;
625 bytesNeeded
= sizeof(struct GenericArray
);
629 BOOL doneDecoding
= FALSE
;
631 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
633 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
640 SetLastError(CRYPT_E_ASN1_CORRUPT
);
647 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
651 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
653 /* Each item decoded may not tolerate extraneous bytes,
654 * so get the length of the next element if known.
656 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
657 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
659 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
660 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
662 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
666 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
667 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
672 if (itemSizes
!= &itemSize
)
673 itemSizes
= CryptMemRealloc(itemSizes
,
674 cItems
* sizeof(struct AsnArrayItemSize
));
679 cItems
* sizeof(struct AsnArrayItemSize
));
681 memcpy(itemSizes
, &itemSize
,
686 decoded
+= itemDecoded
;
687 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
688 itemSizes
[cItems
- 1].size
= size
;
701 *pcbDecoded
= decoded
;
703 *pcbStructInfo
= bytesNeeded
;
704 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
705 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
710 struct GenericArray
*array
;
712 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
713 pvStructInfo
= *(BYTE
**)pvStructInfo
;
714 array
= pvStructInfo
;
715 array
->cItems
= cItems
;
717 array
->rgItems
= startingPointer
;
719 array
->rgItems
= (BYTE
*)array
+
720 sizeof(struct GenericArray
);
721 nextData
= array
->rgItems
+
722 array
->cItems
* arrayDesc
->itemSize
;
723 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
724 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
729 if (arrayDesc
->hasPointer
)
730 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
731 + arrayDesc
->pointerOffset
) = nextData
;
732 ret
= arrayDesc
->decodeFunc(ptr
,
733 itemSizes
[i
].encodedLen
,
734 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
735 array
->rgItems
+ i
* arrayDesc
->itemSize
,
736 &itemSizes
[i
].size
, &itemDecoded
);
739 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
743 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
744 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
747 if (itemSizes
!= &itemSize
)
748 CryptMemFree(itemSizes
);
753 SetLastError(CRYPT_E_ASN1_BADTAG
);
759 /* Decodes an array of like types into a struct GenericArray.
760 * The layout and decoding of the array are described by a struct
761 * AsnArrayDescriptor. Doesn't allocate memory for the decoded items,
762 * leaves that up to the caller.
764 static BOOL
CRYPT_AsnDecodeArrayNoAlloc(const struct AsnArrayDescriptor
*arrayDesc
,
765 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*pcItems
, void *rgItems
,
766 DWORD
*pcbItems
, DWORD
*pcbDecoded
)
770 TRACE("%p, %p, %d, %p, %p, %d\n", arrayDesc
, pbEncoded
,
771 cbEncoded
, pcItems
, rgItems
, pcItems
? *pcbItems
: 0);
775 SetLastError(CRYPT_E_ASN1_EOD
);
778 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
782 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
784 DWORD bytesNeeded
= 0, cItems
= 0, decoded
;
785 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
786 /* There can be arbitrarily many items, but there is often only one.
788 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
790 decoded
= 1 + lenBytes
;
794 BOOL doneDecoding
= FALSE
;
796 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
798 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
805 SetLastError(CRYPT_E_ASN1_CORRUPT
);
812 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
816 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
818 /* Each item decoded may not tolerate extraneous bytes,
819 * so get the length of the next element if known.
821 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
822 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
824 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
825 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
827 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
831 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
832 0, NULL
, &size
, &itemDecoded
);
836 if (itemSizes
!= &itemSize
)
837 itemSizes
= CryptMemRealloc(itemSizes
,
838 cItems
* sizeof(struct AsnArrayItemSize
));
843 cItems
* sizeof(struct AsnArrayItemSize
));
845 memcpy(itemSizes
, &itemSize
,
850 decoded
+= itemDecoded
;
851 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
852 itemSizes
[cItems
- 1].size
= size
;
865 *pcbDecoded
= decoded
;
867 *pcbItems
= bytesNeeded
;
868 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, rgItems
,
869 pcbItems
, bytesNeeded
)))
876 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
877 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
878 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
883 if (arrayDesc
->hasPointer
)
884 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
885 + arrayDesc
->pointerOffset
) = nextData
;
886 ret
= arrayDesc
->decodeFunc(ptr
,
887 itemSizes
[i
].encodedLen
, 0,
888 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
889 &itemSizes
[i
].size
, &itemDecoded
);
892 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
898 if (itemSizes
!= &itemSize
)
899 CryptMemFree(itemSizes
);
904 SetLastError(CRYPT_E_ASN1_BADTAG
);
910 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
911 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
912 * to CRYPT_E_ASN1_CORRUPT.
913 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
916 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
917 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
922 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
924 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
925 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
927 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
928 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
931 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
933 *pcbStructInfo
= bytesNeeded
;
934 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
936 CRYPT_DER_BLOB
*blob
;
938 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
939 pvStructInfo
= *(BYTE
**)pvStructInfo
;
941 blob
->cbData
= 1 + lenBytes
+ dataLen
;
944 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
945 blob
->pbData
= (BYTE
*)pbEncoded
;
948 assert(blob
->pbData
);
949 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
954 SetLastError(CRYPT_E_ASN1_CORRUPT
);
962 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
963 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
964 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
969 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
970 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
972 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
975 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
976 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
978 if (ret
&& pvStructInfo
)
980 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
987 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
989 temp
= blob
->pbData
[i
];
990 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
991 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
995 TRACE("returning %d (%08x)\n", ret
, GetLastError());
999 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
1000 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1001 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1005 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1006 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1010 struct AsnDecodeSequenceItem items
[] = {
1011 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
1012 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
1013 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
1014 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
1015 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
1016 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
1017 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1018 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
1019 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1020 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
1023 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
1024 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
1025 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1026 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
1027 pcbStructInfo
, NULL
, NULL
);
1031 SetLastError(STATUS_ACCESS_VIOLATION
);
1036 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1040 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1041 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1046 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1048 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1050 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
1051 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1053 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1058 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1059 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1063 struct AsnDecodeSequenceItem items
[] = {
1064 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
1065 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1066 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
1067 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1070 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1071 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
1076 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
1077 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1081 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1082 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1083 offsetof(CERT_EXTENSION
, pszObjId
) };
1086 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1087 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1089 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
1090 NULL
, NULL
, &itemSize
, pcbDecoded
);
1095 /* The size expected by the caller includes the combination of
1096 * CERT_INFO's cExtension and rgExtension, in addition to the size of
1097 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1098 * the size of the decoded items, so add the size of cExtension and
1101 bytesNeeded
= FINALMEMBERSIZE(CERT_INFO
, cExtension
) + itemSize
;
1103 *pcbStructInfo
= bytesNeeded
;
1104 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, NULL
, pvStructInfo
,
1105 pcbStructInfo
, bytesNeeded
)))
1109 info
= (CERT_INFO
*)((BYTE
*)pvStructInfo
-
1110 offsetof(CERT_INFO
, cExtension
));
1111 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
,
1112 cbEncoded
, &info
->cExtension
, info
->rgExtension
, &itemSize
,
1119 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
1120 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1126 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1128 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1130 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1131 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1132 if (ret
&& pcbDecoded
)
1133 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1138 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
1139 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1140 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1143 struct AsnDecodeSequenceItem items
[] = {
1144 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
1145 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1146 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
1147 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
1148 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
1149 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
1150 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1151 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1152 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1153 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1155 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
1156 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1158 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1159 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1161 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1162 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1163 FALSE
, TRUE
, offsetof(CERT_INFO
,
1164 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1165 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
1166 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1167 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1168 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
1169 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1170 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1171 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1172 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1173 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1176 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1177 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1179 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1180 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1182 if (ret
&& pvStructInfo
)
1186 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1187 info
= *(CERT_INFO
**)pvStructInfo
;
1189 info
= pvStructInfo
;
1190 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1191 !info
->Subject
.cbData
)
1193 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1194 /* Don't need to deallocate, because it should have failed on the
1195 * first pass (and no memory was allocated.)
1201 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1205 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1206 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1207 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1211 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1212 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1218 /* Unless told not to, first try to decode it as a signed cert. */
1219 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1221 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1223 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1224 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1225 &signedCert
, &size
);
1229 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1230 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1231 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1232 pvStructInfo
, pcbStructInfo
);
1233 LocalFree(signedCert
);
1236 /* Failing that, try it as an unsigned cert */
1240 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1241 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1242 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1247 SetLastError(STATUS_ACCESS_VIOLATION
);
1251 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1255 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1256 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1260 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1261 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1262 offsetof(CERT_EXTENSION
, pszObjId
) };
1265 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1266 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1268 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
1269 NULL
, NULL
, &itemSize
, pcbDecoded
);
1274 /* The size expected by the caller includes the combination of
1275 * CRL_ENTRY's cExtension and rgExtension, in addition to the size of
1276 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1277 * the size of the decoded items, so add the size of cExtension and
1280 bytesNeeded
= FINALMEMBERSIZE(CRL_ENTRY
, cExtension
) + itemSize
;
1282 *pcbStructInfo
= bytesNeeded
;
1283 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, NULL
, pvStructInfo
,
1284 pcbStructInfo
, bytesNeeded
)))
1288 entry
= (CRL_ENTRY
*)((BYTE
*)pvStructInfo
-
1289 offsetof(CRL_ENTRY
, cExtension
));
1290 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
,
1291 cbEncoded
, &entry
->cExtension
, entry
->rgExtension
, &itemSize
,
1298 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1299 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1302 struct AsnDecodeSequenceItem items
[] = {
1303 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1304 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1305 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1306 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1307 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1308 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1309 CRYPT_AsnDecodeCRLEntryExtensions
,
1310 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1311 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1313 PCRL_ENTRY entry
= pvStructInfo
;
1315 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1318 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1319 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1320 entry
? entry
->SerialNumber
.pbData
: NULL
);
1321 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1323 WARN("empty CRL entry serial number\n");
1324 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1330 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1331 * whose rgCRLEntry member has been set prior to calling.
1333 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1334 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1337 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1338 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1339 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1342 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1343 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1345 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
1346 NULL
, NULL
, &itemSize
, pcbDecoded
);
1351 /* The size expected by the caller includes the combination of
1352 * CRL_INFO's cCRLEntry and rgCRLEntry, in addition to the size of
1353 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1354 * the size of the decoded items, so add the size of cCRLEntry and
1357 bytesNeeded
= offsetof(CRL_INFO
, cExtension
) -
1358 offsetof(CRL_INFO
, cCRLEntry
) + itemSize
;
1360 *pcbStructInfo
= bytesNeeded
;
1361 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, NULL
, pvStructInfo
,
1362 pcbStructInfo
, bytesNeeded
)))
1366 info
= (CRL_INFO
*)((BYTE
*)pvStructInfo
-
1367 offsetof(CRL_INFO
, cCRLEntry
));
1368 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
,
1369 cbEncoded
, &info
->cCRLEntry
, info
->rgCRLEntry
, &itemSize
,
1373 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1377 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1378 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1382 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1383 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1384 offsetof(CERT_EXTENSION
, pszObjId
) };
1387 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1388 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1390 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
1391 NULL
, NULL
, &itemSize
, pcbDecoded
);
1396 /* The size expected by the caller includes the combination of
1397 * CRL_INFO's cExtension and rgExtension, in addition to the size of
1398 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1399 * the size of the decoded items, so add the size of cExtension and
1402 bytesNeeded
= FINALMEMBERSIZE(CRL_INFO
, cExtension
) + itemSize
;
1404 *pcbStructInfo
= bytesNeeded
;
1405 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, NULL
, pvStructInfo
,
1406 pcbStructInfo
, bytesNeeded
)))
1410 info
= (CRL_INFO
*)((BYTE
*)pvStructInfo
-
1411 offsetof(CRL_INFO
, cExtension
));
1412 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
,
1413 cbEncoded
, &info
->cExtension
, info
->rgExtension
, &itemSize
,
1420 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1421 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1427 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1429 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1431 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1432 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1433 if (ret
&& pcbDecoded
)
1434 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1439 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1440 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1441 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1443 struct AsnDecodeSequenceItem items
[] = {
1444 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1445 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1446 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1447 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1448 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1449 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1450 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1452 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1453 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1454 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1455 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1456 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1457 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1458 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1459 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1460 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1461 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1465 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1466 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1468 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1469 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1472 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1476 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1477 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1478 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1482 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1483 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1489 /* Unless told not to, first try to decode it as a signed crl. */
1490 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1492 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1494 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1495 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1500 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1501 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1502 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1503 pvStructInfo
, pcbStructInfo
);
1504 LocalFree(signedCrl
);
1507 /* Failing that, try it as an unsigned crl */
1511 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1512 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1513 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1518 SetLastError(STATUS_ACCESS_VIOLATION
);
1522 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1526 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1527 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1532 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1533 pvStructInfo
, *pcbStructInfo
);
1535 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1537 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1538 DWORD bytesNeeded
= sizeof(LPSTR
);
1542 /* The largest possible string for the first two components
1543 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1548 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1549 pbEncoded
[1 + lenBytes
] / 40,
1550 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1552 bytesNeeded
+= strlen(firstTwo
) + 1;
1553 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1554 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1556 /* large enough for ".4000000" */
1560 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1567 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1570 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1577 snprintf(str
, sizeof(str
), ".%d", val
);
1578 bytesNeeded
+= strlen(str
);
1583 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1585 *pcbStructInfo
= bytesNeeded
;
1586 else if (*pcbStructInfo
< bytesNeeded
)
1588 *pcbStructInfo
= bytesNeeded
;
1589 SetLastError(ERROR_MORE_DATA
);
1597 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1600 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1601 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1603 pszObjId
+= strlen(pszObjId
);
1604 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1605 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1609 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1618 sprintf(pszObjId
, ".%d", val
);
1619 pszObjId
+= strlen(pszObjId
);
1623 *(LPSTR
*)pvStructInfo
= NULL
;
1624 *pcbStructInfo
= bytesNeeded
;
1630 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1631 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1635 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1636 pvStructInfo
, *pcbStructInfo
);
1638 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1639 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1640 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1643 SetLastError(CRYPT_E_ASN1_BADTAG
);
1649 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1650 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1652 struct AsnDecodeSequenceItem items
[] = {
1653 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1654 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1655 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1656 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1657 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1658 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1659 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1660 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1663 PCERT_EXTENSION ext
= pvStructInfo
;
1665 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1669 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1670 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1671 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1672 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1674 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1675 debugstr_a(ext
->pszObjId
));
1676 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1680 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1681 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1682 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1686 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1687 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1691 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1692 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1693 offsetof(CERT_EXTENSION
, pszObjId
) };
1696 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
1697 NULL
, NULL
, &itemSize
, NULL
);
1702 /* CRYPT_AsnDecodeArrayNoAlloc only returns the size of the decoded
1703 * items, so add the size of CERT_EXTENSIONS.
1705 bytesNeeded
= sizeof(CERT_EXTENSIONS
) + itemSize
;
1707 *pcbStructInfo
= bytesNeeded
;
1708 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1709 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1711 CERT_EXTENSIONS
*exts
;
1713 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1714 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1715 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1716 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1717 sizeof(CERT_EXTENSIONS
));
1718 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
,
1719 cbEncoded
, &exts
->cExtension
, exts
->rgExtension
, &itemSize
,
1726 SetLastError(STATUS_ACCESS_VIOLATION
);
1733 /* Warning: this assumes the address of value->Value.pbData is already set, in
1734 * order to avoid overwriting memory. (In some cases, it may change it, if it
1735 * doesn't copy anything to memory.) Be sure to set it correctly!
1737 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1738 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1743 CERT_NAME_VALUE
*value
= pvStructInfo
;
1745 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1747 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1748 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1750 switch (pbEncoded
[0])
1752 case ASN_OCTETSTRING
:
1753 valueType
= CERT_RDN_OCTET_STRING
;
1754 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1755 bytesNeeded
+= dataLen
;
1757 case ASN_NUMERICSTRING
:
1758 valueType
= CERT_RDN_NUMERIC_STRING
;
1759 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1760 bytesNeeded
+= dataLen
;
1762 case ASN_PRINTABLESTRING
:
1763 valueType
= CERT_RDN_PRINTABLE_STRING
;
1764 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1765 bytesNeeded
+= dataLen
;
1768 valueType
= CERT_RDN_IA5_STRING
;
1769 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1770 bytesNeeded
+= dataLen
;
1773 valueType
= CERT_RDN_T61_STRING
;
1774 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1775 bytesNeeded
+= dataLen
;
1777 case ASN_VIDEOTEXSTRING
:
1778 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1779 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1780 bytesNeeded
+= dataLen
;
1782 case ASN_GRAPHICSTRING
:
1783 valueType
= CERT_RDN_GRAPHIC_STRING
;
1784 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1785 bytesNeeded
+= dataLen
;
1787 case ASN_VISIBLESTRING
:
1788 valueType
= CERT_RDN_VISIBLE_STRING
;
1789 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1790 bytesNeeded
+= dataLen
;
1792 case ASN_GENERALSTRING
:
1793 valueType
= CERT_RDN_GENERAL_STRING
;
1794 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1795 bytesNeeded
+= dataLen
;
1797 case ASN_UNIVERSALSTRING
:
1798 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1799 SetLastError(CRYPT_E_ASN1_BADTAG
);
1802 valueType
= CERT_RDN_BMP_STRING
;
1803 bytesNeeded
+= dataLen
;
1805 case ASN_UTF8STRING
:
1806 valueType
= CERT_RDN_UTF8_STRING
;
1807 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1808 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1811 SetLastError(CRYPT_E_ASN1_BADTAG
);
1816 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1818 *pcbStructInfo
= bytesNeeded
;
1819 else if (*pcbStructInfo
< bytesNeeded
)
1821 *pcbStructInfo
= bytesNeeded
;
1822 SetLastError(ERROR_MORE_DATA
);
1827 *pcbStructInfo
= bytesNeeded
;
1828 value
->dwValueType
= valueType
;
1833 assert(value
->Value
.pbData
);
1834 switch (pbEncoded
[0])
1836 case ASN_OCTETSTRING
:
1837 case ASN_NUMERICSTRING
:
1838 case ASN_PRINTABLESTRING
:
1841 case ASN_VIDEOTEXSTRING
:
1842 case ASN_GRAPHICSTRING
:
1843 case ASN_VISIBLESTRING
:
1844 case ASN_GENERALSTRING
:
1845 value
->Value
.cbData
= dataLen
;
1848 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1849 memcpy(value
->Value
.pbData
,
1850 pbEncoded
+ 1 + lenBytes
, dataLen
);
1852 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1858 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1860 value
->Value
.cbData
= dataLen
;
1861 for (i
= 0; i
< dataLen
/ 2; i
++)
1862 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1863 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1866 case ASN_UTF8STRING
:
1868 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1870 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1871 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1872 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1879 value
->Value
.cbData
= 0;
1880 value
->Value
.pbData
= NULL
;
1887 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1888 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1889 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1895 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1896 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1897 if (ret
&& pvStructInfo
)
1899 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1900 pcbStructInfo
, *pcbStructInfo
);
1903 CERT_NAME_VALUE
*value
;
1905 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1906 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1907 value
= pvStructInfo
;
1908 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1909 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1910 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1911 pcbStructInfo
, NULL
);
1917 SetLastError(STATUS_ACCESS_VIOLATION
);
1924 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1925 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1930 CERT_NAME_VALUE
*value
= pvStructInfo
;
1932 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1934 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1935 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1937 switch (pbEncoded
[0])
1939 case ASN_NUMERICSTRING
:
1940 valueType
= CERT_RDN_NUMERIC_STRING
;
1942 bytesNeeded
+= (dataLen
+ 1) * 2;
1944 case ASN_PRINTABLESTRING
:
1945 valueType
= CERT_RDN_PRINTABLE_STRING
;
1947 bytesNeeded
+= (dataLen
+ 1) * 2;
1950 valueType
= CERT_RDN_IA5_STRING
;
1952 bytesNeeded
+= (dataLen
+ 1) * 2;
1955 valueType
= CERT_RDN_T61_STRING
;
1957 bytesNeeded
+= (dataLen
+ 1) * 2;
1959 case ASN_VIDEOTEXSTRING
:
1960 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1962 bytesNeeded
+= (dataLen
+ 1) * 2;
1964 case ASN_GRAPHICSTRING
:
1965 valueType
= CERT_RDN_GRAPHIC_STRING
;
1967 bytesNeeded
+= (dataLen
+ 1) * 2;
1969 case ASN_VISIBLESTRING
:
1970 valueType
= CERT_RDN_VISIBLE_STRING
;
1972 bytesNeeded
+= (dataLen
+ 1) * 2;
1974 case ASN_GENERALSTRING
:
1975 valueType
= CERT_RDN_GENERAL_STRING
;
1977 bytesNeeded
+= (dataLen
+ 1) * 2;
1979 case ASN_UNIVERSALSTRING
:
1980 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1982 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1985 valueType
= CERT_RDN_BMP_STRING
;
1987 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1989 case ASN_UTF8STRING
:
1990 valueType
= CERT_RDN_UTF8_STRING
;
1992 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1993 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1996 SetLastError(CRYPT_E_ASN1_BADTAG
);
2001 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2003 *pcbStructInfo
= bytesNeeded
;
2004 else if (*pcbStructInfo
< bytesNeeded
)
2006 *pcbStructInfo
= bytesNeeded
;
2007 SetLastError(ERROR_MORE_DATA
);
2012 *pcbStructInfo
= bytesNeeded
;
2013 value
->dwValueType
= valueType
;
2017 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
2019 assert(value
->Value
.pbData
);
2020 switch (pbEncoded
[0])
2022 case ASN_NUMERICSTRING
:
2023 case ASN_PRINTABLESTRING
:
2026 case ASN_VIDEOTEXSTRING
:
2027 case ASN_GRAPHICSTRING
:
2028 case ASN_VISIBLESTRING
:
2029 case ASN_GENERALSTRING
:
2030 value
->Value
.cbData
= dataLen
* 2;
2031 for (i
= 0; i
< dataLen
; i
++)
2032 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2035 case ASN_UNIVERSALSTRING
:
2036 value
->Value
.cbData
= dataLen
/ 2;
2037 for (i
= 0; i
< dataLen
/ 4; i
++)
2038 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2039 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2043 value
->Value
.cbData
= dataLen
;
2044 for (i
= 0; i
< dataLen
/ 2; i
++)
2045 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2046 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2049 case ASN_UTF8STRING
:
2050 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
2051 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2052 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
2053 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
2054 value
->Value
.cbData
+= sizeof(WCHAR
);
2060 value
->Value
.cbData
= 0;
2061 value
->Value
.pbData
= NULL
;
2068 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
2069 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2070 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2076 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
2077 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
2078 if (ret
&& pvStructInfo
)
2080 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2081 pcbStructInfo
, *pcbStructInfo
);
2084 CERT_NAME_VALUE
*value
;
2086 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2087 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2088 value
= pvStructInfo
;
2089 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
2090 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
2091 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2092 pcbStructInfo
, NULL
);
2098 SetLastError(STATUS_ACCESS_VIOLATION
);
2105 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2106 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2109 struct AsnDecodeSequenceItem items
[] = {
2110 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
2111 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2112 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
2113 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
2114 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
2115 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
2117 CERT_RDN_ATTR
*attr
= pvStructInfo
;
2119 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2120 pvStructInfo
, *pcbStructInfo
);
2123 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
2124 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2125 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
2126 attr
? attr
->pszObjId
: NULL
);
2129 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
2130 debugstr_a(attr
->pszObjId
));
2131 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
2133 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2137 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2138 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2141 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2142 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
2143 offsetof(CERT_RDN_ATTR
, pszObjId
) };
2144 PCERT_RDN rdn
= pvStructInfo
;
2146 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2147 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2148 rdn
? rdn
->rgRDNAttr
: NULL
);
2152 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
2153 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2154 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2160 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2161 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
2162 offsetof(CERT_RDN
, rgRDNAttr
) };
2164 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2165 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2169 SetLastError(STATUS_ACCESS_VIOLATION
);
2176 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
2177 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2181 struct AsnDecodeSequenceItem items
[] = {
2182 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
2183 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2184 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
2185 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
2186 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
2187 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
2189 CERT_RDN_ATTR
*attr
= pvStructInfo
;
2191 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2192 pvStructInfo
, *pcbStructInfo
);
2195 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
2196 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2197 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
2198 attr
? attr
->pszObjId
: NULL
);
2201 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
2202 debugstr_a(attr
->pszObjId
));
2203 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
2205 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2209 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2210 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2213 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2214 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
2215 offsetof(CERT_RDN_ATTR
, pszObjId
) };
2216 PCERT_RDN rdn
= pvStructInfo
;
2218 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2219 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2220 rdn
? rdn
->rgRDNAttr
: NULL
);
2224 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2225 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2226 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2232 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2233 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2234 offsetof(CERT_RDN
, rgRDNAttr
) };
2236 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2237 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2241 SetLastError(STATUS_ACCESS_VIOLATION
);
2248 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2251 BOOL ret
= TRUE
, done
= FALSE
;
2252 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2254 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2261 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2264 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2266 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2268 indefiniteNestingLevels
++;
2269 pbEncoded
+= 1 + lenBytes
;
2270 cbEncoded
-= 1 + lenBytes
;
2271 decoded
+= 1 + lenBytes
;
2272 TRACE("indefiniteNestingLevels = %d\n",
2273 indefiniteNestingLevels
);
2277 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2278 indefiniteNestingLevels
)
2280 indefiniteNestingLevels
--;
2281 TRACE("indefiniteNestingLevels = %d\n",
2282 indefiniteNestingLevels
);
2284 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2285 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2286 decoded
+= 1 + lenBytes
+ dataLen
;
2287 if (!indefiniteNestingLevels
)
2291 } while (ret
&& !done
);
2292 /* If we haven't found all 0 TLVs, we haven't found the end */
2293 if (ret
&& indefiniteNestingLevels
)
2295 SetLastError(CRYPT_E_ASN1_EOD
);
2299 *pcbDecoded
= decoded
;
2300 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2304 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2305 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2309 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2311 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2312 pvStructInfo
, *pcbStructInfo
);
2314 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2316 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2317 bytesNeeded
+= encodedLen
;
2319 *pcbStructInfo
= bytesNeeded
;
2320 else if (*pcbStructInfo
< bytesNeeded
)
2322 SetLastError(ERROR_MORE_DATA
);
2323 *pcbStructInfo
= bytesNeeded
;
2328 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2330 *pcbStructInfo
= bytesNeeded
;
2331 blob
->cbData
= encodedLen
;
2334 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2335 blob
->pbData
= (LPBYTE
)pbEncoded
;
2338 assert(blob
->pbData
);
2339 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2343 blob
->pbData
= NULL
;
2346 *pcbDecoded
= encodedLen
;
2351 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2352 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2355 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2356 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2357 CTL_USAGE
*usage
= pvStructInfo
;
2359 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2360 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2361 usage
? usage
->rgpszUsageIdentifier
: NULL
);
2365 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2366 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2368 struct AsnDecodeSequenceItem items
[] = {
2369 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2370 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2371 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2372 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2373 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
), FALSE
,
2374 TRUE
, offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2377 CTL_ENTRY
*entry
= pvStructInfo
;
2379 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2382 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2383 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2384 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2388 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2389 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2392 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2393 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2394 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2397 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2398 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2400 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2401 NULL
, NULL
, &bytesNeeded
, pcbDecoded
);
2404 /* The size expected by the caller includes the combination of
2405 * CTL_INFO's cCTLEntry and rgCTLEntry, in addition to the size of
2406 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
2407 * the size of the decoded items, so add the size of cCTLEntry and
2410 bytesNeeded
+= MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
);
2412 *pcbStructInfo
= bytesNeeded
;
2413 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, NULL
, pvStructInfo
,
2414 pcbStructInfo
, bytesNeeded
)))
2418 info
= (CTL_INFO
*)((BYTE
*)pvStructInfo
-
2419 offsetof(CTL_INFO
, cCTLEntry
));
2420 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
,
2421 cbEncoded
, &info
->cCTLEntry
, info
->rgCTLEntry
, &bytesNeeded
,
2428 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2429 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2433 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2434 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2435 offsetof(CERT_EXTENSION
, pszObjId
) };
2438 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2439 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2441 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2442 NULL
, NULL
, &itemSize
, pcbDecoded
);
2447 /* The size expected by the caller includes the combination of
2448 * CTL_INFO's cExtension and rgExtension, in addition to the size of
2449 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
2450 * the size of the decoded items, so add the size of cExtension and
2453 bytesNeeded
= FINALMEMBERSIZE(CTL_INFO
, cExtension
) + itemSize
;
2455 *pcbStructInfo
= bytesNeeded
;
2456 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, NULL
, pvStructInfo
,
2457 pcbStructInfo
, bytesNeeded
)))
2461 info
= (CTL_INFO
*)((BYTE
*)pvStructInfo
-
2462 offsetof(CTL_INFO
, cExtension
));
2463 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
,
2464 cbEncoded
, &info
->cExtension
, info
->rgExtension
, &itemSize
,
2471 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2472 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2478 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2480 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2482 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2483 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2484 if (ret
&& pcbDecoded
)
2485 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2490 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2491 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2492 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2496 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2497 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2501 struct AsnDecodeSequenceItem items
[] = {
2502 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2503 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2504 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2505 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2506 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2507 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2508 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2509 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2510 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2511 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2512 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2513 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2514 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2516 { 0, offsetof(CTL_INFO
, NextUpdate
),
2517 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2519 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2520 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2521 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2522 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2523 CRYPT_AsnDecodeCTLEntries
,
2524 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2525 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2526 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2527 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2528 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2531 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2532 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2534 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2535 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2536 pcbStructInfo
, NULL
, NULL
);
2540 SetLastError(STATUS_ACCESS_VIOLATION
);
2546 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2547 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2551 struct AsnDecodeSequenceItem items
[] = {
2552 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2553 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2554 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2555 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2556 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2557 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2559 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2561 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2562 pvStructInfo
, *pcbStructInfo
);
2564 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2565 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2566 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2567 TRACE("returning %d\n", ret
);
2571 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2572 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2573 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2577 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2578 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2583 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2584 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2585 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2587 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2588 NULL
, NULL
, &bytesNeeded
, NULL
)))
2590 bytesNeeded
+= sizeof(CRYPT_SMIME_CAPABILITIES
);
2592 *pcbStructInfo
= bytesNeeded
;
2593 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2594 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2596 PCRYPT_SMIME_CAPABILITIES capabilities
;
2598 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2599 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2600 capabilities
= pvStructInfo
;
2601 capabilities
->rgCapability
=
2602 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2603 sizeof(CRYPT_SMIME_CAPABILITIES
));
2604 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
,
2605 pbEncoded
, cbEncoded
, &capabilities
->cCapability
,
2606 capabilities
->rgCapability
, pcbStructInfo
, NULL
);
2612 SetLastError(STATUS_ACCESS_VIOLATION
);
2615 TRACE("returning %d\n", ret
);
2619 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2620 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2625 LPSTR
*pStr
= pvStructInfo
;
2627 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2629 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2630 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2632 if (pbEncoded
[0] != ASN_IA5STRING
)
2634 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2639 bytesNeeded
+= dataLen
;
2641 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2643 *pcbStructInfo
= bytesNeeded
;
2644 else if (*pcbStructInfo
< bytesNeeded
)
2646 *pcbStructInfo
= bytesNeeded
;
2647 SetLastError(ERROR_MORE_DATA
);
2652 *pcbStructInfo
= bytesNeeded
;
2658 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2669 static BOOL
CRYPT_AsnDecodeIntArray(const BYTE
*pbEncoded
,
2670 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2673 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2674 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2675 struct GenericArray
*array
= pvStructInfo
;
2678 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2679 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2681 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2682 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2683 array
? array
->rgItems
: NULL
);
2684 TRACE("returning %d\n", ret
);
2688 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2689 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2693 struct AsnDecodeSequenceItem items
[] = {
2694 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2695 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2696 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2697 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2698 cNoticeNumbers
), CRYPT_AsnDecodeIntArray
, sizeof(struct GenericArray
),
2699 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2700 rgNoticeNumbers
), 0 },
2704 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2705 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2707 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2708 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2712 /* The caller is expecting a pointer to a
2713 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2714 * CRYPT_AsnDecodeSequence is decoding a
2715 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2716 * needed, and decode again if the requisite space is available.
2718 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2720 *pcbStructInfo
= bytesNeeded
;
2721 else if (*pcbStructInfo
< bytesNeeded
)
2723 *pcbStructInfo
= bytesNeeded
;
2724 SetLastError(ERROR_MORE_DATA
);
2729 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2731 *pcbStructInfo
= bytesNeeded
;
2732 /* The pointer (pvStructInfo) passed in points to the first dynamic
2733 * pointer, so use it as the pointer to the
2734 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2735 * appropriate offset for the first dynamic pointer within the
2736 * notice reference by pointing to the first memory location past
2737 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2740 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2741 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2742 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2743 ret
= CRYPT_AsnDecodeSequence(items
,
2744 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2745 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2746 noticeRef
->pszOrganization
);
2749 TRACE("returning %d\n", ret
);
2753 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2754 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2760 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2762 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2763 DWORD bytesNeeded
= sizeof(LPWSTR
);
2765 switch (pbEncoded
[0])
2767 case ASN_NUMERICSTRING
:
2769 bytesNeeded
+= (dataLen
+ 1) * 2;
2771 case ASN_PRINTABLESTRING
:
2773 bytesNeeded
+= (dataLen
+ 1) * 2;
2777 bytesNeeded
+= (dataLen
+ 1) * 2;
2781 bytesNeeded
+= (dataLen
+ 1) * 2;
2783 case ASN_VIDEOTEXSTRING
:
2785 bytesNeeded
+= (dataLen
+ 1) * 2;
2787 case ASN_GRAPHICSTRING
:
2789 bytesNeeded
+= (dataLen
+ 1) * 2;
2791 case ASN_VISIBLESTRING
:
2793 bytesNeeded
+= (dataLen
+ 1) * 2;
2795 case ASN_GENERALSTRING
:
2797 bytesNeeded
+= (dataLen
+ 1) * 2;
2799 case ASN_UNIVERSALSTRING
:
2801 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2805 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2807 case ASN_UTF8STRING
:
2809 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2810 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2813 SetLastError(CRYPT_E_ASN1_BADTAG
);
2818 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2820 *pcbStructInfo
= bytesNeeded
;
2821 else if (*pcbStructInfo
< bytesNeeded
)
2823 *pcbStructInfo
= bytesNeeded
;
2824 SetLastError(ERROR_MORE_DATA
);
2829 LPWSTR
*pStr
= pvStructInfo
;
2831 *pcbStructInfo
= bytesNeeded
;
2835 LPWSTR str
= *(LPWSTR
*)pStr
;
2838 switch (pbEncoded
[0])
2840 case ASN_NUMERICSTRING
:
2841 case ASN_PRINTABLESTRING
:
2844 case ASN_VIDEOTEXSTRING
:
2845 case ASN_GRAPHICSTRING
:
2846 case ASN_VISIBLESTRING
:
2847 case ASN_GENERALSTRING
:
2848 for (i
= 0; i
< dataLen
; i
++)
2849 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2852 case ASN_UNIVERSALSTRING
:
2853 for (i
= 0; i
< dataLen
/ 4; i
++)
2854 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2855 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2859 for (i
= 0; i
< dataLen
/ 2; i
++)
2860 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2861 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2864 case ASN_UTF8STRING
:
2866 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2867 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2868 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2881 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2882 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2883 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2886 struct AsnDecodeSequenceItem items
[] = {
2887 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2888 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2889 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2890 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2891 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2892 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2893 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2895 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2897 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2898 pvStructInfo
, *pcbStructInfo
);
2900 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2901 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2902 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2903 TRACE("returning %d\n", ret
);
2907 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2908 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2909 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2910 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2914 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2915 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2921 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2922 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2927 *pcbStructInfo
= bytesNeeded
;
2928 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2929 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2931 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2933 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2934 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2935 notice
= pvStructInfo
;
2936 notice
->pNoticeReference
=
2937 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2938 ((BYTE
*)pvStructInfo
+
2939 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2940 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2941 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2942 pvStructInfo
, &bytesNeeded
, NULL
);
2948 SetLastError(STATUS_ACCESS_VIOLATION
);
2951 TRACE("returning %d\n", ret
);
2955 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2956 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2960 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
2961 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2964 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2965 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2967 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2968 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
2970 bytesNeeded
+= FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
);
2972 *pcbStructInfo
= bytesNeeded
;
2973 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
2974 pcbStructInfo
, bytesNeeded
)))
2976 CRYPT_ATTRIBUTE
*attr
= (CRYPT_ATTRIBUTE
*)((BYTE
*)pvStructInfo
-
2977 offsetof(CRYPT_ATTRIBUTE
, cValue
));
2979 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2980 &attr
->cValue
, attr
->rgValue
, pcbStructInfo
, pcbDecoded
);
2986 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2987 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2991 struct AsnDecodeSequenceItem items
[] = {
2992 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2993 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2994 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2995 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2996 CRYPT_AsnDecodePKCSAttributeValue
,
2997 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2998 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
3000 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
3002 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3003 pvStructInfo
, *pcbStructInfo
);
3005 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3006 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3007 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
3008 TRACE("returning %d\n", ret
);
3012 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
3013 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3014 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3018 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3019 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3025 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
3026 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3030 *pcbStructInfo
= bytesNeeded
;
3031 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3032 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3034 PCRYPT_ATTRIBUTE attr
;
3036 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3037 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3038 attr
= pvStructInfo
;
3039 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
3040 sizeof(CRYPT_ATTRIBUTE
));
3041 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
3042 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
3049 SetLastError(STATUS_ACCESS_VIOLATION
);
3052 TRACE("returning %d\n", ret
);
3056 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
3057 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3060 struct AsnArrayDescriptor arrayDesc
= { 0,
3061 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
3062 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
3063 PCRYPT_ATTRIBUTES attrs
= pvStructInfo
;
3066 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3067 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
3072 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
3073 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3074 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3078 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3079 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3085 if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
3086 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3087 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
3088 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
3092 *pcbStructInfo
= bytesNeeded
;
3093 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3094 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3096 PCRYPT_ATTRIBUTES attrs
;
3098 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3099 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3100 attrs
= pvStructInfo
;
3101 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
3102 sizeof(CRYPT_ATTRIBUTES
));
3103 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
3104 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3105 &bytesNeeded
, NULL
);
3111 SetLastError(STATUS_ACCESS_VIOLATION
);
3114 TRACE("returning %d\n", ret
);
3118 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3119 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3121 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
3123 struct AsnDecodeSequenceItem items
[] = {
3124 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
3125 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3126 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
3127 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
3128 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3129 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
3132 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3133 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3135 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3136 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3137 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
3138 if (ret
&& pvStructInfo
)
3140 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
3141 debugstr_a(algo
->pszObjId
));
3146 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
3147 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3151 struct AsnDecodeSequenceItem items
[] = {
3152 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
3153 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3154 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
3155 Algorithm
.pszObjId
) },
3156 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
3157 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3158 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
3160 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
3162 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3163 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3164 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
3168 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
3169 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3170 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3178 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
3179 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3182 *pcbStructInfo
= bytesNeeded
;
3183 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3184 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3186 PCERT_PUBLIC_KEY_INFO info
;
3188 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3189 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3190 info
= pvStructInfo
;
3191 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
3192 sizeof(CERT_PUBLIC_KEY_INFO
);
3193 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
3194 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3195 &bytesNeeded
, NULL
);
3201 SetLastError(STATUS_ACCESS_VIOLATION
);
3208 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3209 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3215 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3218 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
3220 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3223 if (pbEncoded
[1] > 1)
3225 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3232 *pcbStructInfo
= sizeof(BOOL
);
3235 else if (*pcbStructInfo
< sizeof(BOOL
))
3237 *pcbStructInfo
= sizeof(BOOL
);
3238 SetLastError(ERROR_MORE_DATA
);
3243 *pcbStructInfo
= sizeof(BOOL
);
3244 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
3247 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3251 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3252 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3254 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
3255 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
3258 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3259 pvStructInfo
, *pcbStructInfo
);
3263 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3266 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3267 if (1 + lenBytes
> cbEncoded
)
3269 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3272 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3274 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3276 case 1: /* rfc822Name */
3277 case 2: /* dNSName */
3278 case 6: /* uniformResourceIdentifier */
3279 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3281 case 4: /* directoryName */
3282 case 7: /* iPAddress */
3283 bytesNeeded
+= dataLen
;
3285 case 8: /* registeredID */
3286 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3290 /* FIXME: ugly, shouldn't need to know internals of OID decode
3291 * function to use it.
3293 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3296 case 0: /* otherName */
3297 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3298 SetLastError(CRYPT_E_ASN1_BADTAG
);
3301 case 3: /* x400Address, unimplemented */
3302 case 5: /* ediPartyName, unimplemented */
3303 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3304 SetLastError(CRYPT_E_ASN1_BADTAG
);
3308 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3309 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3315 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3317 *pcbStructInfo
= bytesNeeded
;
3318 else if (*pcbStructInfo
< bytesNeeded
)
3320 *pcbStructInfo
= bytesNeeded
;
3321 SetLastError(ERROR_MORE_DATA
);
3326 *pcbStructInfo
= bytesNeeded
;
3327 /* MS used values one greater than the asn1 ones.. sigh */
3328 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3329 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3331 case 1: /* rfc822Name */
3332 case 2: /* dNSName */
3333 case 6: /* uniformResourceIdentifier */
3337 for (i
= 0; i
< dataLen
; i
++)
3338 entry
->u
.pwszURL
[i
] =
3339 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3340 entry
->u
.pwszURL
[i
] = 0;
3341 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3342 debugstr_w(entry
->u
.pwszURL
));
3345 case 4: /* directoryName */
3346 /* The data are memory-equivalent with the IPAddress case,
3349 case 7: /* iPAddress */
3350 /* The next data pointer is in the pwszURL spot, that is,
3351 * the first 4 bytes. Need to move it to the next spot.
3353 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3354 entry
->u
.IPAddress
.cbData
= dataLen
;
3355 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3358 case 8: /* registeredID */
3359 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3360 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3369 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3370 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3374 struct AsnArrayDescriptor arrayDesc
= { 0,
3375 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3376 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3377 PCERT_ALT_NAME_INFO info
= pvStructInfo
;
3379 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3380 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3383 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
3384 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3385 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3386 info
? info
->rgAltEntry
: NULL
);
3390 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3391 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
3392 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3397 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3398 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3400 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3403 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3404 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
3406 if (ret
&& pvStructInfo
)
3408 CRYPT_DATA_BLOB
*blob
= pvStructInfo
;
3415 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
3417 temp
= blob
->pbData
[i
];
3418 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
3419 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
3423 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3427 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3428 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3429 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3435 struct AsnDecodeSequenceItem items
[] = {
3436 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3437 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3438 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3439 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3440 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3441 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3442 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3443 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3444 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3445 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3446 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3449 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3450 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3451 pcbStructInfo
, NULL
, NULL
);
3455 SetLastError(STATUS_ACCESS_VIOLATION
);
3462 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3463 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3464 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3470 struct AsnDecodeSequenceItem items
[] = {
3471 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3472 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3473 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3474 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3475 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3476 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3477 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3478 AuthorityCertIssuer
.rgAltEntry
), 0 },
3479 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3480 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3481 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3482 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3483 AuthorityCertSerialNumber
.pbData
), 0 },
3486 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3487 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3488 pcbStructInfo
, NULL
, NULL
);
3492 SetLastError(STATUS_ACCESS_VIOLATION
);
3499 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3500 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3503 struct AsnDecodeSequenceItem items
[] = {
3504 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3505 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3506 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3507 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3508 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3509 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3511 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3513 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3514 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3515 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3518 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3519 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3520 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3524 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3525 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3529 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3530 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3531 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3533 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3534 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3538 SetLastError(STATUS_ACCESS_VIOLATION
);
3545 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3546 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3551 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3552 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3554 /* The caller has already checked the tag, no need to check it again.
3555 * Check the outer length is valid:
3557 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3559 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3562 pbEncoded
+= 1 + lenBytes
;
3563 cbEncoded
-= 1 + lenBytes
;
3564 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3565 cbEncoded
-= 2; /* space for 0 TLV */
3566 /* Check the inner length is valid: */
3567 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3571 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3572 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3573 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3575 if (*(pbEncoded
+ decodedLen
) != 0 ||
3576 *(pbEncoded
+ decodedLen
+ 1) != 0)
3578 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3579 *(pbEncoded
+ decodedLen
),
3580 *(pbEncoded
+ decodedLen
+ 1));
3581 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3587 if (ret
&& pcbDecoded
)
3589 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3590 TRACE("decoded %d bytes\n", *pcbDecoded
);
3597 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3598 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3601 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3602 struct AsnDecodeSequenceItem items
[] = {
3603 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3604 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3605 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3606 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3607 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3608 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3609 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3613 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3614 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3616 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3617 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3618 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3622 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3623 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3624 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3628 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3629 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3633 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3634 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3635 if (ret
&& pvStructInfo
)
3637 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3638 pcbStructInfo
, *pcbStructInfo
);
3641 CRYPT_CONTENT_INFO
*info
;
3643 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3644 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3645 info
= pvStructInfo
;
3646 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3647 sizeof(CRYPT_CONTENT_INFO
));
3648 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3649 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3650 pcbStructInfo
, NULL
);
3656 SetLastError(STATUS_ACCESS_VIOLATION
);
3662 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3663 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3664 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3667 struct AsnDecodeSequenceItem items
[] = {
3668 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3669 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3670 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3671 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3672 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3674 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3675 CRYPT_AsnDecodePKCSContentInfoInternal
,
3676 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3677 ContentInfo
.pszObjId
), 0 },
3678 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3679 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3680 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3683 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3684 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3689 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3690 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3691 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3695 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3696 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3702 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3703 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3706 *pcbStructInfo
= bytesNeeded
;
3707 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3708 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3710 CERT_ALT_NAME_INFO
*name
;
3712 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3713 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3714 name
= pvStructInfo
;
3715 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3716 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3717 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3718 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3719 &bytesNeeded
, NULL
);
3725 SetLastError(STATUS_ACCESS_VIOLATION
);
3732 struct PATH_LEN_CONSTRAINT
3734 BOOL fPathLenConstraint
;
3735 DWORD dwPathLenConstraint
;
3738 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3739 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3743 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3745 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3746 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3750 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3752 *pcbStructInfo
= bytesNeeded
;
3754 else if (*pcbStructInfo
< bytesNeeded
)
3756 SetLastError(ERROR_MORE_DATA
);
3757 *pcbStructInfo
= bytesNeeded
;
3762 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3764 *pcbStructInfo
= bytesNeeded
;
3765 size
= sizeof(constraint
->dwPathLenConstraint
);
3766 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3767 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3769 constraint
->fPathLenConstraint
= TRUE
;
3770 TRACE("got an int, dwPathLenConstraint is %d\n",
3771 constraint
->dwPathLenConstraint
);
3773 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3777 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3778 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3782 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3783 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3784 offsetof(CERT_NAME_BLOB
, pbData
) };
3785 struct GenericArray
*entries
= pvStructInfo
;
3787 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3788 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3790 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3791 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3792 entries
? entries
->rgItems
: NULL
);
3793 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3797 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3798 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3799 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3805 struct AsnDecodeSequenceItem items
[] = {
3806 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3807 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3808 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3809 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3810 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3811 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3812 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3813 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3814 sizeof(struct GenericArray
), TRUE
, TRUE
,
3815 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3818 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3819 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3820 pcbStructInfo
, NULL
, NULL
);
3824 SetLastError(STATUS_ACCESS_VIOLATION
);
3831 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3832 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3833 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3839 struct AsnDecodeSequenceItem items
[] = {
3840 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3841 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3842 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3843 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3844 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3847 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3848 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3849 pcbStructInfo
, NULL
, NULL
);
3853 SetLastError(STATUS_ACCESS_VIOLATION
);
3860 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3861 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3864 struct AsnDecodeSequenceItem items
[] = {
3865 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3866 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3867 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3869 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3870 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3871 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3874 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3876 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3877 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3879 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3880 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3881 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3885 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3886 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3890 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3891 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3892 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3893 struct GenericArray
*entries
= pvStructInfo
;
3895 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3896 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3898 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3899 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3900 entries
? entries
->rgItems
: NULL
);
3901 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3905 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3906 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3908 struct AsnDecodeSequenceItem items
[] = {
3909 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3910 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3911 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3912 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3913 CRYPT_AsnDecodePolicyQualifiers
, sizeof(struct GenericArray
), TRUE
,
3914 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3916 CERT_POLICY_INFO
*info
= pvStructInfo
;
3919 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3920 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3922 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3923 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3924 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3928 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3929 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3930 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3934 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3935 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3939 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3940 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3941 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3943 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3944 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3948 SetLastError(STATUS_ACCESS_VIOLATION
);
3954 #define RSA1_MAGIC 0x31415352
3956 struct DECODED_RSA_PUB_KEY
3959 CRYPT_INTEGER_BLOB modulus
;
3962 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3963 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3964 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3970 struct AsnDecodeSequenceItem items
[] = {
3971 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3972 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3973 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3975 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3976 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3978 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3981 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3982 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3986 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3987 decodedKey
->modulus
.cbData
;
3991 *pcbStructInfo
= bytesNeeded
;
3994 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3995 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3998 RSAPUBKEY
*rsaPubKey
;
4000 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4001 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4003 hdr
->bType
= PUBLICKEYBLOB
;
4004 hdr
->bVersion
= CUR_BLOB_VERSION
;
4006 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4007 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4008 sizeof(BLOBHEADER
));
4009 rsaPubKey
->magic
= RSA1_MAGIC
;
4010 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4011 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
4012 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
4013 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
4014 decodedKey
->modulus
.cbData
);
4016 LocalFree(decodedKey
);
4021 SetLastError(STATUS_ACCESS_VIOLATION
);
4028 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
4029 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4033 DWORD bytesNeeded
, dataLen
;
4035 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4036 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4038 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4040 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4042 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4043 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4045 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4047 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4049 *pcbStructInfo
= bytesNeeded
;
4050 else if (*pcbStructInfo
< bytesNeeded
)
4052 SetLastError(ERROR_MORE_DATA
);
4053 *pcbStructInfo
= bytesNeeded
;
4058 CRYPT_DATA_BLOB
*blob
;
4060 *pcbStructInfo
= bytesNeeded
;
4061 blob
= pvStructInfo
;
4062 blob
->cbData
= dataLen
;
4063 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4064 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4067 assert(blob
->pbData
);
4069 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4077 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
4078 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4079 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4083 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4084 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4092 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4095 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
4097 SetLastError(CRYPT_E_ASN1_BADTAG
);
4100 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4101 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4104 *pcbStructInfo
= bytesNeeded
;
4105 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4106 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4108 CRYPT_DATA_BLOB
*blob
;
4110 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4111 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4112 blob
= pvStructInfo
;
4113 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4114 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4115 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4116 &bytesNeeded
, NULL
);
4122 SetLastError(STATUS_ACCESS_VIOLATION
);
4129 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4130 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4133 DWORD bytesNeeded
, dataLen
;
4134 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4136 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4137 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4139 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4141 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4142 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4144 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4146 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4148 *pcbStructInfo
= bytesNeeded
;
4149 else if (*pcbStructInfo
< bytesNeeded
)
4151 *pcbStructInfo
= bytesNeeded
;
4152 SetLastError(ERROR_MORE_DATA
);
4157 CRYPT_BIT_BLOB
*blob
;
4159 *pcbStructInfo
= bytesNeeded
;
4160 blob
= pvStructInfo
;
4161 blob
->cbData
= dataLen
- 1;
4162 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4163 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4165 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4169 assert(blob
->pbData
);
4172 BYTE mask
= 0xff << blob
->cUnusedBits
;
4174 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4176 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4184 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4185 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4186 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4190 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4191 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4199 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4202 else if (pbEncoded
[0] != ASN_BITSTRING
)
4204 SetLastError(CRYPT_E_ASN1_BADTAG
);
4207 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4208 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4211 *pcbStructInfo
= bytesNeeded
;
4212 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4213 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4215 CRYPT_BIT_BLOB
*blob
;
4217 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4218 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4219 blob
= pvStructInfo
;
4220 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4221 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4222 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4223 &bytesNeeded
, NULL
);
4229 SetLastError(STATUS_ACCESS_VIOLATION
);
4233 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4237 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4238 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4239 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4242 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
4243 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
4244 DWORD size
= sizeof(buf
);
4246 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
4247 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
4252 *pcbStructInfo
= sizeof(int);
4253 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4257 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
4259 /* initialize to a negative value to sign-extend */
4264 for (i
= 0; i
< blob
->cbData
; i
++)
4267 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
4269 memcpy(pvStructInfo
, &val
, sizeof(int));
4272 else if (GetLastError() == ERROR_MORE_DATA
)
4273 SetLastError(CRYPT_E_ASN1_LARGE
);
4277 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4278 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4279 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4289 SetLastError(CRYPT_E_ASN1_EOD
);
4292 else if (pbEncoded
[0] != ASN_INTEGER
)
4294 SetLastError(CRYPT_E_ASN1_BADTAG
);
4298 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4299 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4303 *pcbStructInfo
= bytesNeeded
;
4304 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4305 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4307 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4308 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4309 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4310 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4311 &bytesNeeded
, NULL
);
4317 SetLastError(STATUS_ACCESS_VIOLATION
);
4324 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4325 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4329 DWORD bytesNeeded
, dataLen
;
4331 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4333 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4335 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4337 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4339 *pcbStructInfo
= bytesNeeded
;
4340 else if (*pcbStructInfo
< bytesNeeded
)
4342 *pcbStructInfo
= bytesNeeded
;
4343 SetLastError(ERROR_MORE_DATA
);
4348 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4350 *pcbStructInfo
= bytesNeeded
;
4351 blob
->cbData
= dataLen
;
4352 assert(blob
->pbData
);
4357 for (i
= 0; i
< blob
->cbData
; i
++)
4359 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4368 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4369 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4370 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4378 if (pbEncoded
[0] != ASN_INTEGER
)
4380 SetLastError(CRYPT_E_ASN1_BADTAG
);
4384 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4385 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4389 *pcbStructInfo
= bytesNeeded
;
4390 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4391 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4393 CRYPT_INTEGER_BLOB
*blob
;
4395 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4396 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4397 blob
= pvStructInfo
;
4398 blob
->pbData
= (BYTE
*)pvStructInfo
+
4399 sizeof(CRYPT_INTEGER_BLOB
);
4400 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4401 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4402 &bytesNeeded
, NULL
);
4408 SetLastError(STATUS_ACCESS_VIOLATION
);
4415 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4416 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4421 if (pbEncoded
[0] == ASN_INTEGER
)
4423 DWORD bytesNeeded
, dataLen
;
4425 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4427 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4430 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4431 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4433 *pcbStructInfo
= bytesNeeded
;
4434 else if (*pcbStructInfo
< bytesNeeded
)
4436 *pcbStructInfo
= bytesNeeded
;
4437 SetLastError(ERROR_MORE_DATA
);
4442 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4444 *pcbStructInfo
= bytesNeeded
;
4445 blob
->cbData
= dataLen
;
4446 assert(blob
->pbData
);
4447 /* remove leading zero byte if it exists */
4448 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4457 for (i
= 0; i
< blob
->cbData
; i
++)
4459 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4468 SetLastError(CRYPT_E_ASN1_BADTAG
);
4474 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4475 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4476 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4484 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4485 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4488 *pcbStructInfo
= bytesNeeded
;
4489 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4490 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4492 CRYPT_INTEGER_BLOB
*blob
;
4494 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4495 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4496 blob
= pvStructInfo
;
4497 blob
->pbData
= (BYTE
*)pvStructInfo
+
4498 sizeof(CRYPT_INTEGER_BLOB
);
4499 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4500 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4501 &bytesNeeded
, NULL
);
4507 SetLastError(STATUS_ACCESS_VIOLATION
);
4514 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4515 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4516 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4522 *pcbStructInfo
= sizeof(int);
4527 if (pbEncoded
[0] == ASN_ENUMERATED
)
4529 unsigned int val
= 0, i
;
4533 SetLastError(CRYPT_E_ASN1_EOD
);
4536 else if (pbEncoded
[1] == 0)
4538 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4543 /* A little strange looking, but we have to accept a sign byte:
4544 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4545 * assuming a small length is okay here, it has to be in short
4548 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4550 SetLastError(CRYPT_E_ASN1_LARGE
);
4553 for (i
= 0; i
< pbEncoded
[1]; i
++)
4556 val
|= pbEncoded
[2 + i
];
4558 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4559 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4561 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4562 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4563 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4569 SetLastError(CRYPT_E_ASN1_BADTAG
);
4575 SetLastError(STATUS_ACCESS_VIOLATION
);
4582 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4585 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4590 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4592 if (!isdigit(*(pbEncoded))) \
4594 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4600 (word) += *(pbEncoded)++ - '0'; \
4605 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4606 SYSTEMTIME
*sysTime
)
4610 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4612 WORD hours
, minutes
= 0;
4613 BYTE sign
= *pbEncoded
++;
4616 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4617 if (ret
&& hours
>= 24)
4619 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4624 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4625 if (ret
&& minutes
>= 60)
4627 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4635 sysTime
->wHour
+= hours
;
4636 sysTime
->wMinute
+= minutes
;
4640 if (hours
> sysTime
->wHour
)
4643 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4646 sysTime
->wHour
-= hours
;
4647 if (minutes
> sysTime
->wMinute
)
4650 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4653 sysTime
->wMinute
-= minutes
;
4660 #define MIN_ENCODED_TIME_LENGTH 10
4662 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4663 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4668 if (pbEncoded
[0] == ASN_UTCTIME
)
4671 SetLastError(CRYPT_E_ASN1_EOD
);
4672 else if (pbEncoded
[1] > 0x7f)
4674 /* long-form date strings really can't be valid */
4675 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4679 SYSTEMTIME sysTime
= { 0 };
4680 BYTE len
= pbEncoded
[1];
4682 if (len
< MIN_ENCODED_TIME_LENGTH
)
4683 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4688 *pcbDecoded
= 2 + len
;
4690 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4691 if (sysTime
.wYear
>= 50)
4692 sysTime
.wYear
+= 1900;
4694 sysTime
.wYear
+= 2000;
4695 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4696 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4697 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4698 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4701 if (len
>= 2 && isdigit(*pbEncoded
) &&
4702 isdigit(*(pbEncoded
+ 1)))
4703 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4705 else if (isdigit(*pbEncoded
))
4706 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4709 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4715 *pcbStructInfo
= sizeof(FILETIME
);
4716 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4718 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4724 SetLastError(CRYPT_E_ASN1_BADTAG
);
4728 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4729 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4730 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4738 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4739 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4743 *pcbStructInfo
= bytesNeeded
;
4744 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4745 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4747 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4748 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4749 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4750 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4751 &bytesNeeded
, NULL
);
4757 SetLastError(STATUS_ACCESS_VIOLATION
);
4763 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4764 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4769 if (pbEncoded
[0] == ASN_GENERALTIME
)
4772 SetLastError(CRYPT_E_ASN1_EOD
);
4773 else if (pbEncoded
[1] > 0x7f)
4775 /* long-form date strings really can't be valid */
4776 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4780 BYTE len
= pbEncoded
[1];
4782 if (len
< MIN_ENCODED_TIME_LENGTH
)
4783 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4786 SYSTEMTIME sysTime
= { 0 };
4790 *pcbDecoded
= 2 + len
;
4792 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4793 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4794 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4795 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4798 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4801 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4803 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4810 /* workaround macro weirdness */
4811 digits
= min(len
, 3);
4812 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4813 sysTime
.wMilliseconds
);
4816 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4822 *pcbStructInfo
= sizeof(FILETIME
);
4823 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4825 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4831 SetLastError(CRYPT_E_ASN1_BADTAG
);
4835 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4836 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4840 InternalDecodeFunc decode
= NULL
;
4842 if (pbEncoded
[0] == ASN_UTCTIME
)
4843 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4844 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4845 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4847 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4848 pcbStructInfo
, pcbDecoded
);
4851 SetLastError(CRYPT_E_ASN1_BADTAG
);
4857 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4858 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4859 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4867 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4868 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4872 *pcbStructInfo
= bytesNeeded
;
4873 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4874 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4876 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4877 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4878 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4879 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4880 &bytesNeeded
, NULL
);
4886 SetLastError(STATUS_ACCESS_VIOLATION
);
4893 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4894 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4895 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4901 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4903 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4905 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4910 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4911 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4913 ptr
= pbEncoded
+ 1 + lenBytes
;
4914 remainingLen
= dataLen
;
4915 while (ret
&& remainingLen
)
4919 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4922 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4924 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4925 ptr
+= 1 + nextLenBytes
+ nextLen
;
4926 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4927 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4928 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4934 CRYPT_SEQUENCE_OF_ANY
*seq
;
4939 *pcbStructInfo
= bytesNeeded
;
4940 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4941 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4943 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4944 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4946 seq
->cValue
= cValue
;
4947 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4949 nextPtr
= (BYTE
*)seq
->rgValue
+
4950 cValue
* sizeof(CRYPT_DER_BLOB
);
4951 ptr
= pbEncoded
+ 1 + lenBytes
;
4952 remainingLen
= dataLen
;
4954 while (ret
&& remainingLen
)
4958 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4961 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4963 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4965 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4966 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4969 seq
->rgValue
[i
].pbData
= nextPtr
;
4970 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4972 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4974 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4975 ptr
+= 1 + nextLenBytes
+ nextLen
;
4985 SetLastError(CRYPT_E_ASN1_BADTAG
);
4991 SetLastError(STATUS_ACCESS_VIOLATION
);
4998 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4999 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5004 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5006 DWORD bytesNeeded
, dataLen
;
5008 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5010 struct AsnArrayDescriptor arrayDesc
= {
5011 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
5012 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5013 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
5014 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5019 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
,
5020 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5021 NULL
, NULL
, &nameLen
, NULL
);
5022 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
5025 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5027 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5029 *pcbStructInfo
= bytesNeeded
;
5030 else if (*pcbStructInfo
< bytesNeeded
)
5032 *pcbStructInfo
= bytesNeeded
;
5033 SetLastError(ERROR_MORE_DATA
);
5038 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5040 *pcbStructInfo
= bytesNeeded
;
5043 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5044 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
,
5045 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5046 &name
->u
.FullName
.cAltEntry
, name
->u
.FullName
.rgAltEntry
,
5050 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5056 SetLastError(CRYPT_E_ASN1_BADTAG
);
5062 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5063 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5065 struct AsnDecodeSequenceItem items
[] = {
5066 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5067 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5068 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5069 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5070 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5071 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5072 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5073 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5074 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5075 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5077 CRL_DIST_POINT
*point
= pvStructInfo
;
5080 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5081 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5082 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5086 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5087 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5088 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5092 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5093 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5097 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5098 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5099 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5101 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
5102 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
5106 SetLastError(STATUS_ACCESS_VIOLATION
);
5113 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5114 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5115 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5119 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5120 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5124 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5125 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5127 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
5128 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
5132 SetLastError(STATUS_ACCESS_VIOLATION
);
5139 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5140 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5141 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5145 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5146 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5150 struct AsnDecodeSequenceItem items
[] = {
5151 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5152 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5153 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5154 offsetof(CRL_ISSUING_DIST_POINT
,
5155 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5156 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5157 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5159 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5160 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5162 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5163 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5164 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5165 OnlySomeReasonFlags
.pbData
), 0 },
5166 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5167 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5170 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5171 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5172 pcbStructInfo
, NULL
, NULL
);
5176 SetLastError(STATUS_ACCESS_VIOLATION
);
5183 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5184 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5189 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5190 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5194 SetLastError(CRYPT_E_ASN1_EOD
);
5197 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5199 SetLastError(CRYPT_E_ASN1_BADTAG
);
5202 /* The BOOL is implicit: if the integer is present, then it's TRUE */
5203 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5204 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
5206 if (ret
&& pvStructInfo
)
5207 *(BOOL
*)pvStructInfo
= TRUE
;
5208 TRACE("returning %d\n", ret
);
5212 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5213 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5217 struct AsnDecodeSequenceItem items
[] = {
5218 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5219 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5220 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5221 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5222 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5223 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5224 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
5227 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5229 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5230 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5232 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5233 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5234 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5237 TRACE("%d\n", *pcbDecoded
);
5238 if (*pcbDecoded
< cbEncoded
)
5239 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5240 *(pbEncoded
+ *pcbDecoded
+ 1));
5242 TRACE("returning %d\n", ret
);
5246 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5247 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5251 struct AsnArrayDescriptor arrayDesc
= { 0,
5252 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5253 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5256 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5257 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5259 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5260 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5262 bytesNeeded
+= MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
,
5263 cPermittedSubtree
, cExcludedSubtree
);
5265 *pcbStructInfo
= bytesNeeded
;
5266 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5267 pcbStructInfo
, bytesNeeded
)))
5269 CERT_NAME_CONSTRAINTS_INFO
*info
= (CERT_NAME_CONSTRAINTS_INFO
*)
5270 ((BYTE
*)pvStructInfo
-
5271 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
));
5273 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5274 &info
->cPermittedSubtree
, info
->rgPermittedSubtree
, &bytesNeeded
,
5281 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5282 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5286 struct AsnArrayDescriptor arrayDesc
= { 0,
5287 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5288 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5291 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5292 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5294 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5295 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5297 bytesNeeded
+= FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
,
5300 *pcbStructInfo
= bytesNeeded
;
5301 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5302 pcbStructInfo
, bytesNeeded
)))
5304 CERT_NAME_CONSTRAINTS_INFO
*info
= (CERT_NAME_CONSTRAINTS_INFO
*)
5305 ((BYTE
*)pvStructInfo
-
5306 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
));
5308 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5309 &info
->cExcludedSubtree
, info
->rgExcludedSubtree
, &bytesNeeded
,
5316 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5317 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5318 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5322 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5323 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5327 struct AsnDecodeSequenceItem items
[] = {
5328 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5329 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5330 CRYPT_AsnDecodePermittedSubtree
,
5331 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5332 cExcludedSubtree
), TRUE
, TRUE
,
5333 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5334 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5335 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5336 CRYPT_AsnDecodeExcludedSubtree
,
5337 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5339 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5342 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5343 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5344 pcbStructInfo
, NULL
, NULL
);
5348 SetLastError(STATUS_ACCESS_VIOLATION
);
5354 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5355 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5359 struct AsnDecodeSequenceItem items
[] = {
5360 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5361 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5363 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5364 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5365 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5367 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5369 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5370 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5372 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5373 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5374 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5375 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5377 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5380 TRACE("returning %d\n", ret
);
5384 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5385 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5388 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5389 struct AsnDecodeSequenceItem items
[] = {
5390 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5391 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5392 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5393 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5394 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5395 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5396 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5397 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5398 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5399 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5400 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5401 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5402 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5403 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5404 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5405 HashEncryptionAlgorithm
.pszObjId
), 0 },
5406 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5407 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5408 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5409 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5410 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5411 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5412 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5416 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5417 pvStructInfo
, *pcbStructInfo
);
5419 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5420 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5421 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5425 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5426 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5427 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5431 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5432 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5436 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5437 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5438 if (ret
&& pvStructInfo
)
5440 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5441 pcbStructInfo
, *pcbStructInfo
);
5444 CMSG_SIGNER_INFO
*info
;
5446 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5447 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5448 info
= pvStructInfo
;
5449 info
->Issuer
.pbData
= ((BYTE
*)info
+
5450 sizeof(CMSG_SIGNER_INFO
));
5451 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5452 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5453 pcbStructInfo
, NULL
);
5459 SetLastError(STATUS_ACCESS_VIOLATION
);
5462 TRACE("returning %d\n", ret
);
5466 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5467 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5471 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
5472 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5475 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5476 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5478 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5479 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5481 bytesNeeded
+= MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
);
5483 *pcbStructInfo
= bytesNeeded
;
5484 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5485 pcbStructInfo
, bytesNeeded
)))
5487 CRYPT_SIGNED_INFO
*info
= (CRYPT_SIGNED_INFO
*)
5488 ((BYTE
*)pvStructInfo
- offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
));
5490 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5491 &info
->cCertEncoded
, info
->rgCertEncoded
, &bytesNeeded
,
5498 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5499 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5503 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
5504 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5507 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5508 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5510 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5511 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5513 bytesNeeded
+= MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
);
5515 *pcbStructInfo
= bytesNeeded
;
5516 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5517 pcbStructInfo
, bytesNeeded
)))
5519 CRYPT_SIGNED_INFO
*info
= (CRYPT_SIGNED_INFO
*)
5520 ((BYTE
*)pvStructInfo
- offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
));
5522 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5523 &info
->cCrlEncoded
, info
->rgCrlEncoded
, &bytesNeeded
,
5530 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5531 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5534 CERT_ID
*id
= pvStructInfo
;
5537 if (*pbEncoded
== ASN_SEQUENCEOF
)
5539 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5540 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5544 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5545 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5546 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5547 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5549 *pcbStructInfo
= sizeof(CERT_ID
);
5552 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5554 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5555 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5559 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5560 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5561 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5562 sizeof(CRYPT_DATA_BLOB
);
5564 *pcbStructInfo
= sizeof(CERT_ID
);
5568 SetLastError(CRYPT_E_ASN1_BADTAG
);
5572 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5573 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5576 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5577 struct AsnDecodeSequenceItem items
[] = {
5578 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5579 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5580 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5581 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5582 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5583 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5584 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5585 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5586 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5587 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5588 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5589 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5590 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5591 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5592 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5593 HashEncryptionAlgorithm
.pszObjId
), 0 },
5594 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5595 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5596 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5597 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5598 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5599 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5600 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5604 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5605 pvStructInfo
, *pcbStructInfo
);
5607 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5608 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5609 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5613 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5614 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5615 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5619 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5620 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5624 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5625 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5626 if (ret
&& pvStructInfo
)
5628 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5629 pcbStructInfo
, *pcbStructInfo
);
5632 CMSG_CMS_SIGNER_INFO
*info
;
5634 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5635 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5636 info
= pvStructInfo
;
5637 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5638 sizeof(CMSG_CMS_SIGNER_INFO
));
5639 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5640 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5641 pcbStructInfo
, NULL
);
5647 SetLastError(STATUS_ACCESS_VIOLATION
);
5650 TRACE("returning %d\n", ret
);
5654 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5655 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5658 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5659 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5660 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5663 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5664 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5666 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5667 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5669 bytesNeeded
+= FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
);
5671 *pcbStructInfo
= bytesNeeded
;
5672 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5673 pcbStructInfo
, bytesNeeded
)))
5675 CRYPT_SIGNED_INFO
*info
= (CRYPT_SIGNED_INFO
*)
5676 ((BYTE
*)pvStructInfo
- offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
));
5678 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5679 &info
->cSignerInfo
, info
->rgSignerInfo
, &bytesNeeded
,
5686 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5687 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5688 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5691 struct AsnDecodeSequenceItem items
[] = {
5692 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5693 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5694 /* Placeholder for the hash algorithms - redundant with those in the
5695 * signers, so just ignore them.
5697 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5698 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5699 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5700 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5701 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5702 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5703 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5704 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5705 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5706 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5707 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5708 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5709 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5710 CRYPT_DecodeSignerArray
,
5711 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5712 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5715 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5716 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5718 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5719 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5721 TRACE("returning %d\n", ret
);
5725 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5726 LPCSTR lpszStructType
)
5728 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5730 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5731 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5733 SetLastError(ERROR_FILE_NOT_FOUND
);
5736 if (!HIWORD(lpszStructType
))
5738 switch (LOWORD(lpszStructType
))
5740 case LOWORD(X509_CERT
):
5741 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5743 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5744 decodeFunc
= CRYPT_AsnDecodeCert
;
5746 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5747 decodeFunc
= CRYPT_AsnDecodeCRL
;
5749 case LOWORD(X509_EXTENSIONS
):
5750 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5752 case LOWORD(X509_NAME_VALUE
):
5753 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5755 case LOWORD(X509_NAME
):
5756 decodeFunc
= CRYPT_AsnDecodeName
;
5758 case LOWORD(X509_PUBLIC_KEY_INFO
):
5759 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5761 case LOWORD(X509_AUTHORITY_KEY_ID
):
5762 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5764 case LOWORD(X509_ALTERNATE_NAME
):
5765 decodeFunc
= CRYPT_AsnDecodeAltName
;
5767 case LOWORD(X509_BASIC_CONSTRAINTS
):
5768 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5770 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5771 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5773 case LOWORD(X509_CERT_POLICIES
):
5774 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5776 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5777 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5779 case LOWORD(X509_UNICODE_NAME
):
5780 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5782 case LOWORD(PKCS_ATTRIBUTE
):
5783 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5785 case LOWORD(X509_UNICODE_NAME_VALUE
):
5786 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5788 case LOWORD(X509_OCTET_STRING
):
5789 decodeFunc
= CRYPT_AsnDecodeOctets
;
5791 case LOWORD(X509_BITS
):
5792 case LOWORD(X509_KEY_USAGE
):
5793 decodeFunc
= CRYPT_AsnDecodeBits
;
5795 case LOWORD(X509_INTEGER
):
5796 decodeFunc
= CRYPT_AsnDecodeInt
;
5798 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5799 decodeFunc
= CRYPT_AsnDecodeInteger
;
5801 case LOWORD(X509_MULTI_BYTE_UINT
):
5802 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5804 case LOWORD(X509_ENUMERATED
):
5805 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5807 case LOWORD(X509_CHOICE_OF_TIME
):
5808 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5810 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5811 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5813 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5814 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5816 case LOWORD(PKCS_CONTENT_INFO
):
5817 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5819 case LOWORD(X509_SEQUENCE_OF_ANY
):
5820 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5822 case LOWORD(PKCS_UTC_TIME
):
5823 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5825 case LOWORD(X509_CRL_DIST_POINTS
):
5826 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5828 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5829 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5831 case LOWORD(PKCS_CTL
):
5832 decodeFunc
= CRYPT_AsnDecodeCTL
;
5834 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5835 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5837 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5838 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5840 case LOWORD(PKCS_ATTRIBUTES
):
5841 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5843 case LOWORD(X509_ISSUING_DIST_POINT
):
5844 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5846 case LOWORD(X509_NAME_CONSTRAINTS
):
5847 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5849 case LOWORD(PKCS7_SIGNER_INFO
):
5850 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5852 case LOWORD(CMS_SIGNER_INFO
):
5853 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5857 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5858 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5859 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5860 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5861 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5862 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5863 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5864 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5865 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5866 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5867 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5868 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5869 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5870 decodeFunc
= CRYPT_AsnDecodeBits
;
5871 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5872 decodeFunc
= CRYPT_AsnDecodeOctets
;
5873 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5874 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5875 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5876 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5877 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5878 decodeFunc
= CRYPT_AsnDecodeAltName
;
5879 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5880 decodeFunc
= CRYPT_AsnDecodeAltName
;
5881 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5882 decodeFunc
= CRYPT_AsnDecodeAltName
;
5883 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5884 decodeFunc
= CRYPT_AsnDecodeAltName
;
5885 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5886 decodeFunc
= CRYPT_AsnDecodeAltName
;
5887 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5888 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5889 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5890 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5891 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5892 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5893 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5894 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5895 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5896 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5897 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5898 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5899 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5900 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5901 else if (!strcmp(lpszStructType
, szOID_CTL
))
5902 decodeFunc
= CRYPT_AsnDecodeCTL
;
5906 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5907 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5909 static HCRYPTOIDFUNCSET set
= NULL
;
5910 CryptDecodeObjectFunc decodeFunc
= NULL
;
5913 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5914 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5915 (void **)&decodeFunc
, hFunc
);
5919 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5920 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5922 static HCRYPTOIDFUNCSET set
= NULL
;
5923 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5926 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5927 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5928 (void **)&decodeFunc
, hFunc
);
5932 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5933 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5934 DWORD
*pcbStructInfo
)
5937 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5938 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5939 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5941 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5942 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5943 pvStructInfo
, pcbStructInfo
);
5945 if (!pvStructInfo
&& !pcbStructInfo
)
5947 SetLastError(ERROR_INVALID_PARAMETER
);
5950 if (cbEncoded
> MAX_ENCODED_LEN
)
5952 SetLastError(CRYPT_E_ASN1_LARGE
);
5956 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5959 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5960 debugstr_a(lpszStructType
));
5961 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5962 lpszStructType
, &hFunc
);
5963 if (!pCryptDecodeObject
)
5964 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5965 lpszStructType
, &hFunc
);
5967 if (pCryptDecodeObject
)
5968 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5969 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5970 else if (pCryptDecodeObjectEx
)
5971 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5972 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5973 pvStructInfo
, pcbStructInfo
);
5975 CryptFreeOIDFunctionAddress(hFunc
, 0);
5976 TRACE_(crypt
)("returning %d\n", ret
);
5980 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5981 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5982 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5985 CryptDecodeObjectExFunc decodeFunc
;
5986 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5988 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5989 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5990 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5992 if (!pvStructInfo
&& !pcbStructInfo
)
5994 SetLastError(ERROR_INVALID_PARAMETER
);
5997 if (cbEncoded
> MAX_ENCODED_LEN
)
5999 SetLastError(CRYPT_E_ASN1_LARGE
);
6003 SetLastError(NOERROR
);
6004 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
6005 *(BYTE
**)pvStructInfo
= NULL
;
6006 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6009 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6010 debugstr_a(lpszStructType
));
6011 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6015 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6016 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6019 CryptDecodeObjectFunc pCryptDecodeObject
=
6020 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6022 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6023 * directly, as that could cause an infinite loop.
6025 if (pCryptDecodeObject
)
6027 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6029 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6030 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6031 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6032 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6033 ret
= pCryptDecodeObject(dwCertEncodingType
,
6034 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6035 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6038 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6039 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6043 CryptFreeOIDFunctionAddress(hFunc
, 0);
6044 TRACE_(crypt
)("returning %d\n", ret
);
6048 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6052 TRACE_(crypt
)("(%p)\n", pPFX
);
6054 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6055 * version integer of length 1 (3 encoded byes) and at least one other
6056 * datum (two encoded bytes), plus at least two bytes for the outer
6057 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6059 if (pPFX
->cbData
< 7)
6061 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6065 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6067 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6069 /* Need at least three bytes for the integer version */
6070 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6072 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6073 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6074 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6083 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6086 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);