2 * Copyright 2005-2008 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
67 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
68 DWORD
, DWORD
, void *, DWORD
*);
69 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
70 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
76 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
78 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
82 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
88 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
92 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
93 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
94 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
97 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
99 /* Doesn't check the tag, assumes the caller does so */
100 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
101 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
102 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
103 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
104 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
105 * member has been initialized, doesn't do exception handling, and doesn't do
106 * memory allocation. Also doesn't check tag, assumes the caller has checked
109 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
113 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
114 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
116 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
117 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
120 /* Gets the number of length bytes from the given (leading) length byte */
121 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
123 /* Helper function to get the encoded length of the data starting at pbEncoded,
124 * where pbEncoded[0] is the tag. If the data are too short to contain a
125 * length or if the length is too large for cbEncoded, sets an appropriate
126 * error code and returns FALSE. If the encoded length is unknown due to
127 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
129 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
136 SetLastError(CRYPT_E_ASN1_CORRUPT
);
139 else if (pbEncoded
[1] <= 0x7f)
141 if (pbEncoded
[1] + 1 > cbEncoded
)
143 SetLastError(CRYPT_E_ASN1_EOD
);
152 else if (pbEncoded
[1] == 0x80)
154 *len
= CMSG_INDEFINITE_LENGTH
;
159 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
161 if (lenLen
> sizeof(DWORD
) + 1)
163 SetLastError(CRYPT_E_ASN1_LARGE
);
166 else if (lenLen
+ 2 > cbEncoded
)
168 SetLastError(CRYPT_E_ASN1_CORRUPT
);
181 if (out
+ lenLen
+ 1 > cbEncoded
)
183 SetLastError(CRYPT_E_ASN1_EOD
);
196 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
197 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
201 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
202 *len
== CMSG_INDEFINITE_LENGTH
)
204 SetLastError(CRYPT_E_ASN1_CORRUPT
);
210 /* Helper function to check *pcbStructInfo, set it to the required size, and
211 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
212 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
213 * pointer to the newly allocated memory.
215 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
216 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
221 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
223 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
224 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
226 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
227 if (!*(BYTE
**)pvStructInfo
)
230 *pcbStructInfo
= bytesNeeded
;
232 else if (*pcbStructInfo
< bytesNeeded
)
234 *pcbStructInfo
= bytesNeeded
;
235 SetLastError(ERROR_MORE_DATA
);
239 *pcbStructInfo
= bytesNeeded
;
243 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
245 if (pDecodePara
&& pDecodePara
->pfnFree
)
246 pDecodePara
->pfnFree(pv
);
251 /* Helper function to check *pcbStructInfo and set it to the required size.
252 * Assumes pvStructInfo is not NULL.
254 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
258 if (*pcbStructInfo
< bytesNeeded
)
260 *pcbStructInfo
= bytesNeeded
;
261 SetLastError(ERROR_MORE_DATA
);
266 *pcbStructInfo
= bytesNeeded
;
273 * The expected tag of the item. If tag is 0, decodeFunc is called
274 * regardless of the tag value seen.
276 * A sequence is decoded into a struct. The offset member is the
277 * offset of this item within that struct.
279 * The decoder function to use. If this is NULL, then the member isn't
280 * decoded, but minSize space is reserved for it.
282 * The minimum amount of space occupied after decoding. You must set this.
284 * If true, and the tag doesn't match the expected tag for this item,
285 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
286 * filled with 0 for this member.
287 * hasPointer, pointerOffset:
288 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
289 * the offset within the struct of the data pointer (or to the
290 * first data pointer, if more than one exist).
292 * Used by CRYPT_AsnDecodeSequence, not for your use.
294 struct AsnDecodeSequenceItem
298 InternalDecodeFunc decodeFunc
;
306 /* Decodes the items in a sequence, where the items are described in items,
307 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
308 * pvStructInfo. nextData is a pointer to the memory location at which the
309 * first decoded item with a dynamic pointer should point.
310 * Upon decoding, *cbDecoded is the total number of bytes decoded.
311 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
313 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
314 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
315 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
318 DWORD i
, decoded
= 0;
319 const BYTE
*ptr
= pbEncoded
;
321 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
322 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
324 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
326 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
330 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
331 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
333 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
335 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
337 DWORD itemEncodedLen
;
339 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
340 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
342 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
343 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
345 TRACE("Setting next pointer to %p\n",
347 *(BYTE
**)((BYTE
*)pvStructInfo
+
348 items
[i
].pointerOffset
) = nextData
;
350 if (items
[i
].decodeFunc
)
355 TRACE("decoding item %d\n", i
);
357 TRACE("sizing item %d\n", i
);
358 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
359 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
360 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
361 : NULL
, &items
[i
].size
, &itemDecoded
);
364 /* Account for alignment padding */
365 if (items
[i
].size
% sizeof(DWORD_PTR
))
366 items
[i
].size
+= sizeof(DWORD_PTR
) -
367 items
[i
].size
% sizeof(DWORD_PTR
);
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
);
381 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
383 if (itemDecoded
> itemEncodedLen
- 2 ||
384 *(ptr
+ itemDecoded
) != 0 ||
385 *(ptr
+ itemDecoded
+ 1) != 0)
387 TRACE("expected 0 TLV\n");
388 SetLastError(CRYPT_E_ASN1_CORRUPT
);
397 decoded
+= itemDecoded
;
398 TRACE("item %d: decoded %d bytes\n", i
,
403 else if (items
[i
].optional
&&
404 GetLastError() == CRYPT_E_ASN1_BADTAG
)
406 TRACE("skipping optional item %d\n", i
);
407 items
[i
].size
= items
[i
].minSize
;
408 SetLastError(NOERROR
);
412 TRACE("item %d failed: %08x\n", i
,
415 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
417 ERR("can't use indefinite length encoding without a decoder\n");
418 SetLastError(CRYPT_E_ASN1_CORRUPT
);
423 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
424 ptr
+= itemEncodedLen
;
425 decoded
+= itemEncodedLen
;
426 items
[i
].size
= items
[i
].minSize
;
429 else if (items
[i
].optional
)
431 TRACE("skipping optional item %d\n", i
);
432 items
[i
].size
= items
[i
].minSize
;
436 TRACE("item %d: tag %02x doesn't match expected %02x\n",
437 i
, ptr
[0], items
[i
].tag
);
438 SetLastError(CRYPT_E_ASN1_BADTAG
);
443 else if (items
[i
].optional
)
445 TRACE("missing optional item %d, skipping\n", i
);
446 items
[i
].size
= items
[i
].minSize
;
450 TRACE("not enough bytes for item %d, failing\n", i
);
451 SetLastError(CRYPT_E_ASN1_CORRUPT
);
456 *cbDecoded
= decoded
;
457 TRACE("returning %d\n", ret
);
461 /* This decodes an arbitrary sequence into a contiguous block of memory
462 * (basically, a struct.) Each element being decoded is described by a struct
463 * AsnDecodeSequenceItem, see above.
464 * startingPointer is an optional pointer to the first place where dynamic
465 * data will be stored. If you know the starting offset, you may pass it
466 * here. Otherwise, pass NULL, and one will be inferred from the items.
468 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
469 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
470 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
471 DWORD
*pcbDecoded
, void *startingPointer
)
475 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
476 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
481 SetLastError(CRYPT_E_ASN1_EOD
);
484 if (pbEncoded
[0] == ASN_SEQUENCE
)
488 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
490 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
491 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
492 BOOL indefinite
= FALSE
;
494 cbEncoded
-= 1 + lenBytes
;
495 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
500 else if (cbEncoded
< dataLen
)
502 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
504 SetLastError(CRYPT_E_ASN1_CORRUPT
);
509 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
510 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
511 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
513 if (cbDecoded
> cbEncoded
- 2)
515 /* Not enough space for 0 TLV */
516 SetLastError(CRYPT_E_ASN1_CORRUPT
);
519 else if (*(ptr
+ cbDecoded
) != 0 ||
520 *(ptr
+ cbDecoded
+ 1) != 0)
522 TRACE("expected 0 TLV\n");
523 SetLastError(CRYPT_E_ASN1_CORRUPT
);
530 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
532 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
534 SetLastError(CRYPT_E_ASN1_CORRUPT
);
539 DWORD i
, bytesNeeded
= 0, structSize
= 0;
541 for (i
= 0; i
< cItem
; i
++)
543 bytesNeeded
+= items
[i
].size
;
544 structSize
+= items
[i
].minSize
;
547 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
549 *pcbStructInfo
= bytesNeeded
;
550 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
551 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
555 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
556 pvStructInfo
= *(BYTE
**)pvStructInfo
;
558 nextData
= (BYTE
*)startingPointer
;
560 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
561 memset(pvStructInfo
, 0, structSize
);
562 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
563 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
565 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
566 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
573 SetLastError(CRYPT_E_ASN1_BADTAG
);
576 TRACE("returning %d (%08x)\n", ret
, GetLastError());
581 * The expected tag of the entire encoded array (usually a variant
582 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
583 * regardless of the tag seen.
585 * used to decode each item in the array
587 * is the minimum size of each decoded item
589 * indicates whether each item has a dynamic pointer
591 * indicates the offset within itemSize at which the pointer exists
593 struct AsnArrayDescriptor
596 InternalDecodeFunc decodeFunc
;
602 struct AsnArrayItemSize
608 /* Decodes an array of like types into a struct GenericArray.
609 * The layout and decoding of the array are described by a struct
610 * AsnArrayDescriptor.
612 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
613 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
614 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
615 DWORD
*pcbDecoded
, void *startingPointer
)
619 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
620 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
623 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
627 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
629 DWORD bytesNeeded
, cItems
= 0, decoded
;
630 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
631 /* There can be arbitrarily many items, but there is often only one.
633 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
635 decoded
= 1 + lenBytes
;
636 bytesNeeded
= sizeof(struct GenericArray
);
640 BOOL doneDecoding
= FALSE
;
642 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
644 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
651 SetLastError(CRYPT_E_ASN1_CORRUPT
);
658 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
662 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
664 /* Each item decoded may not tolerate extraneous bytes,
665 * so get the length of the next element if known.
667 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
668 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
670 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
671 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
673 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
677 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
678 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
683 if (itemSizes
!= &itemSize
)
684 itemSizes
= CryptMemRealloc(itemSizes
,
685 cItems
* sizeof(struct AsnArrayItemSize
));
690 cItems
* sizeof(struct AsnArrayItemSize
));
692 memcpy(itemSizes
, &itemSize
,
697 decoded
+= itemDecoded
;
698 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
699 itemSizes
[cItems
- 1].size
= size
;
712 *pcbDecoded
= decoded
;
714 *pcbStructInfo
= bytesNeeded
;
715 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
716 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
721 struct GenericArray
*array
;
723 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
724 pvStructInfo
= *(BYTE
**)pvStructInfo
;
725 array
= (struct GenericArray
*)pvStructInfo
;
726 array
->cItems
= cItems
;
728 array
->rgItems
= startingPointer
;
730 array
->rgItems
= (BYTE
*)array
+
731 sizeof(struct GenericArray
);
732 nextData
= array
->rgItems
+
733 array
->cItems
* arrayDesc
->itemSize
;
734 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
735 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
740 if (arrayDesc
->hasPointer
)
741 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
742 + arrayDesc
->pointerOffset
) = nextData
;
743 ret
= arrayDesc
->decodeFunc(ptr
,
744 itemSizes
[i
].encodedLen
,
745 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
746 array
->rgItems
+ i
* arrayDesc
->itemSize
,
747 &itemSizes
[i
].size
, &itemDecoded
);
750 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
754 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
755 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
758 if (itemSizes
!= &itemSize
)
759 CryptMemFree(itemSizes
);
764 SetLastError(CRYPT_E_ASN1_BADTAG
);
770 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
771 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
772 * to CRYPT_E_ASN1_CORRUPT.
773 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
776 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
777 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
782 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
784 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
785 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
787 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
788 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
791 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
793 *pcbStructInfo
= bytesNeeded
;
794 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
796 CRYPT_DER_BLOB
*blob
;
798 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
799 pvStructInfo
= *(BYTE
**)pvStructInfo
;
800 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
801 blob
->cbData
= 1 + lenBytes
+ dataLen
;
804 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
805 blob
->pbData
= (BYTE
*)pbEncoded
;
808 assert(blob
->pbData
);
809 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
814 SetLastError(CRYPT_E_ASN1_CORRUPT
);
822 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
823 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
824 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
829 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
830 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
832 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
835 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
836 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
838 if (ret
&& pvStructInfo
)
840 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
847 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
849 temp
= blob
->pbData
[i
];
850 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
851 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
855 TRACE("returning %d (%08x)\n", ret
, GetLastError());
859 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
860 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
861 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
865 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
866 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
870 struct AsnDecodeSequenceItem items
[] = {
871 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
872 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
873 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
874 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
875 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
876 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
877 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
878 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
879 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
880 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
883 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
884 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
885 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
886 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
887 pcbStructInfo
, NULL
, NULL
);
891 SetLastError(STATUS_ACCESS_VIOLATION
);
896 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
900 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
901 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
906 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
908 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
910 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
911 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
913 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
918 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
919 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
923 struct AsnDecodeSequenceItem items
[] = {
924 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
925 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
926 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
927 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
930 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
931 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
936 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
937 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
943 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
945 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
947 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
948 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
949 if (ret
&& pcbDecoded
)
950 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
955 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
956 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
957 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
960 struct AsnDecodeSequenceItem items
[] = {
961 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
962 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
963 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
964 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
965 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
966 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
967 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
968 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
969 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
970 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
972 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
973 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
975 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
976 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
978 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
979 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
980 FALSE
, TRUE
, offsetof(CERT_INFO
,
981 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
982 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
983 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
984 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
985 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
986 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
987 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
988 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
989 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
990 offsetof(CERT_INFO
, rgExtension
), 0 },
993 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
994 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
996 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
997 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
999 if (ret
&& pvStructInfo
)
1003 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1004 info
= *(CERT_INFO
**)pvStructInfo
;
1006 info
= (CERT_INFO
*)pvStructInfo
;
1007 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1008 !info
->Subject
.cbData
)
1010 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1011 /* Don't need to deallocate, because it should have failed on the
1012 * first pass (and no memory was allocated.)
1018 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1022 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1023 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1024 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1028 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1029 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1035 /* Unless told not to, first try to decode it as a signed cert. */
1036 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1038 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1040 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1041 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1042 (BYTE
*)&signedCert
, &size
);
1046 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1047 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1048 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1049 pvStructInfo
, pcbStructInfo
);
1050 LocalFree(signedCert
);
1053 /* Failing that, try it as an unsigned cert */
1057 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1058 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1059 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1064 SetLastError(STATUS_ACCESS_VIOLATION
);
1068 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1072 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1073 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1076 struct AsnDecodeSequenceItem items
[] = {
1077 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1078 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1079 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1080 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1081 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1082 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1083 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1084 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1086 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
1088 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1091 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1092 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1093 entry
? entry
->SerialNumber
.pbData
: NULL
);
1094 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1096 WARN("empty CRL entry serial number\n");
1097 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1103 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1104 * been set prior to calling.
1106 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1107 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1110 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1111 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1112 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1113 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1115 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1116 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1118 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1119 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1120 entries
? entries
->rgItems
: NULL
);
1121 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1125 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1126 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1127 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1129 struct AsnDecodeSequenceItem items
[] = {
1130 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1131 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1132 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1133 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1134 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1135 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1136 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1138 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1139 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1140 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1141 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1142 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1143 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1144 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1145 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1146 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1147 offsetof(CRL_INFO
, rgExtension
), 0 },
1151 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1152 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1154 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1155 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1158 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1162 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1163 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1164 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1168 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1169 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1175 /* Unless told not to, first try to decode it as a signed crl. */
1176 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1178 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1180 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1181 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1182 (BYTE
*)&signedCrl
, &size
);
1186 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1187 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1188 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1189 pvStructInfo
, pcbStructInfo
);
1190 LocalFree(signedCrl
);
1193 /* Failing that, try it as an unsigned crl */
1197 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1198 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1199 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1204 SetLastError(STATUS_ACCESS_VIOLATION
);
1208 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1212 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1213 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1218 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1219 pvStructInfo
, *pcbStructInfo
);
1221 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1223 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1224 DWORD bytesNeeded
= sizeof(LPSTR
);
1228 /* The largest possible string for the first two components
1229 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1234 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1235 pbEncoded
[1 + lenBytes
] / 40,
1236 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1238 bytesNeeded
+= strlen(firstTwo
) + 1;
1239 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1240 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1242 /* large enough for ".4000000" */
1246 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1253 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1256 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1263 snprintf(str
, sizeof(str
), ".%d", val
);
1264 bytesNeeded
+= strlen(str
);
1269 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1271 *pcbStructInfo
= bytesNeeded
;
1272 else if (*pcbStructInfo
< bytesNeeded
)
1274 *pcbStructInfo
= bytesNeeded
;
1275 SetLastError(ERROR_MORE_DATA
);
1283 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1286 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1287 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1289 pszObjId
+= strlen(pszObjId
);
1290 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1291 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1295 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1304 sprintf(pszObjId
, ".%d", val
);
1305 pszObjId
+= strlen(pszObjId
);
1309 *(LPSTR
*)pvStructInfo
= NULL
;
1310 *pcbStructInfo
= bytesNeeded
;
1316 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1317 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1321 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1322 pvStructInfo
, *pcbStructInfo
);
1324 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1325 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1326 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1329 SetLastError(CRYPT_E_ASN1_BADTAG
);
1335 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1338 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1339 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1341 struct AsnDecodeSequenceItem items
[] = {
1342 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1343 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1344 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1345 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1346 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1347 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1348 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1349 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1352 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1354 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1358 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1359 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1360 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1361 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1363 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1364 debugstr_a(ext
->pszObjId
));
1365 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1369 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
1370 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1374 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1375 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1376 offsetof(CERT_EXTENSION
, pszObjId
) };
1377 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1379 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1380 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1382 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1383 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1384 exts
? exts
->rgExtension
: NULL
);
1388 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1389 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1390 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1396 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1397 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1398 if (ret
&& pvStructInfo
)
1400 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1401 pcbStructInfo
, *pcbStructInfo
);
1404 CERT_EXTENSIONS
*exts
;
1406 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1407 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1408 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1409 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1410 sizeof(CERT_EXTENSIONS
));
1411 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1412 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1413 pcbStructInfo
, NULL
);
1419 SetLastError(STATUS_ACCESS_VIOLATION
);
1426 /* Warning: this assumes the address of value->Value.pbData is already set, in
1427 * order to avoid overwriting memory. (In some cases, it may change it, if it
1428 * doesn't copy anything to memory.) Be sure to set it correctly!
1430 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1431 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1436 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1438 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1440 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1441 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1443 switch (pbEncoded
[0])
1445 case ASN_OCTETSTRING
:
1446 valueType
= CERT_RDN_OCTET_STRING
;
1447 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1448 bytesNeeded
+= dataLen
;
1450 case ASN_NUMERICSTRING
:
1451 valueType
= CERT_RDN_NUMERIC_STRING
;
1452 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1453 bytesNeeded
+= dataLen
;
1455 case ASN_PRINTABLESTRING
:
1456 valueType
= CERT_RDN_PRINTABLE_STRING
;
1457 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1458 bytesNeeded
+= dataLen
;
1461 valueType
= CERT_RDN_IA5_STRING
;
1462 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1463 bytesNeeded
+= dataLen
;
1466 valueType
= CERT_RDN_T61_STRING
;
1467 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1468 bytesNeeded
+= dataLen
;
1470 case ASN_VIDEOTEXSTRING
:
1471 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1472 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1473 bytesNeeded
+= dataLen
;
1475 case ASN_GRAPHICSTRING
:
1476 valueType
= CERT_RDN_GRAPHIC_STRING
;
1477 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1478 bytesNeeded
+= dataLen
;
1480 case ASN_VISIBLESTRING
:
1481 valueType
= CERT_RDN_VISIBLE_STRING
;
1482 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1483 bytesNeeded
+= dataLen
;
1485 case ASN_GENERALSTRING
:
1486 valueType
= CERT_RDN_GENERAL_STRING
;
1487 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1488 bytesNeeded
+= dataLen
;
1490 case ASN_UNIVERSALSTRING
:
1491 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1492 SetLastError(CRYPT_E_ASN1_BADTAG
);
1495 valueType
= CERT_RDN_BMP_STRING
;
1496 bytesNeeded
+= dataLen
;
1498 case ASN_UTF8STRING
:
1499 valueType
= CERT_RDN_UTF8_STRING
;
1500 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1501 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1504 SetLastError(CRYPT_E_ASN1_BADTAG
);
1509 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1511 *pcbStructInfo
= bytesNeeded
;
1512 else if (*pcbStructInfo
< bytesNeeded
)
1514 *pcbStructInfo
= bytesNeeded
;
1515 SetLastError(ERROR_MORE_DATA
);
1520 *pcbStructInfo
= bytesNeeded
;
1521 value
->dwValueType
= valueType
;
1526 assert(value
->Value
.pbData
);
1527 switch (pbEncoded
[0])
1529 case ASN_OCTETSTRING
:
1530 case ASN_NUMERICSTRING
:
1531 case ASN_PRINTABLESTRING
:
1534 case ASN_VIDEOTEXSTRING
:
1535 case ASN_GRAPHICSTRING
:
1536 case ASN_VISIBLESTRING
:
1537 case ASN_GENERALSTRING
:
1538 value
->Value
.cbData
= dataLen
;
1541 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1542 memcpy(value
->Value
.pbData
,
1543 pbEncoded
+ 1 + lenBytes
, dataLen
);
1545 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1551 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1553 value
->Value
.cbData
= dataLen
;
1554 for (i
= 0; i
< dataLen
/ 2; i
++)
1555 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1556 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1559 case ASN_UTF8STRING
:
1561 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1563 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1564 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1565 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1572 value
->Value
.cbData
= 0;
1573 value
->Value
.pbData
= NULL
;
1580 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1581 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1582 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1588 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1589 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1590 if (ret
&& pvStructInfo
)
1592 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1593 pcbStructInfo
, *pcbStructInfo
);
1596 CERT_NAME_VALUE
*value
;
1598 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1599 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1600 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1601 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1602 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1603 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1604 pcbStructInfo
, NULL
);
1610 SetLastError(STATUS_ACCESS_VIOLATION
);
1617 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1618 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1623 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1625 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1627 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1628 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1630 switch (pbEncoded
[0])
1632 case ASN_NUMERICSTRING
:
1633 valueType
= CERT_RDN_NUMERIC_STRING
;
1634 bytesNeeded
+= dataLen
* 2;
1636 case ASN_PRINTABLESTRING
:
1637 valueType
= CERT_RDN_PRINTABLE_STRING
;
1638 bytesNeeded
+= dataLen
* 2;
1641 valueType
= CERT_RDN_IA5_STRING
;
1642 bytesNeeded
+= dataLen
* 2;
1645 valueType
= CERT_RDN_T61_STRING
;
1646 bytesNeeded
+= dataLen
* 2;
1648 case ASN_VIDEOTEXSTRING
:
1649 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1650 bytesNeeded
+= dataLen
* 2;
1652 case ASN_GRAPHICSTRING
:
1653 valueType
= CERT_RDN_GRAPHIC_STRING
;
1654 bytesNeeded
+= dataLen
* 2;
1656 case ASN_VISIBLESTRING
:
1657 valueType
= CERT_RDN_VISIBLE_STRING
;
1658 bytesNeeded
+= dataLen
* 2;
1660 case ASN_GENERALSTRING
:
1661 valueType
= CERT_RDN_GENERAL_STRING
;
1662 bytesNeeded
+= dataLen
* 2;
1664 case ASN_UNIVERSALSTRING
:
1665 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1666 bytesNeeded
+= dataLen
/ 2;
1669 valueType
= CERT_RDN_BMP_STRING
;
1670 bytesNeeded
+= dataLen
;
1672 case ASN_UTF8STRING
:
1673 valueType
= CERT_RDN_UTF8_STRING
;
1674 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1675 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1678 SetLastError(CRYPT_E_ASN1_BADTAG
);
1683 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1685 *pcbStructInfo
= bytesNeeded
;
1686 else if (*pcbStructInfo
< bytesNeeded
)
1688 *pcbStructInfo
= bytesNeeded
;
1689 SetLastError(ERROR_MORE_DATA
);
1694 *pcbStructInfo
= bytesNeeded
;
1695 value
->dwValueType
= valueType
;
1699 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1701 assert(value
->Value
.pbData
);
1702 switch (pbEncoded
[0])
1704 case ASN_NUMERICSTRING
:
1705 case ASN_PRINTABLESTRING
:
1708 case ASN_VIDEOTEXSTRING
:
1709 case ASN_GRAPHICSTRING
:
1710 case ASN_VISIBLESTRING
:
1711 case ASN_GENERALSTRING
:
1712 value
->Value
.cbData
= dataLen
* 2;
1713 for (i
= 0; i
< dataLen
; i
++)
1714 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1716 case ASN_UNIVERSALSTRING
:
1717 value
->Value
.cbData
= dataLen
/ 2;
1718 for (i
= 0; i
< dataLen
/ 4; i
++)
1719 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1720 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1723 value
->Value
.cbData
= dataLen
;
1724 for (i
= 0; i
< dataLen
/ 2; i
++)
1725 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1726 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1728 case ASN_UTF8STRING
:
1729 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1730 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1731 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1737 value
->Value
.cbData
= 0;
1738 value
->Value
.pbData
= NULL
;
1745 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1746 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1747 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1753 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1754 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1755 if (ret
&& pvStructInfo
)
1757 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1758 pcbStructInfo
, *pcbStructInfo
);
1761 CERT_NAME_VALUE
*value
;
1763 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1764 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1765 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1766 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1767 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1768 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1769 pcbStructInfo
, NULL
);
1775 SetLastError(STATUS_ACCESS_VIOLATION
);
1782 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1783 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1786 struct AsnDecodeSequenceItem items
[] = {
1787 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1788 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1789 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1790 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1791 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1792 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1794 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1796 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1797 pvStructInfo
, *pcbStructInfo
);
1800 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1801 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1802 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1803 attr
? attr
->pszObjId
: NULL
);
1806 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1807 debugstr_a(attr
->pszObjId
));
1808 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1810 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1814 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1815 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1818 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1819 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1820 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1821 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1823 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1824 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1825 rdn
? rdn
->rgRDNAttr
: NULL
);
1829 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1830 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1831 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1837 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1838 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1839 offsetof(CERT_RDN
, rgRDNAttr
) };
1841 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1842 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1846 SetLastError(STATUS_ACCESS_VIOLATION
);
1853 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1854 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1858 struct AsnDecodeSequenceItem items
[] = {
1859 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1860 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1861 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1862 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1863 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1864 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1866 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1868 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1869 pvStructInfo
, *pcbStructInfo
);
1872 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1873 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1874 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1875 attr
? attr
->pszObjId
: NULL
);
1878 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1879 debugstr_a(attr
->pszObjId
));
1880 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1882 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1886 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1887 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1890 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1891 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1892 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1893 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1895 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1896 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1897 rdn
? rdn
->rgRDNAttr
: NULL
);
1901 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1902 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1903 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1909 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1910 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1911 offsetof(CERT_RDN
, rgRDNAttr
) };
1913 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1914 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1918 SetLastError(STATUS_ACCESS_VIOLATION
);
1925 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1928 BOOL ret
= TRUE
, done
= FALSE
;
1929 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
1931 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
1938 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
1941 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1943 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
1945 indefiniteNestingLevels
++;
1946 pbEncoded
+= 1 + lenBytes
;
1947 cbEncoded
-= 1 + lenBytes
;
1948 decoded
+= 1 + lenBytes
;
1949 TRACE("indefiniteNestingLevels = %d\n",
1950 indefiniteNestingLevels
);
1954 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
1955 indefiniteNestingLevels
)
1957 indefiniteNestingLevels
--;
1958 TRACE("indefiniteNestingLevels = %d\n",
1959 indefiniteNestingLevels
);
1961 pbEncoded
+= 1 + lenBytes
+ dataLen
;
1962 cbEncoded
-= 1 + lenBytes
+ dataLen
;
1963 decoded
+= 1 + lenBytes
+ dataLen
;
1964 if (!indefiniteNestingLevels
)
1968 } while (ret
&& !done
);
1969 /* If we haven't found all 0 TLVs, we haven't found the end */
1970 if (ret
&& indefiniteNestingLevels
)
1972 SetLastError(CRYPT_E_ASN1_EOD
);
1976 *pcbDecoded
= decoded
;
1977 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
1981 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
1982 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1986 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
1988 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1989 pvStructInfo
, *pcbStructInfo
);
1991 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
1993 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1994 bytesNeeded
+= encodedLen
;
1996 *pcbStructInfo
= bytesNeeded
;
1997 else if (*pcbStructInfo
< bytesNeeded
)
1999 SetLastError(ERROR_MORE_DATA
);
2000 *pcbStructInfo
= bytesNeeded
;
2005 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
2007 *pcbStructInfo
= bytesNeeded
;
2008 blob
->cbData
= encodedLen
;
2011 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2012 blob
->pbData
= (LPBYTE
)pbEncoded
;
2015 assert(blob
->pbData
);
2016 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2020 blob
->pbData
= NULL
;
2023 *pcbDecoded
= encodedLen
;
2028 static BOOL
CRYPT_DecodeDERArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2029 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2032 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
2033 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2034 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
2036 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2037 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2039 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2040 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2041 array
? array
->rgItems
: NULL
);
2045 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2046 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2049 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2050 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2051 CTL_USAGE
*usage
= (CTL_USAGE
*)pvStructInfo
;
2053 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2054 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2055 usage
? usage
->rgpszUsageIdentifier
: NULL
);
2059 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2060 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2062 struct AsnDecodeSequenceItem items
[] = {
2063 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2064 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2065 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2066 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2067 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
), FALSE
,
2068 TRUE
, offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2071 CTL_ENTRY
*entry
= (CTL_ENTRY
*)pvStructInfo
;
2073 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2076 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2077 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2078 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2082 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2083 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2086 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2087 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2088 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2089 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2091 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2092 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2094 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2095 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2096 entries
? entries
->rgItems
: NULL
);
2100 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2101 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2102 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2106 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2107 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2111 struct AsnDecodeSequenceItem items
[] = {
2112 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2113 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2114 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2115 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2116 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2117 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2118 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2119 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2120 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2121 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2122 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2123 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2124 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2126 { 0, offsetof(CTL_INFO
, NextUpdate
),
2127 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2129 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2130 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2131 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2132 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2133 CRYPT_AsnDecodeCTLEntries
, sizeof(struct GenericArray
),
2134 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2135 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2136 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
2137 offsetof(CTL_INFO
, rgExtension
), 0 },
2140 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2141 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2143 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2144 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2145 pcbStructInfo
, NULL
, NULL
);
2149 SetLastError(STATUS_ACCESS_VIOLATION
);
2155 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2156 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2160 struct AsnDecodeSequenceItem items
[] = {
2161 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2162 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2163 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2164 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2165 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2166 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2168 PCRYPT_SMIME_CAPABILITY capability
= (PCRYPT_SMIME_CAPABILITY
)pvStructInfo
;
2170 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2171 pvStructInfo
, *pcbStructInfo
);
2173 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2174 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2175 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2176 TRACE("returning %d\n", ret
);
2180 static BOOL
CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE
*pbEncoded
,
2181 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2184 struct AsnArrayDescriptor arrayDesc
= { 0,
2185 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2186 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2187 PCRYPT_SMIME_CAPABILITIES capabilities
=
2188 (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2191 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2192 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2193 capabilities
? capabilities
->rgCapability
: NULL
);
2197 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2198 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2199 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2203 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2204 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2211 SetLastError(CRYPT_E_ASN1_EOD
);
2212 else if (pbEncoded
[0] != ASN_SEQUENCEOF
)
2213 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2214 else if ((ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2215 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2219 *pcbStructInfo
= bytesNeeded
;
2220 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2221 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2223 PCRYPT_SMIME_CAPABILITIES capabilities
;
2225 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2226 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2227 capabilities
= (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2228 capabilities
->rgCapability
=
2229 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2230 sizeof(CRYPT_SMIME_CAPABILITIES
));
2231 ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2232 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2233 &bytesNeeded
, NULL
);
2239 SetLastError(STATUS_ACCESS_VIOLATION
);
2242 TRACE("returning %d\n", ret
);
2246 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2247 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2251 struct AsnDecodeSequenceItem items
[] = {
2252 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2253 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2254 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2255 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2256 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
2257 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2259 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2261 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2262 pvStructInfo
, *pcbStructInfo
);
2264 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2265 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2266 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2267 TRACE("returning %d\n", ret
);
2271 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2272 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2273 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2277 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2278 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2284 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2285 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2289 *pcbStructInfo
= bytesNeeded
;
2290 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2291 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2293 PCRYPT_ATTRIBUTE attr
;
2295 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2296 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2297 attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2298 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2299 sizeof(CRYPT_ATTRIBUTE
));
2300 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2301 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2308 SetLastError(STATUS_ACCESS_VIOLATION
);
2311 TRACE("returning %d\n", ret
);
2315 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2316 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2319 struct AsnArrayDescriptor arrayDesc
= { 0,
2320 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2321 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2322 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2325 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2326 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2331 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2332 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2333 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2337 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2338 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2345 SetLastError(CRYPT_E_ASN1_EOD
);
2346 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2347 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2348 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2349 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2353 *pcbStructInfo
= bytesNeeded
;
2354 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2355 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2357 PCRYPT_ATTRIBUTES attrs
;
2359 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2360 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2361 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2362 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2363 sizeof(CRYPT_ATTRIBUTES
));
2364 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2365 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2366 &bytesNeeded
, NULL
);
2372 SetLastError(STATUS_ACCESS_VIOLATION
);
2375 TRACE("returning %d\n", ret
);
2379 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2380 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2382 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
2383 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
2385 struct AsnDecodeSequenceItem items
[] = {
2386 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2387 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2388 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2389 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2390 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2391 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2394 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2395 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2397 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2398 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2399 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2400 if (ret
&& pvStructInfo
)
2402 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2403 debugstr_a(algo
->pszObjId
));
2408 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2409 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2413 struct AsnDecodeSequenceItem items
[] = {
2414 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2415 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2416 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2417 Algorithm
.pszObjId
) },
2418 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2419 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2420 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2422 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2424 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2425 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2426 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2430 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2431 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2432 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2440 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2441 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2444 *pcbStructInfo
= bytesNeeded
;
2445 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2446 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2448 PCERT_PUBLIC_KEY_INFO info
;
2450 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2451 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2452 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2453 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2454 sizeof(CERT_PUBLIC_KEY_INFO
);
2455 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2456 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2457 &bytesNeeded
, NULL
);
2463 SetLastError(STATUS_ACCESS_VIOLATION
);
2470 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2471 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2477 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2480 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2482 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2485 if (pbEncoded
[1] > 1)
2487 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2494 *pcbStructInfo
= sizeof(BOOL
);
2497 else if (*pcbStructInfo
< sizeof(BOOL
))
2499 *pcbStructInfo
= sizeof(BOOL
);
2500 SetLastError(ERROR_MORE_DATA
);
2505 *pcbStructInfo
= sizeof(BOOL
);
2506 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2509 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2513 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2514 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2516 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2517 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2520 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2521 pvStructInfo
, *pcbStructInfo
);
2525 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2528 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2529 if (1 + lenBytes
> cbEncoded
)
2531 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2534 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2536 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2538 case 1: /* rfc822Name */
2539 case 2: /* dNSName */
2540 case 6: /* uniformResourceIdentifier */
2541 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2543 case 4: /* directoryName */
2544 case 7: /* iPAddress */
2545 bytesNeeded
+= dataLen
;
2547 case 8: /* registeredID */
2548 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2552 /* FIXME: ugly, shouldn't need to know internals of OID decode
2553 * function to use it.
2555 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2558 case 0: /* otherName */
2559 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2560 SetLastError(CRYPT_E_ASN1_BADTAG
);
2563 case 3: /* x400Address, unimplemented */
2564 case 5: /* ediPartyName, unimplemented */
2565 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2566 SetLastError(CRYPT_E_ASN1_BADTAG
);
2570 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2571 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2577 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2579 *pcbStructInfo
= bytesNeeded
;
2580 else if (*pcbStructInfo
< bytesNeeded
)
2582 *pcbStructInfo
= bytesNeeded
;
2583 SetLastError(ERROR_MORE_DATA
);
2588 *pcbStructInfo
= bytesNeeded
;
2589 /* MS used values one greater than the asn1 ones.. sigh */
2590 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
2591 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2593 case 1: /* rfc822Name */
2594 case 2: /* dNSName */
2595 case 6: /* uniformResourceIdentifier */
2599 for (i
= 0; i
< dataLen
; i
++)
2600 entry
->u
.pwszURL
[i
] =
2601 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2602 entry
->u
.pwszURL
[i
] = 0;
2603 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2604 debugstr_w(entry
->u
.pwszURL
));
2607 case 4: /* directoryName */
2608 /* The data are memory-equivalent with the IPAddress case,
2611 case 7: /* iPAddress */
2612 /* The next data pointer is in the pwszURL spot, that is,
2613 * the first 4 bytes. Need to move it to the next spot.
2615 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2616 entry
->u
.IPAddress
.cbData
= dataLen
;
2617 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2620 case 8: /* registeredID */
2621 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2622 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2631 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
2632 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2636 struct AsnArrayDescriptor arrayDesc
= { 0,
2637 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2638 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2639 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2641 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2642 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2645 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2646 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2647 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2648 info
? info
->rgAltEntry
: NULL
);
2652 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2653 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
2654 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2659 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2660 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2662 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2665 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
2666 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
2668 if (ret
&& pvStructInfo
)
2670 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2677 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
2679 temp
= blob
->pbData
[i
];
2680 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
2681 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
2685 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2689 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2690 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2691 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2697 struct AsnDecodeSequenceItem items
[] = {
2698 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2699 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2700 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2701 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2702 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2703 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2704 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2705 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2706 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2707 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2708 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2711 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2712 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2713 pcbStructInfo
, NULL
, NULL
);
2717 SetLastError(STATUS_ACCESS_VIOLATION
);
2724 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2725 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2726 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2732 struct AsnDecodeSequenceItem items
[] = {
2733 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2734 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2735 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2736 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2737 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2738 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2739 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2740 AuthorityCertIssuer
.rgAltEntry
), 0 },
2741 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2742 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2743 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2744 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2745 AuthorityCertSerialNumber
.pbData
), 0 },
2748 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2749 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2750 pcbStructInfo
, NULL
, NULL
);
2754 SetLastError(STATUS_ACCESS_VIOLATION
);
2761 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
2762 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2765 struct AsnDecodeSequenceItem items
[] = {
2766 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
2767 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
2768 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
2769 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
2770 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
2771 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
2773 CERT_ACCESS_DESCRIPTION
*descr
= (CERT_ACCESS_DESCRIPTION
*)pvStructInfo
;
2775 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2776 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2777 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
2780 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
2781 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2782 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2786 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2787 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2791 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2792 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
2793 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
2795 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2796 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2800 SetLastError(STATUS_ACCESS_VIOLATION
);
2807 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2808 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2813 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2814 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2816 /* The caller has already checked the tag, no need to check it again.
2817 * Check the outer length is valid:
2819 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
2821 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2824 pbEncoded
+= 1 + lenBytes
;
2825 cbEncoded
-= 1 + lenBytes
;
2826 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2827 cbEncoded
-= 2; /* space for 0 TLV */
2828 /* Check the inner length is valid: */
2829 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
2833 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
2834 pvStructInfo
, pcbStructInfo
, &decodedLen
);
2835 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2837 if (*(pbEncoded
+ decodedLen
) != 0 ||
2838 *(pbEncoded
+ decodedLen
+ 1) != 0)
2840 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2841 *(pbEncoded
+ decodedLen
),
2842 *(pbEncoded
+ decodedLen
+ 1));
2843 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2849 if (ret
&& pcbDecoded
)
2851 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
2852 TRACE("decoded %d bytes\n", *pcbDecoded
);
2859 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
2860 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2863 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2864 struct AsnDecodeSequenceItem items
[] = {
2865 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2866 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2867 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2868 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2869 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2870 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2871 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2875 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2876 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2878 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2879 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2880 pcbDecoded
, info
? info
->pszObjId
: NULL
);
2884 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2885 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2886 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2890 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2891 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2895 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
2896 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
2897 if (ret
&& pvStructInfo
)
2899 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2900 pcbStructInfo
, *pcbStructInfo
);
2903 CRYPT_CONTENT_INFO
*info
;
2905 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2906 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2907 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2908 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2909 sizeof(CRYPT_CONTENT_INFO
));
2910 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
2911 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2912 pcbStructInfo
, NULL
);
2918 SetLastError(STATUS_ACCESS_VIOLATION
);
2924 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2925 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2926 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2929 struct AsnDecodeSequenceItem items
[] = {
2930 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
2931 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2932 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2933 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2934 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2936 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2937 CRYPT_AsnDecodePKCSContentInfoInternal
,
2938 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2939 ContentInfo
.pszObjId
), 0 },
2940 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2941 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2942 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2945 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2946 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
2951 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2952 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2953 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2957 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2958 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2964 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2965 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2968 *pcbStructInfo
= bytesNeeded
;
2969 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2970 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2972 CERT_ALT_NAME_INFO
*name
;
2974 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2975 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2976 name
= (CERT_ALT_NAME_INFO
*)pvStructInfo
;
2977 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
2978 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
2979 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2980 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2981 &bytesNeeded
, NULL
);
2987 SetLastError(STATUS_ACCESS_VIOLATION
);
2994 struct PATH_LEN_CONSTRAINT
2996 BOOL fPathLenConstraint
;
2997 DWORD dwPathLenConstraint
;
3000 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3001 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3005 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3007 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3008 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3012 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3014 *pcbStructInfo
= bytesNeeded
;
3016 else if (*pcbStructInfo
< bytesNeeded
)
3018 SetLastError(ERROR_MORE_DATA
);
3019 *pcbStructInfo
= bytesNeeded
;
3024 struct PATH_LEN_CONSTRAINT
*constraint
=
3025 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
3027 *pcbStructInfo
= bytesNeeded
;
3028 size
= sizeof(constraint
->dwPathLenConstraint
);
3029 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3030 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3032 constraint
->fPathLenConstraint
= TRUE
;
3033 TRACE("got an int, dwPathLenConstraint is %d\n",
3034 constraint
->dwPathLenConstraint
);
3036 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3040 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3041 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3045 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3046 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3047 offsetof(CERT_NAME_BLOB
, pbData
) };
3048 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
3050 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3051 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3053 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3054 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3055 entries
? entries
->rgItems
: NULL
);
3056 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3060 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3061 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3062 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3068 struct AsnDecodeSequenceItem items
[] = {
3069 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3070 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3071 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3072 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3073 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3074 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3075 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3076 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3077 sizeof(struct GenericArray
), TRUE
, TRUE
,
3078 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3081 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3082 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3083 pcbStructInfo
, NULL
, NULL
);
3087 SetLastError(STATUS_ACCESS_VIOLATION
);
3094 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3095 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3096 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3102 struct AsnDecodeSequenceItem items
[] = {
3103 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3104 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3105 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3106 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3107 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3110 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3111 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3112 pcbStructInfo
, NULL
, NULL
);
3116 SetLastError(STATUS_ACCESS_VIOLATION
);
3123 #define RSA1_MAGIC 0x31415352
3125 struct DECODED_RSA_PUB_KEY
3128 CRYPT_INTEGER_BLOB modulus
;
3131 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3132 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3133 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3139 struct AsnDecodeSequenceItem items
[] = {
3140 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3141 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3142 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3144 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3145 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3147 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3150 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3151 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3155 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3156 decodedKey
->modulus
.cbData
;
3160 *pcbStructInfo
= bytesNeeded
;
3163 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3164 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3167 RSAPUBKEY
*rsaPubKey
;
3169 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3170 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3171 hdr
= (BLOBHEADER
*)pvStructInfo
;
3172 hdr
->bType
= PUBLICKEYBLOB
;
3173 hdr
->bVersion
= CUR_BLOB_VERSION
;
3175 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3176 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3177 sizeof(BLOBHEADER
));
3178 rsaPubKey
->magic
= RSA1_MAGIC
;
3179 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3180 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3181 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3182 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3183 decodedKey
->modulus
.cbData
);
3185 LocalFree(decodedKey
);
3190 SetLastError(STATUS_ACCESS_VIOLATION
);
3197 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3198 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3202 DWORD bytesNeeded
, dataLen
;
3204 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3205 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3207 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3209 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3211 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3212 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3214 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3216 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3218 *pcbStructInfo
= bytesNeeded
;
3219 else if (*pcbStructInfo
< bytesNeeded
)
3221 SetLastError(ERROR_MORE_DATA
);
3222 *pcbStructInfo
= bytesNeeded
;
3227 CRYPT_DATA_BLOB
*blob
;
3229 *pcbStructInfo
= bytesNeeded
;
3230 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3231 blob
->cbData
= dataLen
;
3232 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3233 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3236 assert(blob
->pbData
);
3238 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3246 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3247 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3248 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3253 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3261 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3264 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3266 SetLastError(CRYPT_E_ASN1_BADTAG
);
3269 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3270 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3273 *pcbStructInfo
= bytesNeeded
;
3274 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3275 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3277 CRYPT_DATA_BLOB
*blob
;
3279 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3280 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3281 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3282 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3283 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3284 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3285 &bytesNeeded
, NULL
);
3291 SetLastError(STATUS_ACCESS_VIOLATION
);
3298 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3299 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3302 DWORD bytesNeeded
, dataLen
;
3303 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3305 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3306 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3308 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3310 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3311 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3313 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3315 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3317 *pcbStructInfo
= bytesNeeded
;
3318 else if (*pcbStructInfo
< bytesNeeded
)
3320 *pcbStructInfo
= bytesNeeded
;
3321 SetLastError(ERROR_MORE_DATA
);
3326 CRYPT_BIT_BLOB
*blob
;
3328 *pcbStructInfo
= bytesNeeded
;
3329 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3330 blob
->cbData
= dataLen
- 1;
3331 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3332 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3334 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3338 assert(blob
->pbData
);
3341 BYTE mask
= 0xff << blob
->cUnusedBits
;
3343 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3345 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3353 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3354 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3355 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3359 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3360 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3368 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3371 else if (pbEncoded
[0] != ASN_BITSTRING
)
3373 SetLastError(CRYPT_E_ASN1_BADTAG
);
3376 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3377 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3380 *pcbStructInfo
= bytesNeeded
;
3381 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3382 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3384 CRYPT_BIT_BLOB
*blob
;
3386 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3387 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3388 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3389 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3390 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3391 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3392 &bytesNeeded
, NULL
);
3398 SetLastError(STATUS_ACCESS_VIOLATION
);
3402 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3406 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3407 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3408 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3411 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3412 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3413 DWORD size
= sizeof(buf
);
3415 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3416 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
3421 *pcbStructInfo
= sizeof(int);
3422 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3426 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3428 /* initialize to a negative value to sign-extend */
3433 for (i
= 0; i
< blob
->cbData
; i
++)
3436 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3438 memcpy(pvStructInfo
, &val
, sizeof(int));
3441 else if (GetLastError() == ERROR_MORE_DATA
)
3442 SetLastError(CRYPT_E_ASN1_LARGE
);
3446 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3447 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3448 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3458 SetLastError(CRYPT_E_ASN1_EOD
);
3461 else if (pbEncoded
[0] != ASN_INTEGER
)
3463 SetLastError(CRYPT_E_ASN1_BADTAG
);
3467 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3468 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3472 *pcbStructInfo
= bytesNeeded
;
3473 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3474 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3476 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3477 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3478 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3479 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3480 &bytesNeeded
, NULL
);
3486 SetLastError(STATUS_ACCESS_VIOLATION
);
3493 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
3494 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3498 DWORD bytesNeeded
, dataLen
;
3500 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3502 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3504 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3506 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3508 *pcbStructInfo
= bytesNeeded
;
3509 else if (*pcbStructInfo
< bytesNeeded
)
3511 *pcbStructInfo
= bytesNeeded
;
3512 SetLastError(ERROR_MORE_DATA
);
3517 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3519 *pcbStructInfo
= bytesNeeded
;
3520 blob
->cbData
= dataLen
;
3521 assert(blob
->pbData
);
3526 for (i
= 0; i
< blob
->cbData
; i
++)
3528 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3537 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3538 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3539 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3547 if (pbEncoded
[0] != ASN_INTEGER
)
3549 SetLastError(CRYPT_E_ASN1_BADTAG
);
3553 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3554 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3558 *pcbStructInfo
= bytesNeeded
;
3559 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3560 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3562 CRYPT_INTEGER_BLOB
*blob
;
3564 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3565 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3566 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3567 blob
->pbData
= (BYTE
*)pvStructInfo
+
3568 sizeof(CRYPT_INTEGER_BLOB
);
3569 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3570 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3571 &bytesNeeded
, NULL
);
3577 SetLastError(STATUS_ACCESS_VIOLATION
);
3584 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
3585 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3590 if (pbEncoded
[0] == ASN_INTEGER
)
3592 DWORD bytesNeeded
, dataLen
;
3594 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3596 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3599 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3600 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3602 *pcbStructInfo
= bytesNeeded
;
3603 else if (*pcbStructInfo
< bytesNeeded
)
3605 *pcbStructInfo
= bytesNeeded
;
3606 SetLastError(ERROR_MORE_DATA
);
3611 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3613 *pcbStructInfo
= bytesNeeded
;
3614 blob
->cbData
= dataLen
;
3615 assert(blob
->pbData
);
3616 /* remove leading zero byte if it exists */
3617 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3626 for (i
= 0; i
< blob
->cbData
; i
++)
3628 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3637 SetLastError(CRYPT_E_ASN1_BADTAG
);
3643 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3644 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3645 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3653 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
3654 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3657 *pcbStructInfo
= bytesNeeded
;
3658 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3659 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3661 CRYPT_INTEGER_BLOB
*blob
;
3663 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3664 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3665 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3666 blob
->pbData
= (BYTE
*)pvStructInfo
+
3667 sizeof(CRYPT_INTEGER_BLOB
);
3668 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
3669 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3670 &bytesNeeded
, NULL
);
3676 SetLastError(STATUS_ACCESS_VIOLATION
);
3683 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3684 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3685 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3691 *pcbStructInfo
= sizeof(int);
3696 if (pbEncoded
[0] == ASN_ENUMERATED
)
3698 unsigned int val
= 0, i
;
3702 SetLastError(CRYPT_E_ASN1_EOD
);
3705 else if (pbEncoded
[1] == 0)
3707 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3712 /* A little strange looking, but we have to accept a sign byte:
3713 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3714 * assuming a small length is okay here, it has to be in short
3717 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3719 SetLastError(CRYPT_E_ASN1_LARGE
);
3722 for (i
= 0; i
< pbEncoded
[1]; i
++)
3725 val
|= pbEncoded
[2 + i
];
3727 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3728 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3730 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3731 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3732 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3738 SetLastError(CRYPT_E_ASN1_BADTAG
);
3744 SetLastError(STATUS_ACCESS_VIOLATION
);
3751 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3754 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3759 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3761 if (!isdigit(*(pbEncoded))) \
3763 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3769 (word) += *(pbEncoded)++ - '0'; \
3774 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3775 SYSTEMTIME
*sysTime
)
3779 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3781 WORD hours
, minutes
= 0;
3782 BYTE sign
= *pbEncoded
++;
3785 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3786 if (ret
&& hours
>= 24)
3788 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3793 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3794 if (ret
&& minutes
>= 60)
3796 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3804 sysTime
->wHour
+= hours
;
3805 sysTime
->wMinute
+= minutes
;
3809 if (hours
> sysTime
->wHour
)
3812 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3815 sysTime
->wHour
-= hours
;
3816 if (minutes
> sysTime
->wMinute
)
3819 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3822 sysTime
->wMinute
-= minutes
;
3829 #define MIN_ENCODED_TIME_LENGTH 10
3831 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
3832 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3837 if (pbEncoded
[0] == ASN_UTCTIME
)
3840 SetLastError(CRYPT_E_ASN1_EOD
);
3841 else if (pbEncoded
[1] > 0x7f)
3843 /* long-form date strings really can't be valid */
3844 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3848 SYSTEMTIME sysTime
= { 0 };
3849 BYTE len
= pbEncoded
[1];
3851 if (len
< MIN_ENCODED_TIME_LENGTH
)
3852 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3857 *pcbDecoded
= 2 + len
;
3859 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3860 if (sysTime
.wYear
>= 50)
3861 sysTime
.wYear
+= 1900;
3863 sysTime
.wYear
+= 2000;
3864 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3865 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3866 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3867 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3870 if (len
>= 2 && isdigit(*pbEncoded
) &&
3871 isdigit(*(pbEncoded
+ 1)))
3872 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3874 else if (isdigit(*pbEncoded
))
3875 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3878 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3884 *pcbStructInfo
= sizeof(FILETIME
);
3885 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3887 ret
= SystemTimeToFileTime(&sysTime
,
3888 (FILETIME
*)pvStructInfo
);
3894 SetLastError(CRYPT_E_ASN1_BADTAG
);
3898 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3899 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3900 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3908 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3909 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3913 *pcbStructInfo
= bytesNeeded
;
3914 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3915 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3917 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3918 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3919 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3920 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3921 &bytesNeeded
, NULL
);
3927 SetLastError(STATUS_ACCESS_VIOLATION
);
3933 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
3934 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3939 if (pbEncoded
[0] == ASN_GENERALTIME
)
3942 SetLastError(CRYPT_E_ASN1_EOD
);
3943 else if (pbEncoded
[1] > 0x7f)
3945 /* long-form date strings really can't be valid */
3946 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3950 BYTE len
= pbEncoded
[1];
3952 if (len
< MIN_ENCODED_TIME_LENGTH
)
3953 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3956 SYSTEMTIME sysTime
= { 0 };
3960 *pcbDecoded
= 2 + len
;
3962 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3963 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3964 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3965 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3968 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3971 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3973 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3980 /* workaround macro weirdness */
3981 digits
= min(len
, 3);
3982 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3983 sysTime
.wMilliseconds
);
3986 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3992 *pcbStructInfo
= sizeof(FILETIME
);
3993 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3995 ret
= SystemTimeToFileTime(&sysTime
,
3996 (FILETIME
*)pvStructInfo
);
4002 SetLastError(CRYPT_E_ASN1_BADTAG
);
4006 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4007 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4011 InternalDecodeFunc decode
= NULL
;
4013 if (pbEncoded
[0] == ASN_UTCTIME
)
4014 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4015 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4016 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4018 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4019 pcbStructInfo
, pcbDecoded
);
4022 SetLastError(CRYPT_E_ASN1_BADTAG
);
4028 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4029 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4030 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4038 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4039 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4043 *pcbStructInfo
= bytesNeeded
;
4044 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4045 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4047 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4048 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4049 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4050 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4051 &bytesNeeded
, NULL
);
4057 SetLastError(STATUS_ACCESS_VIOLATION
);
4064 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4065 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4066 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4072 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4074 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4076 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4081 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4082 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4084 ptr
= pbEncoded
+ 1 + lenBytes
;
4085 remainingLen
= dataLen
;
4086 while (ret
&& remainingLen
)
4090 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4093 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4095 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4096 ptr
+= 1 + nextLenBytes
+ nextLen
;
4097 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4098 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4099 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4105 CRYPT_SEQUENCE_OF_ANY
*seq
;
4110 *pcbStructInfo
= bytesNeeded
;
4111 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4112 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4114 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4115 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4116 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
4117 seq
->cValue
= cValue
;
4118 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4120 nextPtr
= (BYTE
*)seq
->rgValue
+
4121 cValue
* sizeof(CRYPT_DER_BLOB
);
4122 ptr
= pbEncoded
+ 1 + lenBytes
;
4123 remainingLen
= dataLen
;
4125 while (ret
&& remainingLen
)
4129 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4132 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4134 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4136 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4137 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4140 seq
->rgValue
[i
].pbData
= nextPtr
;
4141 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4143 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4145 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4146 ptr
+= 1 + nextLenBytes
+ nextLen
;
4156 SetLastError(CRYPT_E_ASN1_BADTAG
);
4162 SetLastError(STATUS_ACCESS_VIOLATION
);
4169 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4170 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4175 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4177 DWORD bytesNeeded
, dataLen
;
4179 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4181 struct AsnArrayDescriptor arrayDesc
= {
4182 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
4183 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4184 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4185 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4190 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4191 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4192 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
4193 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4194 * as the sizeof(struct GenericArray), so don't include it in the
4195 * total bytes needed.
4197 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4198 sizeof(CERT_ALT_NAME_INFO
);
4201 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4203 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4205 *pcbStructInfo
= bytesNeeded
;
4206 else if (*pcbStructInfo
< bytesNeeded
)
4208 *pcbStructInfo
= bytesNeeded
;
4209 SetLastError(ERROR_MORE_DATA
);
4214 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
4216 *pcbStructInfo
= bytesNeeded
;
4219 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4220 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4221 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4222 0, NULL
, &name
->u
.FullName
, &nameLen
, NULL
,
4223 name
->u
.FullName
.rgAltEntry
);
4226 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4232 SetLastError(CRYPT_E_ASN1_BADTAG
);
4238 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4239 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4241 struct AsnDecodeSequenceItem items
[] = {
4242 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4243 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4244 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4245 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4246 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4247 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4248 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4249 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4250 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4251 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4255 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4256 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4261 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4262 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4263 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4267 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4268 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4272 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4273 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4274 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4276 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4277 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4281 SetLastError(STATUS_ACCESS_VIOLATION
);
4288 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
4289 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4290 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4294 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4295 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4299 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4300 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
4302 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4303 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4307 SetLastError(STATUS_ACCESS_VIOLATION
);
4314 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4315 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4316 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4320 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4321 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4325 struct AsnDecodeSequenceItem items
[] = {
4326 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4327 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4328 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4329 offsetof(CRL_ISSUING_DIST_POINT
,
4330 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4331 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4332 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4334 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4335 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4337 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4338 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4339 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4340 OnlySomeReasonFlags
.pbData
), 0 },
4341 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4342 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4345 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4346 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4347 pcbStructInfo
, NULL
, NULL
);
4351 SetLastError(STATUS_ACCESS_VIOLATION
);
4358 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
4359 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4364 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4365 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4369 SetLastError(CRYPT_E_ASN1_EOD
);
4372 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
4374 SetLastError(CRYPT_E_ASN1_BADTAG
);
4377 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4378 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
4379 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
4381 if (ret
&& pvStructInfo
)
4382 *(BOOL
*)pvStructInfo
= TRUE
;
4383 TRACE("returning %d\n", ret
);
4387 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
4388 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4392 struct AsnDecodeSequenceItem items
[] = {
4393 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
4394 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
4395 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
4396 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
4397 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
4398 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
4399 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
4402 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)pvStructInfo
;
4404 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4405 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4407 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4408 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4409 pcbDecoded
, subtree
? (BYTE
*)subtree
->Base
.u
.pwszURL
: NULL
);
4412 TRACE("%d\n", *pcbDecoded
);
4413 if (*pcbDecoded
< cbEncoded
)
4414 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
4415 *(pbEncoded
+ *pcbDecoded
+ 1));
4417 TRACE("returning %d\n", ret
);
4421 static BOOL
CRYPT_AsnDecodeSubtreeArray(const BYTE
*pbEncoded
,
4422 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4426 struct AsnArrayDescriptor arrayDesc
= { 0,
4427 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4428 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4429 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4431 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4432 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4434 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4435 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4436 array
? array
->rgItems
: NULL
);
4441 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
4442 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4443 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4447 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4448 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4452 struct AsnDecodeSequenceItem items
[] = {
4453 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4454 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
4455 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4456 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
4457 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
4458 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4459 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4460 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
4463 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4464 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4465 pcbStructInfo
, NULL
, NULL
);
4469 SetLastError(STATUS_ACCESS_VIOLATION
);
4475 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
4476 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4480 struct AsnDecodeSequenceItem items
[] = {
4481 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4482 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4484 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4485 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4486 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4488 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
4489 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
4491 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4492 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4494 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4495 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4496 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4497 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4499 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4502 TRACE("returning %d\n", ret
);
4506 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4507 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4510 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4511 struct AsnDecodeSequenceItem items
[] = {
4512 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4513 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4514 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4515 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4516 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4517 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4518 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4519 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4520 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4521 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4522 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4523 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4524 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4525 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4526 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4527 HashEncryptionAlgorithm
.pszObjId
), 0 },
4528 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4529 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4530 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4531 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4532 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4533 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4534 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4538 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4539 pvStructInfo
, *pcbStructInfo
);
4541 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4542 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4543 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
4547 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4548 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4549 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4553 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4554 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4558 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4559 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4560 if (ret
&& pvStructInfo
)
4562 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4563 pcbStructInfo
, *pcbStructInfo
);
4566 CMSG_SIGNER_INFO
*info
;
4568 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4569 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4570 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4571 info
->Issuer
.pbData
= ((BYTE
*)info
+
4572 sizeof(CMSG_SIGNER_INFO
));
4573 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
4574 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4575 pcbStructInfo
, NULL
);
4581 SetLastError(STATUS_ACCESS_VIOLATION
);
4584 TRACE("returning %d\n", ret
);
4588 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
4589 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4592 CERT_ID
*id
= (CERT_ID
*)pvStructInfo
;
4595 if (*pbEncoded
== ASN_SEQUENCEOF
)
4597 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
4598 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
4602 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
4603 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
4604 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4605 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
4607 *pcbStructInfo
= sizeof(CERT_ID
);
4610 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
4612 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
4613 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
4617 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
4618 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
4619 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4620 sizeof(CRYPT_DATA_BLOB
);
4622 *pcbStructInfo
= sizeof(CERT_ID
);
4626 SetLastError(CRYPT_E_ASN1_BADTAG
);
4630 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
4631 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4634 CMSG_CMS_SIGNER_INFO
*info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4635 struct AsnDecodeSequenceItem items
[] = {
4636 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
4637 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4638 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
4639 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
4640 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
4641 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
4642 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4643 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4644 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4645 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
4646 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4647 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4648 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
4649 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4650 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
4651 HashEncryptionAlgorithm
.pszObjId
), 0 },
4652 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
4653 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4654 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4655 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4656 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
4657 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4658 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4662 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4663 pvStructInfo
, *pcbStructInfo
);
4665 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4666 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4667 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
4671 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
4672 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4673 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4677 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4678 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4682 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
4683 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4684 if (ret
&& pvStructInfo
)
4686 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4687 pcbStructInfo
, *pcbStructInfo
);
4690 CMSG_CMS_SIGNER_INFO
*info
;
4692 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4693 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4694 info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4695 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
4696 sizeof(CMSG_CMS_SIGNER_INFO
));
4697 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
4698 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4699 pcbStructInfo
, NULL
);
4705 SetLastError(STATUS_ACCESS_VIOLATION
);
4708 TRACE("returning %d\n", ret
);
4712 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4713 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4716 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
4717 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
4718 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
4719 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4721 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4722 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4724 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4725 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4726 array
? array
->rgItems
: NULL
);
4730 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4731 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
4732 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
4735 struct AsnDecodeSequenceItem items
[] = {
4736 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
4737 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4738 /* Placeholder for the hash algorithms - redundant with those in the
4739 * signers, so just ignore them.
4741 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
4742 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
4743 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
4744 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
4745 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4746 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
4747 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4748 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
4749 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4750 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
4751 sizeof(struct GenericArray
), TRUE
, TRUE
,
4752 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
4753 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
4754 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4755 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
4758 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4759 pDecodePara
, signedInfo
, *pcbSignedInfo
);
4761 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4762 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
4764 TRACE("returning %d\n", ret
);
4768 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
4769 LPCSTR lpszStructType
)
4771 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4773 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
4774 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
4776 SetLastError(ERROR_FILE_NOT_FOUND
);
4779 if (!HIWORD(lpszStructType
))
4781 switch (LOWORD(lpszStructType
))
4783 case LOWORD(X509_CERT
):
4784 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
4786 case LOWORD(X509_CERT_TO_BE_SIGNED
):
4787 decodeFunc
= CRYPT_AsnDecodeCert
;
4789 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
4790 decodeFunc
= CRYPT_AsnDecodeCRL
;
4792 case LOWORD(X509_EXTENSIONS
):
4793 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4795 case LOWORD(X509_NAME_VALUE
):
4796 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4798 case LOWORD(X509_NAME
):
4799 decodeFunc
= CRYPT_AsnDecodeName
;
4801 case LOWORD(X509_PUBLIC_KEY_INFO
):
4802 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4804 case LOWORD(X509_AUTHORITY_KEY_ID
):
4805 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4807 case LOWORD(X509_ALTERNATE_NAME
):
4808 decodeFunc
= CRYPT_AsnDecodeAltName
;
4810 case LOWORD(X509_BASIC_CONSTRAINTS
):
4811 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4813 case LOWORD(X509_BASIC_CONSTRAINTS2
):
4814 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4816 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
4817 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4819 case LOWORD(X509_UNICODE_NAME
):
4820 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4822 case LOWORD(PKCS_ATTRIBUTE
):
4823 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4825 case LOWORD(X509_UNICODE_NAME_VALUE
):
4826 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4828 case LOWORD(X509_OCTET_STRING
):
4829 decodeFunc
= CRYPT_AsnDecodeOctets
;
4831 case LOWORD(X509_BITS
):
4832 case LOWORD(X509_KEY_USAGE
):
4833 decodeFunc
= CRYPT_AsnDecodeBits
;
4835 case LOWORD(X509_INTEGER
):
4836 decodeFunc
= CRYPT_AsnDecodeInt
;
4838 case LOWORD(X509_MULTI_BYTE_INTEGER
):
4839 decodeFunc
= CRYPT_AsnDecodeInteger
;
4841 case LOWORD(X509_MULTI_BYTE_UINT
):
4842 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4844 case LOWORD(X509_ENUMERATED
):
4845 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4847 case LOWORD(X509_CHOICE_OF_TIME
):
4848 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4850 case LOWORD(X509_AUTHORITY_KEY_ID2
):
4851 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4853 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
4854 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
4856 case LOWORD(PKCS_CONTENT_INFO
):
4857 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4859 case LOWORD(X509_SEQUENCE_OF_ANY
):
4860 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4862 case LOWORD(PKCS_UTC_TIME
):
4863 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4865 case LOWORD(X509_CRL_DIST_POINTS
):
4866 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4868 case LOWORD(X509_ENHANCED_KEY_USAGE
):
4869 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4871 case LOWORD(PKCS_CTL
):
4872 decodeFunc
= CRYPT_AsnDecodeCTL
;
4874 case LOWORD(PKCS_SMIME_CAPABILITIES
):
4875 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4877 case LOWORD(PKCS_ATTRIBUTES
):
4878 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4880 case LOWORD(X509_ISSUING_DIST_POINT
):
4881 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4883 case LOWORD(X509_NAME_CONSTRAINTS
):
4884 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4886 case LOWORD(PKCS7_SIGNER_INFO
):
4887 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4889 case LOWORD(CMS_SIGNER_INFO
):
4890 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
4894 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4895 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4896 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4897 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4898 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
4899 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4900 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4901 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4902 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4903 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4904 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4905 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4906 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4907 decodeFunc
= CRYPT_AsnDecodeBits
;
4908 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4909 decodeFunc
= CRYPT_AsnDecodeOctets
;
4910 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4911 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4912 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4913 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4914 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4915 decodeFunc
= CRYPT_AsnDecodeAltName
;
4916 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4917 decodeFunc
= CRYPT_AsnDecodeAltName
;
4918 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4919 decodeFunc
= CRYPT_AsnDecodeAltName
;
4920 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4921 decodeFunc
= CRYPT_AsnDecodeAltName
;
4922 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4923 decodeFunc
= CRYPT_AsnDecodeAltName
;
4924 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4925 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4926 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4927 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4928 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4929 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4930 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
4931 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4932 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
4933 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
4934 else if (!strcmp(lpszStructType
, szOID_CTL
))
4935 decodeFunc
= CRYPT_AsnDecodeCTL
;
4939 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
4940 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4942 static HCRYPTOIDFUNCSET set
= NULL
;
4943 CryptDecodeObjectFunc decodeFunc
= NULL
;
4946 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
4947 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4948 (void **)&decodeFunc
, hFunc
);
4952 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
4953 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4955 static HCRYPTOIDFUNCSET set
= NULL
;
4956 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4959 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4960 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4961 (void **)&decodeFunc
, hFunc
);
4965 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4966 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
4967 DWORD
*pcbStructInfo
)
4970 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
4971 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
4972 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4974 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
4975 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
4976 pvStructInfo
, pcbStructInfo
);
4978 if (!pvStructInfo
&& !pcbStructInfo
)
4980 SetLastError(ERROR_INVALID_PARAMETER
);
4983 if (cbEncoded
> MAX_ENCODED_LEN
)
4985 SetLastError(CRYPT_E_ASN1_LARGE
);
4989 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
4992 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4993 debugstr_a(lpszStructType
));
4994 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
4995 lpszStructType
, &hFunc
);
4996 if (!pCryptDecodeObject
)
4997 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
4998 lpszStructType
, &hFunc
);
5000 if (pCryptDecodeObject
)
5001 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5002 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5003 else if (pCryptDecodeObjectEx
)
5004 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5005 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5006 pvStructInfo
, pcbStructInfo
);
5008 CryptFreeOIDFunctionAddress(hFunc
, 0);
5009 TRACE_(crypt
)("returning %d\n", ret
);
5013 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5014 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5015 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5018 CryptDecodeObjectExFunc decodeFunc
;
5019 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5021 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5022 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5023 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5025 if (!pvStructInfo
&& !pcbStructInfo
)
5027 SetLastError(ERROR_INVALID_PARAMETER
);
5030 if (cbEncoded
> MAX_ENCODED_LEN
)
5032 SetLastError(CRYPT_E_ASN1_LARGE
);
5036 SetLastError(NOERROR
);
5037 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5038 *(BYTE
**)pvStructInfo
= NULL
;
5039 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5042 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5043 debugstr_a(lpszStructType
));
5044 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5048 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5049 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5052 CryptDecodeObjectFunc pCryptDecodeObject
=
5053 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5055 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5056 * directly, as that could cause an infinite loop.
5058 if (pCryptDecodeObject
)
5060 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5062 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5063 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5064 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5065 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5066 ret
= pCryptDecodeObject(dwCertEncodingType
,
5067 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5068 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5071 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5072 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5076 CryptFreeOIDFunctionAddress(hFunc
, 0);
5077 TRACE_(crypt
)("returning %d\n", ret
);