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
) };
2395 struct GenericArray
*entries
= pvStructInfo
;
2397 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2398 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2400 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2401 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2402 entries
? entries
->rgItems
: NULL
);
2406 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2407 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2408 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2412 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2413 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2417 struct AsnDecodeSequenceItem items
[] = {
2418 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2419 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2420 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2421 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2422 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2423 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2424 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2425 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2426 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2427 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2428 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2429 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2430 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2432 { 0, offsetof(CTL_INFO
, NextUpdate
),
2433 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2435 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2436 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2437 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2438 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2439 CRYPT_AsnDecodeCTLEntries
, sizeof(struct GenericArray
),
2440 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2441 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2442 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
2443 offsetof(CTL_INFO
, rgExtension
), 0 },
2446 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2447 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2449 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2450 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2451 pcbStructInfo
, NULL
, NULL
);
2455 SetLastError(STATUS_ACCESS_VIOLATION
);
2461 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2462 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2466 struct AsnDecodeSequenceItem items
[] = {
2467 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2468 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2469 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2470 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2471 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2472 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2474 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2476 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2477 pvStructInfo
, *pcbStructInfo
);
2479 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2480 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2481 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2482 TRACE("returning %d\n", ret
);
2486 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2487 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2488 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2492 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2493 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2498 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2499 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2500 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2502 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2503 NULL
, NULL
, &bytesNeeded
, NULL
)))
2505 bytesNeeded
+= sizeof(CRYPT_SMIME_CAPABILITIES
);
2507 *pcbStructInfo
= bytesNeeded
;
2508 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2509 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2511 PCRYPT_SMIME_CAPABILITIES capabilities
;
2513 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2514 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2515 capabilities
= pvStructInfo
;
2516 capabilities
->rgCapability
=
2517 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2518 sizeof(CRYPT_SMIME_CAPABILITIES
));
2519 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
,
2520 pbEncoded
, cbEncoded
, &capabilities
->cCapability
,
2521 capabilities
->rgCapability
, pcbStructInfo
, NULL
);
2527 SetLastError(STATUS_ACCESS_VIOLATION
);
2530 TRACE("returning %d\n", ret
);
2534 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2535 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2540 LPSTR
*pStr
= pvStructInfo
;
2542 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2544 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2545 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2547 if (pbEncoded
[0] != ASN_IA5STRING
)
2549 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2554 bytesNeeded
+= dataLen
;
2556 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2558 *pcbStructInfo
= bytesNeeded
;
2559 else if (*pcbStructInfo
< bytesNeeded
)
2561 *pcbStructInfo
= bytesNeeded
;
2562 SetLastError(ERROR_MORE_DATA
);
2567 *pcbStructInfo
= bytesNeeded
;
2573 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2584 static BOOL
CRYPT_AsnDecodeIntArray(const BYTE
*pbEncoded
,
2585 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2588 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2589 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2590 struct GenericArray
*array
= pvStructInfo
;
2593 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2594 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2596 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2597 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2598 array
? array
->rgItems
: NULL
);
2599 TRACE("returning %d\n", ret
);
2603 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2604 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2608 struct AsnDecodeSequenceItem items
[] = {
2609 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2610 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2611 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2612 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2613 cNoticeNumbers
), CRYPT_AsnDecodeIntArray
, sizeof(struct GenericArray
),
2614 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2615 rgNoticeNumbers
), 0 },
2619 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2620 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2622 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2623 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2627 /* The caller is expecting a pointer to a
2628 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2629 * CRYPT_AsnDecodeSequence is decoding a
2630 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2631 * needed, and decode again if the requisite space is available.
2633 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2635 *pcbStructInfo
= bytesNeeded
;
2636 else if (*pcbStructInfo
< bytesNeeded
)
2638 *pcbStructInfo
= bytesNeeded
;
2639 SetLastError(ERROR_MORE_DATA
);
2644 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2646 *pcbStructInfo
= bytesNeeded
;
2647 /* The pointer (pvStructInfo) passed in points to the first dynamic
2648 * pointer, so use it as the pointer to the
2649 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2650 * appropriate offset for the first dynamic pointer within the
2651 * notice reference by pointing to the first memory location past
2652 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2655 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2656 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2657 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2658 ret
= CRYPT_AsnDecodeSequence(items
,
2659 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2660 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2661 noticeRef
->pszOrganization
);
2664 TRACE("returning %d\n", ret
);
2668 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2669 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2675 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2677 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2678 DWORD bytesNeeded
= sizeof(LPWSTR
);
2680 switch (pbEncoded
[0])
2682 case ASN_NUMERICSTRING
:
2684 bytesNeeded
+= (dataLen
+ 1) * 2;
2686 case ASN_PRINTABLESTRING
:
2688 bytesNeeded
+= (dataLen
+ 1) * 2;
2692 bytesNeeded
+= (dataLen
+ 1) * 2;
2696 bytesNeeded
+= (dataLen
+ 1) * 2;
2698 case ASN_VIDEOTEXSTRING
:
2700 bytesNeeded
+= (dataLen
+ 1) * 2;
2702 case ASN_GRAPHICSTRING
:
2704 bytesNeeded
+= (dataLen
+ 1) * 2;
2706 case ASN_VISIBLESTRING
:
2708 bytesNeeded
+= (dataLen
+ 1) * 2;
2710 case ASN_GENERALSTRING
:
2712 bytesNeeded
+= (dataLen
+ 1) * 2;
2714 case ASN_UNIVERSALSTRING
:
2716 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2720 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2722 case ASN_UTF8STRING
:
2724 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2725 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2728 SetLastError(CRYPT_E_ASN1_BADTAG
);
2733 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2735 *pcbStructInfo
= bytesNeeded
;
2736 else if (*pcbStructInfo
< bytesNeeded
)
2738 *pcbStructInfo
= bytesNeeded
;
2739 SetLastError(ERROR_MORE_DATA
);
2744 LPWSTR
*pStr
= pvStructInfo
;
2746 *pcbStructInfo
= bytesNeeded
;
2750 LPWSTR str
= *(LPWSTR
*)pStr
;
2753 switch (pbEncoded
[0])
2755 case ASN_NUMERICSTRING
:
2756 case ASN_PRINTABLESTRING
:
2759 case ASN_VIDEOTEXSTRING
:
2760 case ASN_GRAPHICSTRING
:
2761 case ASN_VISIBLESTRING
:
2762 case ASN_GENERALSTRING
:
2763 for (i
= 0; i
< dataLen
; i
++)
2764 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2767 case ASN_UNIVERSALSTRING
:
2768 for (i
= 0; i
< dataLen
/ 4; i
++)
2769 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2770 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2774 for (i
= 0; i
< dataLen
/ 2; i
++)
2775 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2776 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2779 case ASN_UTF8STRING
:
2781 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2782 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2783 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2796 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2797 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2798 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2801 struct AsnDecodeSequenceItem items
[] = {
2802 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2803 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2804 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2805 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2806 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2807 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2808 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2810 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2812 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2813 pvStructInfo
, *pcbStructInfo
);
2815 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2816 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2817 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2818 TRACE("returning %d\n", ret
);
2822 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2823 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2824 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2825 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2829 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2830 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2836 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2837 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2842 *pcbStructInfo
= bytesNeeded
;
2843 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2844 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2846 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2848 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2849 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2850 notice
= pvStructInfo
;
2851 notice
->pNoticeReference
=
2852 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2853 ((BYTE
*)pvStructInfo
+
2854 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2855 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2856 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2857 pvStructInfo
, &bytesNeeded
, NULL
);
2863 SetLastError(STATUS_ACCESS_VIOLATION
);
2866 TRACE("returning %d\n", ret
);
2870 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2871 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2875 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
2876 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2879 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2880 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2882 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2883 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
2885 bytesNeeded
+= FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
);
2887 *pcbStructInfo
= bytesNeeded
;
2888 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
2889 pcbStructInfo
, bytesNeeded
)))
2891 CRYPT_ATTRIBUTE
*attr
= (CRYPT_ATTRIBUTE
*)((BYTE
*)pvStructInfo
-
2892 offsetof(CRYPT_ATTRIBUTE
, cValue
));
2894 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
2895 &attr
->cValue
, attr
->rgValue
, pcbStructInfo
, pcbDecoded
);
2901 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2902 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2906 struct AsnDecodeSequenceItem items
[] = {
2907 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2908 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2909 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2910 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2911 CRYPT_AsnDecodePKCSAttributeValue
,
2912 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2913 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2915 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2917 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2918 pvStructInfo
, *pcbStructInfo
);
2920 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2921 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2922 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2923 TRACE("returning %d\n", ret
);
2927 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2928 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2929 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2933 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2934 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2940 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2941 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2945 *pcbStructInfo
= bytesNeeded
;
2946 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2947 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2949 PCRYPT_ATTRIBUTE attr
;
2951 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2952 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2953 attr
= pvStructInfo
;
2954 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2955 sizeof(CRYPT_ATTRIBUTE
));
2956 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2957 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2964 SetLastError(STATUS_ACCESS_VIOLATION
);
2967 TRACE("returning %d\n", ret
);
2971 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2972 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2975 struct AsnArrayDescriptor arrayDesc
= { 0,
2976 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2977 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2978 PCRYPT_ATTRIBUTES attrs
= pvStructInfo
;
2981 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2982 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2987 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2988 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2989 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2993 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2994 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3000 if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
3001 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3002 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
3003 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
3007 *pcbStructInfo
= bytesNeeded
;
3008 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3009 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3011 PCRYPT_ATTRIBUTES attrs
;
3013 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3014 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3015 attrs
= pvStructInfo
;
3016 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
3017 sizeof(CRYPT_ATTRIBUTES
));
3018 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
3019 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3020 &bytesNeeded
, NULL
);
3026 SetLastError(STATUS_ACCESS_VIOLATION
);
3029 TRACE("returning %d\n", ret
);
3033 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3034 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3036 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
3038 struct AsnDecodeSequenceItem items
[] = {
3039 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
3040 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3041 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
3042 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
3043 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3044 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
3047 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3048 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3050 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3051 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3052 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
3053 if (ret
&& pvStructInfo
)
3055 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
3056 debugstr_a(algo
->pszObjId
));
3061 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
3062 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3066 struct AsnDecodeSequenceItem items
[] = {
3067 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
3068 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3069 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
3070 Algorithm
.pszObjId
) },
3071 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
3072 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3073 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
3075 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
3077 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3078 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3079 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
3083 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
3084 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3085 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3093 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
3094 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3097 *pcbStructInfo
= bytesNeeded
;
3098 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3099 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3101 PCERT_PUBLIC_KEY_INFO info
;
3103 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3104 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3105 info
= pvStructInfo
;
3106 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
3107 sizeof(CERT_PUBLIC_KEY_INFO
);
3108 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
3109 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3110 &bytesNeeded
, NULL
);
3116 SetLastError(STATUS_ACCESS_VIOLATION
);
3123 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3124 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3130 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3133 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
3135 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3138 if (pbEncoded
[1] > 1)
3140 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3147 *pcbStructInfo
= sizeof(BOOL
);
3150 else if (*pcbStructInfo
< sizeof(BOOL
))
3152 *pcbStructInfo
= sizeof(BOOL
);
3153 SetLastError(ERROR_MORE_DATA
);
3158 *pcbStructInfo
= sizeof(BOOL
);
3159 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
3162 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3166 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3167 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3169 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
3170 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
3173 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3174 pvStructInfo
, *pcbStructInfo
);
3178 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3181 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3182 if (1 + lenBytes
> cbEncoded
)
3184 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3187 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3189 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3191 case 1: /* rfc822Name */
3192 case 2: /* dNSName */
3193 case 6: /* uniformResourceIdentifier */
3194 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3196 case 4: /* directoryName */
3197 case 7: /* iPAddress */
3198 bytesNeeded
+= dataLen
;
3200 case 8: /* registeredID */
3201 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3205 /* FIXME: ugly, shouldn't need to know internals of OID decode
3206 * function to use it.
3208 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3211 case 0: /* otherName */
3212 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3213 SetLastError(CRYPT_E_ASN1_BADTAG
);
3216 case 3: /* x400Address, unimplemented */
3217 case 5: /* ediPartyName, unimplemented */
3218 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3219 SetLastError(CRYPT_E_ASN1_BADTAG
);
3223 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3224 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3230 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3232 *pcbStructInfo
= bytesNeeded
;
3233 else if (*pcbStructInfo
< bytesNeeded
)
3235 *pcbStructInfo
= bytesNeeded
;
3236 SetLastError(ERROR_MORE_DATA
);
3241 *pcbStructInfo
= bytesNeeded
;
3242 /* MS used values one greater than the asn1 ones.. sigh */
3243 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3244 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3246 case 1: /* rfc822Name */
3247 case 2: /* dNSName */
3248 case 6: /* uniformResourceIdentifier */
3252 for (i
= 0; i
< dataLen
; i
++)
3253 entry
->u
.pwszURL
[i
] =
3254 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3255 entry
->u
.pwszURL
[i
] = 0;
3256 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3257 debugstr_w(entry
->u
.pwszURL
));
3260 case 4: /* directoryName */
3261 /* The data are memory-equivalent with the IPAddress case,
3264 case 7: /* iPAddress */
3265 /* The next data pointer is in the pwszURL spot, that is,
3266 * the first 4 bytes. Need to move it to the next spot.
3268 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3269 entry
->u
.IPAddress
.cbData
= dataLen
;
3270 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3273 case 8: /* registeredID */
3274 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3275 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3284 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3285 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3289 struct AsnArrayDescriptor arrayDesc
= { 0,
3290 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3291 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3292 PCERT_ALT_NAME_INFO info
= pvStructInfo
;
3294 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3295 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3298 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
3299 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3300 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3301 info
? info
->rgAltEntry
: NULL
);
3305 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3306 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
3307 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3312 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3313 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3315 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3318 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3319 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
3321 if (ret
&& pvStructInfo
)
3323 CRYPT_DATA_BLOB
*blob
= pvStructInfo
;
3330 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
3332 temp
= blob
->pbData
[i
];
3333 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
3334 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
3338 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3342 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3343 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3344 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3350 struct AsnDecodeSequenceItem items
[] = {
3351 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3352 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3353 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3354 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3355 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3356 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3357 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3358 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3359 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3360 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3361 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3364 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3365 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3366 pcbStructInfo
, NULL
, NULL
);
3370 SetLastError(STATUS_ACCESS_VIOLATION
);
3377 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3378 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3379 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3385 struct AsnDecodeSequenceItem items
[] = {
3386 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3387 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3388 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3389 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3390 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3391 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3392 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3393 AuthorityCertIssuer
.rgAltEntry
), 0 },
3394 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3395 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3396 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3397 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3398 AuthorityCertSerialNumber
.pbData
), 0 },
3401 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3402 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3403 pcbStructInfo
, NULL
, NULL
);
3407 SetLastError(STATUS_ACCESS_VIOLATION
);
3414 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3415 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3418 struct AsnDecodeSequenceItem items
[] = {
3419 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3420 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3421 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3422 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3423 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3424 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3426 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3428 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3429 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3430 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3433 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3434 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3435 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3439 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3440 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3444 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3445 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3446 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3448 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3449 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3453 SetLastError(STATUS_ACCESS_VIOLATION
);
3460 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3461 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3466 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3467 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3469 /* The caller has already checked the tag, no need to check it again.
3470 * Check the outer length is valid:
3472 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3474 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3477 pbEncoded
+= 1 + lenBytes
;
3478 cbEncoded
-= 1 + lenBytes
;
3479 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3480 cbEncoded
-= 2; /* space for 0 TLV */
3481 /* Check the inner length is valid: */
3482 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3486 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3487 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3488 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3490 if (*(pbEncoded
+ decodedLen
) != 0 ||
3491 *(pbEncoded
+ decodedLen
+ 1) != 0)
3493 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3494 *(pbEncoded
+ decodedLen
),
3495 *(pbEncoded
+ decodedLen
+ 1));
3496 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3502 if (ret
&& pcbDecoded
)
3504 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3505 TRACE("decoded %d bytes\n", *pcbDecoded
);
3512 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3513 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3516 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3517 struct AsnDecodeSequenceItem items
[] = {
3518 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3519 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3520 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3521 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3522 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3523 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3524 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3528 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3529 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3531 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3532 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3533 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3537 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3538 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3539 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3543 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3544 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3548 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3549 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3550 if (ret
&& pvStructInfo
)
3552 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3553 pcbStructInfo
, *pcbStructInfo
);
3556 CRYPT_CONTENT_INFO
*info
;
3558 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3559 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3560 info
= pvStructInfo
;
3561 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3562 sizeof(CRYPT_CONTENT_INFO
));
3563 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3564 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3565 pcbStructInfo
, NULL
);
3571 SetLastError(STATUS_ACCESS_VIOLATION
);
3577 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3578 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3579 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3582 struct AsnDecodeSequenceItem items
[] = {
3583 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3584 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3585 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3586 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3587 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3589 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3590 CRYPT_AsnDecodePKCSContentInfoInternal
,
3591 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3592 ContentInfo
.pszObjId
), 0 },
3593 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3594 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3595 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3598 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3599 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3604 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3605 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3606 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3610 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3611 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3617 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3618 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3621 *pcbStructInfo
= bytesNeeded
;
3622 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3623 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3625 CERT_ALT_NAME_INFO
*name
;
3627 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3628 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3629 name
= pvStructInfo
;
3630 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3631 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3632 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3633 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3634 &bytesNeeded
, NULL
);
3640 SetLastError(STATUS_ACCESS_VIOLATION
);
3647 struct PATH_LEN_CONSTRAINT
3649 BOOL fPathLenConstraint
;
3650 DWORD dwPathLenConstraint
;
3653 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3654 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3658 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3660 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3661 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3665 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3667 *pcbStructInfo
= bytesNeeded
;
3669 else if (*pcbStructInfo
< bytesNeeded
)
3671 SetLastError(ERROR_MORE_DATA
);
3672 *pcbStructInfo
= bytesNeeded
;
3677 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3679 *pcbStructInfo
= bytesNeeded
;
3680 size
= sizeof(constraint
->dwPathLenConstraint
);
3681 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3682 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3684 constraint
->fPathLenConstraint
= TRUE
;
3685 TRACE("got an int, dwPathLenConstraint is %d\n",
3686 constraint
->dwPathLenConstraint
);
3688 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3692 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3693 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3697 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3698 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3699 offsetof(CERT_NAME_BLOB
, pbData
) };
3700 struct GenericArray
*entries
= pvStructInfo
;
3702 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3703 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3705 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3706 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3707 entries
? entries
->rgItems
: NULL
);
3708 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3712 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3713 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3714 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3720 struct AsnDecodeSequenceItem items
[] = {
3721 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3722 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3723 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3724 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3725 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3726 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3727 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3728 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3729 sizeof(struct GenericArray
), TRUE
, TRUE
,
3730 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3733 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3734 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3735 pcbStructInfo
, NULL
, NULL
);
3739 SetLastError(STATUS_ACCESS_VIOLATION
);
3746 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3747 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3748 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3754 struct AsnDecodeSequenceItem items
[] = {
3755 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3756 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3757 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3758 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3759 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3762 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3763 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3764 pcbStructInfo
, NULL
, NULL
);
3768 SetLastError(STATUS_ACCESS_VIOLATION
);
3775 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3776 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3779 struct AsnDecodeSequenceItem items
[] = {
3780 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3781 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3782 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3784 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3785 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3786 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3789 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3791 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3792 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3794 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3795 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3796 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3800 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3801 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3805 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3806 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3807 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3808 struct GenericArray
*entries
= pvStructInfo
;
3810 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3811 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3813 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3814 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3815 entries
? entries
->rgItems
: NULL
);
3816 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3820 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3821 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3823 struct AsnDecodeSequenceItem items
[] = {
3824 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3825 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3826 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3827 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3828 CRYPT_AsnDecodePolicyQualifiers
, sizeof(struct GenericArray
), TRUE
,
3829 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3831 CERT_POLICY_INFO
*info
= pvStructInfo
;
3834 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3835 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3837 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3838 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3839 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3843 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3844 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3845 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3849 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3850 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3854 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3855 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3856 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3858 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3859 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3863 SetLastError(STATUS_ACCESS_VIOLATION
);
3869 #define RSA1_MAGIC 0x31415352
3871 struct DECODED_RSA_PUB_KEY
3874 CRYPT_INTEGER_BLOB modulus
;
3877 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3878 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3879 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3885 struct AsnDecodeSequenceItem items
[] = {
3886 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3887 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3888 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3890 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3891 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3893 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3896 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3897 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3901 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3902 decodedKey
->modulus
.cbData
;
3906 *pcbStructInfo
= bytesNeeded
;
3909 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3910 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3913 RSAPUBKEY
*rsaPubKey
;
3915 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3916 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3918 hdr
->bType
= PUBLICKEYBLOB
;
3919 hdr
->bVersion
= CUR_BLOB_VERSION
;
3921 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3922 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3923 sizeof(BLOBHEADER
));
3924 rsaPubKey
->magic
= RSA1_MAGIC
;
3925 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3926 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3927 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3928 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3929 decodedKey
->modulus
.cbData
);
3931 LocalFree(decodedKey
);
3936 SetLastError(STATUS_ACCESS_VIOLATION
);
3943 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3944 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3948 DWORD bytesNeeded
, dataLen
;
3950 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3951 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3953 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3955 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3957 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3958 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3960 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3962 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3964 *pcbStructInfo
= bytesNeeded
;
3965 else if (*pcbStructInfo
< bytesNeeded
)
3967 SetLastError(ERROR_MORE_DATA
);
3968 *pcbStructInfo
= bytesNeeded
;
3973 CRYPT_DATA_BLOB
*blob
;
3975 *pcbStructInfo
= bytesNeeded
;
3976 blob
= pvStructInfo
;
3977 blob
->cbData
= dataLen
;
3978 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3979 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3982 assert(blob
->pbData
);
3984 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3992 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3993 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3994 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3998 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3999 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4007 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4010 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
4012 SetLastError(CRYPT_E_ASN1_BADTAG
);
4015 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4016 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4019 *pcbStructInfo
= bytesNeeded
;
4020 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4021 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4023 CRYPT_DATA_BLOB
*blob
;
4025 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4026 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4027 blob
= pvStructInfo
;
4028 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4029 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4030 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4031 &bytesNeeded
, NULL
);
4037 SetLastError(STATUS_ACCESS_VIOLATION
);
4044 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4045 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4048 DWORD bytesNeeded
, dataLen
;
4049 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4051 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4052 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4054 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4056 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4057 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4059 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4061 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4063 *pcbStructInfo
= bytesNeeded
;
4064 else if (*pcbStructInfo
< bytesNeeded
)
4066 *pcbStructInfo
= bytesNeeded
;
4067 SetLastError(ERROR_MORE_DATA
);
4072 CRYPT_BIT_BLOB
*blob
;
4074 *pcbStructInfo
= bytesNeeded
;
4075 blob
= pvStructInfo
;
4076 blob
->cbData
= dataLen
- 1;
4077 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4078 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4080 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4084 assert(blob
->pbData
);
4087 BYTE mask
= 0xff << blob
->cUnusedBits
;
4089 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4091 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4099 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4100 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4101 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4105 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4106 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4114 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4117 else if (pbEncoded
[0] != ASN_BITSTRING
)
4119 SetLastError(CRYPT_E_ASN1_BADTAG
);
4122 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4123 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4126 *pcbStructInfo
= bytesNeeded
;
4127 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4128 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4130 CRYPT_BIT_BLOB
*blob
;
4132 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4133 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4134 blob
= pvStructInfo
;
4135 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4136 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4137 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4138 &bytesNeeded
, NULL
);
4144 SetLastError(STATUS_ACCESS_VIOLATION
);
4148 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4152 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4153 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4154 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4157 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
4158 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
4159 DWORD size
= sizeof(buf
);
4161 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
4162 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
4167 *pcbStructInfo
= sizeof(int);
4168 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4172 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
4174 /* initialize to a negative value to sign-extend */
4179 for (i
= 0; i
< blob
->cbData
; i
++)
4182 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
4184 memcpy(pvStructInfo
, &val
, sizeof(int));
4187 else if (GetLastError() == ERROR_MORE_DATA
)
4188 SetLastError(CRYPT_E_ASN1_LARGE
);
4192 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4193 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4194 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4204 SetLastError(CRYPT_E_ASN1_EOD
);
4207 else if (pbEncoded
[0] != ASN_INTEGER
)
4209 SetLastError(CRYPT_E_ASN1_BADTAG
);
4213 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4214 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4218 *pcbStructInfo
= bytesNeeded
;
4219 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4220 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4222 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4223 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4224 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4225 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4226 &bytesNeeded
, NULL
);
4232 SetLastError(STATUS_ACCESS_VIOLATION
);
4239 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4240 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4244 DWORD bytesNeeded
, dataLen
;
4246 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4248 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4250 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4252 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4254 *pcbStructInfo
= bytesNeeded
;
4255 else if (*pcbStructInfo
< bytesNeeded
)
4257 *pcbStructInfo
= bytesNeeded
;
4258 SetLastError(ERROR_MORE_DATA
);
4263 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4265 *pcbStructInfo
= bytesNeeded
;
4266 blob
->cbData
= dataLen
;
4267 assert(blob
->pbData
);
4272 for (i
= 0; i
< blob
->cbData
; i
++)
4274 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4283 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4284 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4285 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4293 if (pbEncoded
[0] != ASN_INTEGER
)
4295 SetLastError(CRYPT_E_ASN1_BADTAG
);
4299 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4300 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4304 *pcbStructInfo
= bytesNeeded
;
4305 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4306 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4308 CRYPT_INTEGER_BLOB
*blob
;
4310 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4311 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4312 blob
= pvStructInfo
;
4313 blob
->pbData
= (BYTE
*)pvStructInfo
+
4314 sizeof(CRYPT_INTEGER_BLOB
);
4315 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4316 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4317 &bytesNeeded
, NULL
);
4323 SetLastError(STATUS_ACCESS_VIOLATION
);
4330 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4331 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4336 if (pbEncoded
[0] == ASN_INTEGER
)
4338 DWORD bytesNeeded
, dataLen
;
4340 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4342 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4345 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4346 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4348 *pcbStructInfo
= bytesNeeded
;
4349 else if (*pcbStructInfo
< bytesNeeded
)
4351 *pcbStructInfo
= bytesNeeded
;
4352 SetLastError(ERROR_MORE_DATA
);
4357 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4359 *pcbStructInfo
= bytesNeeded
;
4360 blob
->cbData
= dataLen
;
4361 assert(blob
->pbData
);
4362 /* remove leading zero byte if it exists */
4363 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4372 for (i
= 0; i
< blob
->cbData
; i
++)
4374 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4383 SetLastError(CRYPT_E_ASN1_BADTAG
);
4389 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4390 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4391 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4399 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4400 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4403 *pcbStructInfo
= bytesNeeded
;
4404 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4405 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4407 CRYPT_INTEGER_BLOB
*blob
;
4409 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4410 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4411 blob
= pvStructInfo
;
4412 blob
->pbData
= (BYTE
*)pvStructInfo
+
4413 sizeof(CRYPT_INTEGER_BLOB
);
4414 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4415 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4416 &bytesNeeded
, NULL
);
4422 SetLastError(STATUS_ACCESS_VIOLATION
);
4429 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4430 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4431 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4437 *pcbStructInfo
= sizeof(int);
4442 if (pbEncoded
[0] == ASN_ENUMERATED
)
4444 unsigned int val
= 0, i
;
4448 SetLastError(CRYPT_E_ASN1_EOD
);
4451 else if (pbEncoded
[1] == 0)
4453 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4458 /* A little strange looking, but we have to accept a sign byte:
4459 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4460 * assuming a small length is okay here, it has to be in short
4463 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4465 SetLastError(CRYPT_E_ASN1_LARGE
);
4468 for (i
= 0; i
< pbEncoded
[1]; i
++)
4471 val
|= pbEncoded
[2 + i
];
4473 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4474 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4476 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4477 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4478 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4484 SetLastError(CRYPT_E_ASN1_BADTAG
);
4490 SetLastError(STATUS_ACCESS_VIOLATION
);
4497 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4500 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4505 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4507 if (!isdigit(*(pbEncoded))) \
4509 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4515 (word) += *(pbEncoded)++ - '0'; \
4520 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4521 SYSTEMTIME
*sysTime
)
4525 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4527 WORD hours
, minutes
= 0;
4528 BYTE sign
= *pbEncoded
++;
4531 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4532 if (ret
&& hours
>= 24)
4534 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4539 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4540 if (ret
&& minutes
>= 60)
4542 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4550 sysTime
->wHour
+= hours
;
4551 sysTime
->wMinute
+= minutes
;
4555 if (hours
> sysTime
->wHour
)
4558 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4561 sysTime
->wHour
-= hours
;
4562 if (minutes
> sysTime
->wMinute
)
4565 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4568 sysTime
->wMinute
-= minutes
;
4575 #define MIN_ENCODED_TIME_LENGTH 10
4577 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4578 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4583 if (pbEncoded
[0] == ASN_UTCTIME
)
4586 SetLastError(CRYPT_E_ASN1_EOD
);
4587 else if (pbEncoded
[1] > 0x7f)
4589 /* long-form date strings really can't be valid */
4590 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4594 SYSTEMTIME sysTime
= { 0 };
4595 BYTE len
= pbEncoded
[1];
4597 if (len
< MIN_ENCODED_TIME_LENGTH
)
4598 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4603 *pcbDecoded
= 2 + len
;
4605 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4606 if (sysTime
.wYear
>= 50)
4607 sysTime
.wYear
+= 1900;
4609 sysTime
.wYear
+= 2000;
4610 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4611 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4612 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4613 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4616 if (len
>= 2 && isdigit(*pbEncoded
) &&
4617 isdigit(*(pbEncoded
+ 1)))
4618 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4620 else if (isdigit(*pbEncoded
))
4621 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4624 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4630 *pcbStructInfo
= sizeof(FILETIME
);
4631 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4633 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4639 SetLastError(CRYPT_E_ASN1_BADTAG
);
4643 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4644 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4645 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4653 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4654 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4658 *pcbStructInfo
= bytesNeeded
;
4659 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4660 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4662 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4663 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4664 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4665 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4666 &bytesNeeded
, NULL
);
4672 SetLastError(STATUS_ACCESS_VIOLATION
);
4678 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4679 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4684 if (pbEncoded
[0] == ASN_GENERALTIME
)
4687 SetLastError(CRYPT_E_ASN1_EOD
);
4688 else if (pbEncoded
[1] > 0x7f)
4690 /* long-form date strings really can't be valid */
4691 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4695 BYTE len
= pbEncoded
[1];
4697 if (len
< MIN_ENCODED_TIME_LENGTH
)
4698 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4701 SYSTEMTIME sysTime
= { 0 };
4705 *pcbDecoded
= 2 + len
;
4707 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4708 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4709 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4710 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4713 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4716 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4718 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4725 /* workaround macro weirdness */
4726 digits
= min(len
, 3);
4727 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4728 sysTime
.wMilliseconds
);
4731 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4737 *pcbStructInfo
= sizeof(FILETIME
);
4738 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4740 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4746 SetLastError(CRYPT_E_ASN1_BADTAG
);
4750 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4751 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4755 InternalDecodeFunc decode
= NULL
;
4757 if (pbEncoded
[0] == ASN_UTCTIME
)
4758 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4759 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4760 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4762 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4763 pcbStructInfo
, pcbDecoded
);
4766 SetLastError(CRYPT_E_ASN1_BADTAG
);
4772 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4773 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4774 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4782 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4783 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4787 *pcbStructInfo
= bytesNeeded
;
4788 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4789 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4791 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4792 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4793 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4794 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4795 &bytesNeeded
, NULL
);
4801 SetLastError(STATUS_ACCESS_VIOLATION
);
4808 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4809 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4810 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4816 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4818 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4820 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4825 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4826 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4828 ptr
= pbEncoded
+ 1 + lenBytes
;
4829 remainingLen
= dataLen
;
4830 while (ret
&& remainingLen
)
4834 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4837 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4839 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4840 ptr
+= 1 + nextLenBytes
+ nextLen
;
4841 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4842 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4843 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4849 CRYPT_SEQUENCE_OF_ANY
*seq
;
4854 *pcbStructInfo
= bytesNeeded
;
4855 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4856 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4858 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4859 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4861 seq
->cValue
= cValue
;
4862 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4864 nextPtr
= (BYTE
*)seq
->rgValue
+
4865 cValue
* sizeof(CRYPT_DER_BLOB
);
4866 ptr
= pbEncoded
+ 1 + lenBytes
;
4867 remainingLen
= dataLen
;
4869 while (ret
&& remainingLen
)
4873 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4876 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4878 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4880 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4881 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4884 seq
->rgValue
[i
].pbData
= nextPtr
;
4885 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4887 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4889 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4890 ptr
+= 1 + nextLenBytes
+ nextLen
;
4900 SetLastError(CRYPT_E_ASN1_BADTAG
);
4906 SetLastError(STATUS_ACCESS_VIOLATION
);
4913 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4914 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4919 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4921 DWORD bytesNeeded
, dataLen
;
4923 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4925 struct AsnArrayDescriptor arrayDesc
= {
4926 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
4927 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4928 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4929 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4934 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4935 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4936 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
4937 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4938 * as the sizeof(struct GenericArray), so don't include it in the
4939 * total bytes needed.
4941 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4942 sizeof(CERT_ALT_NAME_INFO
);
4945 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4947 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4949 *pcbStructInfo
= bytesNeeded
;
4950 else if (*pcbStructInfo
< bytesNeeded
)
4952 *pcbStructInfo
= bytesNeeded
;
4953 SetLastError(ERROR_MORE_DATA
);
4958 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4960 *pcbStructInfo
= bytesNeeded
;
4963 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4964 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4965 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4966 0, NULL
, &name
->u
.FullName
, &nameLen
, NULL
,
4967 name
->u
.FullName
.rgAltEntry
);
4970 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4976 SetLastError(CRYPT_E_ASN1_BADTAG
);
4982 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4983 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4985 struct AsnDecodeSequenceItem items
[] = {
4986 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4987 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4988 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4989 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4990 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4991 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4992 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4993 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4994 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4995 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4997 CRL_DIST_POINT
*point
= pvStructInfo
;
5000 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5001 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5002 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5006 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5007 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5008 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5012 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5013 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5017 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5018 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5019 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5021 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
5022 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
5026 SetLastError(STATUS_ACCESS_VIOLATION
);
5033 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5034 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5035 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5039 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5040 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5044 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5045 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5047 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
5048 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
5052 SetLastError(STATUS_ACCESS_VIOLATION
);
5059 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5060 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5061 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5065 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5066 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5070 struct AsnDecodeSequenceItem items
[] = {
5071 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5072 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5073 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5074 offsetof(CRL_ISSUING_DIST_POINT
,
5075 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5076 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5077 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5079 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5080 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5082 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5083 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5084 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5085 OnlySomeReasonFlags
.pbData
), 0 },
5086 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5087 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5090 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5091 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5092 pcbStructInfo
, NULL
, NULL
);
5096 SetLastError(STATUS_ACCESS_VIOLATION
);
5103 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5104 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5109 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5110 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5114 SetLastError(CRYPT_E_ASN1_EOD
);
5117 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5119 SetLastError(CRYPT_E_ASN1_BADTAG
);
5122 /* The BOOL is implicit: if the integer is present, then it's TRUE */
5123 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5124 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
5126 if (ret
&& pvStructInfo
)
5127 *(BOOL
*)pvStructInfo
= TRUE
;
5128 TRACE("returning %d\n", ret
);
5132 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5133 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5137 struct AsnDecodeSequenceItem items
[] = {
5138 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5139 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5140 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5141 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5142 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5143 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5144 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
5147 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5149 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5150 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5152 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5153 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5154 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5157 TRACE("%d\n", *pcbDecoded
);
5158 if (*pcbDecoded
< cbEncoded
)
5159 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5160 *(pbEncoded
+ *pcbDecoded
+ 1));
5162 TRACE("returning %d\n", ret
);
5166 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5167 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5171 struct AsnArrayDescriptor arrayDesc
= { 0,
5172 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5173 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5176 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5177 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5179 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5180 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5182 bytesNeeded
+= MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
,
5183 cPermittedSubtree
, cExcludedSubtree
);
5185 *pcbStructInfo
= bytesNeeded
;
5186 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5187 pcbStructInfo
, bytesNeeded
)))
5189 CERT_NAME_CONSTRAINTS_INFO
*info
= (CERT_NAME_CONSTRAINTS_INFO
*)
5190 ((BYTE
*)pvStructInfo
-
5191 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
));
5193 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5194 &info
->cPermittedSubtree
, info
->rgPermittedSubtree
, &bytesNeeded
,
5201 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5202 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5206 struct AsnArrayDescriptor arrayDesc
= { 0,
5207 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5208 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5211 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5212 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5214 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5215 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5217 bytesNeeded
+= FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
,
5220 *pcbStructInfo
= bytesNeeded
;
5221 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5222 pcbStructInfo
, bytesNeeded
)))
5224 CERT_NAME_CONSTRAINTS_INFO
*info
= (CERT_NAME_CONSTRAINTS_INFO
*)
5225 ((BYTE
*)pvStructInfo
-
5226 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
));
5228 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5229 &info
->cExcludedSubtree
, info
->rgExcludedSubtree
, &bytesNeeded
,
5236 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5237 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5238 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5242 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5243 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5247 struct AsnDecodeSequenceItem items
[] = {
5248 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5249 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5250 CRYPT_AsnDecodePermittedSubtree
,
5251 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5252 cExcludedSubtree
), TRUE
, TRUE
,
5253 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5254 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5255 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5256 CRYPT_AsnDecodeExcludedSubtree
,
5257 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5259 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5262 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5263 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5264 pcbStructInfo
, NULL
, NULL
);
5268 SetLastError(STATUS_ACCESS_VIOLATION
);
5274 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5275 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5279 struct AsnDecodeSequenceItem items
[] = {
5280 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5281 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5283 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5284 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5285 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5287 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5289 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5290 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5292 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5293 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5294 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5295 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5297 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5300 TRACE("returning %d\n", ret
);
5304 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5305 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5308 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5309 struct AsnDecodeSequenceItem items
[] = {
5310 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5311 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5312 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5313 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5314 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5315 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5316 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5317 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5318 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5319 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5320 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5321 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5322 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5323 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5324 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5325 HashEncryptionAlgorithm
.pszObjId
), 0 },
5326 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5327 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5328 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5329 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5330 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5331 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5332 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5336 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5337 pvStructInfo
, *pcbStructInfo
);
5339 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5340 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5341 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5345 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5346 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5347 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5351 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5352 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5356 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5357 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5358 if (ret
&& pvStructInfo
)
5360 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5361 pcbStructInfo
, *pcbStructInfo
);
5364 CMSG_SIGNER_INFO
*info
;
5366 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5367 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5368 info
= pvStructInfo
;
5369 info
->Issuer
.pbData
= ((BYTE
*)info
+
5370 sizeof(CMSG_SIGNER_INFO
));
5371 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5372 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5373 pcbStructInfo
, NULL
);
5379 SetLastError(STATUS_ACCESS_VIOLATION
);
5382 TRACE("returning %d\n", ret
);
5386 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5387 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5391 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
5392 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5395 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5396 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5398 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5399 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5401 bytesNeeded
+= MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
);
5403 *pcbStructInfo
= bytesNeeded
;
5404 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5405 pcbStructInfo
, bytesNeeded
)))
5407 CRYPT_SIGNED_INFO
*info
= (CRYPT_SIGNED_INFO
*)
5408 ((BYTE
*)pvStructInfo
- offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
));
5410 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5411 &info
->cCertEncoded
, info
->rgCertEncoded
, &bytesNeeded
,
5418 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5419 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5423 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
5424 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5427 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5428 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5430 if ((ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5431 NULL
, NULL
, &bytesNeeded
, pcbDecoded
)))
5433 bytesNeeded
+= MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
);
5435 *pcbStructInfo
= bytesNeeded
;
5436 else if ((ret
= CRYPT_DecodeEnsureSpace(0, NULL
, pvStructInfo
,
5437 pcbStructInfo
, bytesNeeded
)))
5439 CRYPT_SIGNED_INFO
*info
= (CRYPT_SIGNED_INFO
*)
5440 ((BYTE
*)pvStructInfo
- offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
));
5442 ret
= CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc
, pbEncoded
, cbEncoded
,
5443 &info
->cCrlEncoded
, info
->rgCrlEncoded
, &bytesNeeded
,
5450 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5451 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5454 CERT_ID
*id
= pvStructInfo
;
5457 if (*pbEncoded
== ASN_SEQUENCEOF
)
5459 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5460 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5464 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5465 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5466 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5467 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5469 *pcbStructInfo
= sizeof(CERT_ID
);
5472 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5474 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5475 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5479 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5480 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5481 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5482 sizeof(CRYPT_DATA_BLOB
);
5484 *pcbStructInfo
= sizeof(CERT_ID
);
5488 SetLastError(CRYPT_E_ASN1_BADTAG
);
5492 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5493 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5496 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5497 struct AsnDecodeSequenceItem items
[] = {
5498 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5499 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5500 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5501 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5502 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5503 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5504 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5505 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5506 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5507 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5508 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5509 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5510 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5511 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5512 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5513 HashEncryptionAlgorithm
.pszObjId
), 0 },
5514 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5515 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5516 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5517 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5518 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5519 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5520 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5524 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5525 pvStructInfo
, *pcbStructInfo
);
5527 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5528 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5529 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5533 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5534 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5535 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5539 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5540 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5544 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5545 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5546 if (ret
&& pvStructInfo
)
5548 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5549 pcbStructInfo
, *pcbStructInfo
);
5552 CMSG_CMS_SIGNER_INFO
*info
;
5554 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5555 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5556 info
= pvStructInfo
;
5557 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5558 sizeof(CMSG_CMS_SIGNER_INFO
));
5559 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5560 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5561 pcbStructInfo
, NULL
);
5567 SetLastError(STATUS_ACCESS_VIOLATION
);
5570 TRACE("returning %d\n", ret
);
5574 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5575 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5578 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5579 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5580 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5581 struct GenericArray
*array
= pvStructInfo
;
5583 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5584 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5586 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
5587 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
5588 array
? array
->rgItems
: NULL
);
5592 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5593 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5594 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5597 struct AsnDecodeSequenceItem items
[] = {
5598 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5599 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5600 /* Placeholder for the hash algorithms - redundant with those in the
5601 * signers, so just ignore them.
5603 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5604 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5605 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5606 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5607 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5608 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5609 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5610 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5611 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5612 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5613 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5614 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5615 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5616 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
5617 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5620 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5621 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5623 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5624 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5626 TRACE("returning %d\n", ret
);
5630 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5631 LPCSTR lpszStructType
)
5633 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5635 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5636 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5638 SetLastError(ERROR_FILE_NOT_FOUND
);
5641 if (!HIWORD(lpszStructType
))
5643 switch (LOWORD(lpszStructType
))
5645 case LOWORD(X509_CERT
):
5646 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5648 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5649 decodeFunc
= CRYPT_AsnDecodeCert
;
5651 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5652 decodeFunc
= CRYPT_AsnDecodeCRL
;
5654 case LOWORD(X509_EXTENSIONS
):
5655 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5657 case LOWORD(X509_NAME_VALUE
):
5658 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5660 case LOWORD(X509_NAME
):
5661 decodeFunc
= CRYPT_AsnDecodeName
;
5663 case LOWORD(X509_PUBLIC_KEY_INFO
):
5664 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5666 case LOWORD(X509_AUTHORITY_KEY_ID
):
5667 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5669 case LOWORD(X509_ALTERNATE_NAME
):
5670 decodeFunc
= CRYPT_AsnDecodeAltName
;
5672 case LOWORD(X509_BASIC_CONSTRAINTS
):
5673 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5675 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5676 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5678 case LOWORD(X509_CERT_POLICIES
):
5679 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5681 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5682 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5684 case LOWORD(X509_UNICODE_NAME
):
5685 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5687 case LOWORD(PKCS_ATTRIBUTE
):
5688 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5690 case LOWORD(X509_UNICODE_NAME_VALUE
):
5691 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5693 case LOWORD(X509_OCTET_STRING
):
5694 decodeFunc
= CRYPT_AsnDecodeOctets
;
5696 case LOWORD(X509_BITS
):
5697 case LOWORD(X509_KEY_USAGE
):
5698 decodeFunc
= CRYPT_AsnDecodeBits
;
5700 case LOWORD(X509_INTEGER
):
5701 decodeFunc
= CRYPT_AsnDecodeInt
;
5703 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5704 decodeFunc
= CRYPT_AsnDecodeInteger
;
5706 case LOWORD(X509_MULTI_BYTE_UINT
):
5707 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5709 case LOWORD(X509_ENUMERATED
):
5710 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5712 case LOWORD(X509_CHOICE_OF_TIME
):
5713 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5715 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5716 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5718 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5719 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5721 case LOWORD(PKCS_CONTENT_INFO
):
5722 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5724 case LOWORD(X509_SEQUENCE_OF_ANY
):
5725 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5727 case LOWORD(PKCS_UTC_TIME
):
5728 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5730 case LOWORD(X509_CRL_DIST_POINTS
):
5731 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5733 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5734 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5736 case LOWORD(PKCS_CTL
):
5737 decodeFunc
= CRYPT_AsnDecodeCTL
;
5739 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5740 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5742 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5743 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5745 case LOWORD(PKCS_ATTRIBUTES
):
5746 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5748 case LOWORD(X509_ISSUING_DIST_POINT
):
5749 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5751 case LOWORD(X509_NAME_CONSTRAINTS
):
5752 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5754 case LOWORD(PKCS7_SIGNER_INFO
):
5755 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5757 case LOWORD(CMS_SIGNER_INFO
):
5758 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5762 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5763 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5764 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5765 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5766 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5767 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5768 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5769 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5770 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5771 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5772 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5773 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5774 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5775 decodeFunc
= CRYPT_AsnDecodeBits
;
5776 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5777 decodeFunc
= CRYPT_AsnDecodeOctets
;
5778 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5779 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5780 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5781 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5782 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5783 decodeFunc
= CRYPT_AsnDecodeAltName
;
5784 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5785 decodeFunc
= CRYPT_AsnDecodeAltName
;
5786 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5787 decodeFunc
= CRYPT_AsnDecodeAltName
;
5788 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5789 decodeFunc
= CRYPT_AsnDecodeAltName
;
5790 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5791 decodeFunc
= CRYPT_AsnDecodeAltName
;
5792 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5793 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5794 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5795 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5796 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5797 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5798 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5799 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5800 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5801 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5802 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5803 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5804 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5805 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5806 else if (!strcmp(lpszStructType
, szOID_CTL
))
5807 decodeFunc
= CRYPT_AsnDecodeCTL
;
5811 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5812 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5814 static HCRYPTOIDFUNCSET set
= NULL
;
5815 CryptDecodeObjectFunc decodeFunc
= NULL
;
5818 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5819 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5820 (void **)&decodeFunc
, hFunc
);
5824 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5825 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5827 static HCRYPTOIDFUNCSET set
= NULL
;
5828 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5831 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5832 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5833 (void **)&decodeFunc
, hFunc
);
5837 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5838 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5839 DWORD
*pcbStructInfo
)
5842 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5843 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5844 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5846 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5847 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5848 pvStructInfo
, pcbStructInfo
);
5850 if (!pvStructInfo
&& !pcbStructInfo
)
5852 SetLastError(ERROR_INVALID_PARAMETER
);
5855 if (cbEncoded
> MAX_ENCODED_LEN
)
5857 SetLastError(CRYPT_E_ASN1_LARGE
);
5861 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5864 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5865 debugstr_a(lpszStructType
));
5866 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5867 lpszStructType
, &hFunc
);
5868 if (!pCryptDecodeObject
)
5869 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5870 lpszStructType
, &hFunc
);
5872 if (pCryptDecodeObject
)
5873 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5874 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5875 else if (pCryptDecodeObjectEx
)
5876 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5877 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5878 pvStructInfo
, pcbStructInfo
);
5880 CryptFreeOIDFunctionAddress(hFunc
, 0);
5881 TRACE_(crypt
)("returning %d\n", ret
);
5885 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5886 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5887 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5890 CryptDecodeObjectExFunc decodeFunc
;
5891 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5893 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5894 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5895 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5897 if (!pvStructInfo
&& !pcbStructInfo
)
5899 SetLastError(ERROR_INVALID_PARAMETER
);
5902 if (cbEncoded
> MAX_ENCODED_LEN
)
5904 SetLastError(CRYPT_E_ASN1_LARGE
);
5908 SetLastError(NOERROR
);
5909 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5910 *(BYTE
**)pvStructInfo
= NULL
;
5911 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5914 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5915 debugstr_a(lpszStructType
));
5916 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5920 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5921 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5924 CryptDecodeObjectFunc pCryptDecodeObject
=
5925 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5927 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5928 * directly, as that could cause an infinite loop.
5930 if (pCryptDecodeObject
)
5932 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5934 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5935 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5936 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5937 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5938 ret
= pCryptDecodeObject(dwCertEncodingType
,
5939 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5940 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5943 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5944 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5948 CryptFreeOIDFunctionAddress(hFunc
, 0);
5949 TRACE_(crypt
)("returning %d\n", ret
);
5953 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
5957 TRACE_(crypt
)("(%p)\n", pPFX
);
5959 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5960 * version integer of length 1 (3 encoded byes) and at least one other
5961 * datum (two encoded bytes), plus at least two bytes for the outer
5962 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5964 if (pPFX
->cbData
< 7)
5966 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
5970 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
5972 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
5974 /* Need at least three bytes for the integer version */
5975 if (pPFX
->cbData
< 1 + lenLen
+ 3)
5977 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
5978 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
5979 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
5988 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
5991 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);