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 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
100 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
101 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
102 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
103 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
104 * member has been initialized, doesn't do exception handling, and doesn't do
105 * memory allocation. Also doesn't check tag, assumes the caller has checked
108 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
111 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
112 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
113 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
115 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
116 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
119 /* Gets the number of length bytes from the given (leading) length byte */
120 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
122 /* Helper function to get the encoded length of the data starting at pbEncoded,
123 * where pbEncoded[0] is the tag. If the data are too short to contain a
124 * length or if the length is too large for cbEncoded, sets an appropriate
125 * error code and returns FALSE. If the encoded length is unknown due to
126 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
128 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
135 SetLastError(CRYPT_E_ASN1_CORRUPT
);
138 else if (pbEncoded
[1] <= 0x7f)
140 if (pbEncoded
[1] + 1 > cbEncoded
)
142 SetLastError(CRYPT_E_ASN1_EOD
);
151 else if (pbEncoded
[1] == 0x80)
153 *len
= CMSG_INDEFINITE_LENGTH
;
158 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
160 if (lenLen
> sizeof(DWORD
) + 1)
162 SetLastError(CRYPT_E_ASN1_LARGE
);
165 else if (lenLen
+ 2 > cbEncoded
)
167 SetLastError(CRYPT_E_ASN1_CORRUPT
);
180 if (out
+ lenLen
+ 1 > cbEncoded
)
182 SetLastError(CRYPT_E_ASN1_EOD
);
195 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
196 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
200 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
201 *len
== CMSG_INDEFINITE_LENGTH
)
203 SetLastError(CRYPT_E_ASN1_CORRUPT
);
209 /* Helper function to check *pcbStructInfo, set it to the required size, and
210 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
211 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
212 * pointer to the newly allocated memory.
214 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
215 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
220 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
222 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
223 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
225 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
226 if (!*(BYTE
**)pvStructInfo
)
229 *pcbStructInfo
= bytesNeeded
;
231 else if (*pcbStructInfo
< bytesNeeded
)
233 *pcbStructInfo
= bytesNeeded
;
234 SetLastError(ERROR_MORE_DATA
);
238 *pcbStructInfo
= bytesNeeded
;
242 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
244 if (pDecodePara
&& pDecodePara
->pfnFree
)
245 pDecodePara
->pfnFree(pv
);
250 /* Helper function to check *pcbStructInfo and set it to the required size.
251 * Assumes pvStructInfo is not NULL.
253 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
257 if (*pcbStructInfo
< bytesNeeded
)
259 *pcbStructInfo
= bytesNeeded
;
260 SetLastError(ERROR_MORE_DATA
);
265 *pcbStructInfo
= bytesNeeded
;
272 * The expected tag of the item. If tag is 0, decodeFunc is called
273 * regardless of the tag value seen.
275 * A sequence is decoded into a struct. The offset member is the
276 * offset of this item within that struct.
278 * The decoder function to use. If this is NULL, then the member isn't
279 * decoded, but minSize space is reserved for it.
281 * The minimum amount of space occupied after decoding. You must set this.
283 * If true, and the tag doesn't match the expected tag for this item,
284 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
285 * filled with 0 for this member.
286 * hasPointer, pointerOffset:
287 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
288 * the offset within the struct of the data pointer (or to the
289 * first data pointer, if more than one exist).
291 * Used by CRYPT_AsnDecodeSequence, not for your use.
293 struct AsnDecodeSequenceItem
297 InternalDecodeFunc decodeFunc
;
305 /* Decodes the items in a sequence, where the items are described in items,
306 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
307 * pvStructInfo. nextData is a pointer to the memory location at which the
308 * first decoded item with a dynamic pointer should point.
309 * Upon decoding, *cbDecoded is the total number of bytes decoded.
310 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
312 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
313 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
314 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
317 DWORD i
, decoded
= 0;
318 const BYTE
*ptr
= pbEncoded
;
320 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
321 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
323 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
325 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
329 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
330 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
332 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
334 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
336 DWORD itemEncodedLen
;
338 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
339 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
341 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
342 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
344 TRACE("Setting next pointer to %p\n",
346 *(BYTE
**)((BYTE
*)pvStructInfo
+
347 items
[i
].pointerOffset
) = nextData
;
349 if (items
[i
].decodeFunc
)
354 TRACE("decoding item %d\n", i
);
356 TRACE("sizing item %d\n", i
);
357 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
358 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
359 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
360 : NULL
, &items
[i
].size
, &itemDecoded
);
363 /* Account for alignment padding */
364 if (items
[i
].size
% sizeof(DWORD_PTR
))
365 items
[i
].size
+= sizeof(DWORD_PTR
) -
366 items
[i
].size
% sizeof(DWORD_PTR
);
367 TRACE("item %d size: %d\n", i
, items
[i
].size
);
368 if (nextData
&& items
[i
].hasPointer
&&
369 items
[i
].size
> items
[i
].minSize
)
370 nextData
+= items
[i
].size
- items
[i
].minSize
;
371 if (itemDecoded
> itemEncodedLen
)
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded
, itemEncodedLen
);
375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
380 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
382 if (itemDecoded
> itemEncodedLen
- 2 ||
383 *(ptr
+ itemDecoded
) != 0 ||
384 *(ptr
+ itemDecoded
+ 1) != 0)
386 TRACE("expected 0 TLV\n");
387 SetLastError(CRYPT_E_ASN1_CORRUPT
);
396 decoded
+= itemDecoded
;
397 TRACE("item %d: decoded %d bytes\n", i
,
402 else if (items
[i
].optional
&&
403 GetLastError() == CRYPT_E_ASN1_BADTAG
)
405 TRACE("skipping optional item %d\n", i
);
406 items
[i
].size
= items
[i
].minSize
;
407 SetLastError(NOERROR
);
411 TRACE("item %d failed: %08x\n", i
,
414 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
416 ERR("can't use indefinite length encoding without a decoder\n");
417 SetLastError(CRYPT_E_ASN1_CORRUPT
);
422 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
423 ptr
+= itemEncodedLen
;
424 decoded
+= itemEncodedLen
;
425 items
[i
].size
= items
[i
].minSize
;
428 else if (items
[i
].optional
)
430 TRACE("skipping optional item %d\n", i
);
431 items
[i
].size
= items
[i
].minSize
;
435 TRACE("item %d: tag %02x doesn't match expected %02x\n",
436 i
, ptr
[0], items
[i
].tag
);
437 SetLastError(CRYPT_E_ASN1_BADTAG
);
442 else if (items
[i
].optional
)
444 TRACE("missing optional item %d, skipping\n", i
);
445 items
[i
].size
= items
[i
].minSize
;
449 TRACE("not enough bytes for item %d, failing\n", i
);
450 SetLastError(CRYPT_E_ASN1_CORRUPT
);
455 *cbDecoded
= decoded
;
456 TRACE("returning %d\n", ret
);
460 /* This decodes an arbitrary sequence into a contiguous block of memory
461 * (basically, a struct.) Each element being decoded is described by a struct
462 * AsnDecodeSequenceItem, see above.
463 * startingPointer is an optional pointer to the first place where dynamic
464 * data will be stored. If you know the starting offset, you may pass it
465 * here. Otherwise, pass NULL, and one will be inferred from the items.
467 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
468 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
469 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
470 DWORD
*pcbDecoded
, void *startingPointer
)
474 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
475 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
478 if (pbEncoded
[0] == ASN_SEQUENCE
)
482 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
484 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
485 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
486 BOOL indefinite
= FALSE
;
488 cbEncoded
-= 1 + lenBytes
;
489 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
494 else if (cbEncoded
< dataLen
)
496 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
498 SetLastError(CRYPT_E_ASN1_CORRUPT
);
503 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
504 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
505 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
507 if (cbDecoded
> cbEncoded
- 2)
509 /* Not enough space for 0 TLV */
510 SetLastError(CRYPT_E_ASN1_CORRUPT
);
513 else if (*(ptr
+ cbDecoded
) != 0 ||
514 *(ptr
+ cbDecoded
+ 1) != 0)
516 TRACE("expected 0 TLV\n");
517 SetLastError(CRYPT_E_ASN1_CORRUPT
);
524 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
526 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
528 SetLastError(CRYPT_E_ASN1_CORRUPT
);
533 DWORD i
, bytesNeeded
= 0, structSize
= 0;
535 for (i
= 0; i
< cItem
; i
++)
537 bytesNeeded
+= items
[i
].size
;
538 structSize
+= items
[i
].minSize
;
541 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
543 *pcbStructInfo
= bytesNeeded
;
544 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
545 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
549 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
550 pvStructInfo
= *(BYTE
**)pvStructInfo
;
552 nextData
= (BYTE
*)startingPointer
;
554 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
555 memset(pvStructInfo
, 0, structSize
);
556 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
557 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
559 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
560 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
567 SetLastError(CRYPT_E_ASN1_BADTAG
);
570 TRACE("returning %d (%08x)\n", ret
, GetLastError());
575 * The expected tag of the entire encoded array (usually a variant
576 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
577 * regardless of the tag seen.
579 * used to decode each item in the array
581 * is the minimum size of each decoded item
583 * indicates whether each item has a dynamic pointer
585 * indicates the offset within itemSize at which the pointer exists
587 struct AsnArrayDescriptor
590 InternalDecodeFunc decodeFunc
;
596 struct AsnArrayItemSize
602 /* Decodes an array of like types into a struct GenericArray.
603 * The layout and decoding of the array are described by a struct
604 * AsnArrayDescriptor.
606 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
607 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
608 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
609 DWORD
*pcbDecoded
, void *startingPointer
)
613 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
614 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
617 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
621 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
623 DWORD bytesNeeded
, cItems
= 0, decoded
;
624 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
625 /* There can be arbitrarily many items, but there is often only one.
627 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
629 decoded
= 1 + lenBytes
;
630 bytesNeeded
= sizeof(struct GenericArray
);
634 BOOL doneDecoding
= FALSE
;
636 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
638 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
645 SetLastError(CRYPT_E_ASN1_CORRUPT
);
652 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
656 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
658 /* Each item decoded may not tolerate extraneous bytes,
659 * so get the length of the next element if known.
661 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
662 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
664 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
665 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
667 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
671 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
672 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
677 if (itemSizes
!= &itemSize
)
678 itemSizes
= CryptMemRealloc(itemSizes
,
679 cItems
* sizeof(struct AsnArrayItemSize
));
684 cItems
* sizeof(struct AsnArrayItemSize
));
686 memcpy(itemSizes
, &itemSize
,
691 decoded
+= itemDecoded
;
692 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
693 itemSizes
[cItems
- 1].size
= size
;
706 *pcbDecoded
= decoded
;
708 *pcbStructInfo
= bytesNeeded
;
709 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
710 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
715 struct GenericArray
*array
;
717 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
718 pvStructInfo
= *(BYTE
**)pvStructInfo
;
719 array
= (struct GenericArray
*)pvStructInfo
;
720 array
->cItems
= cItems
;
722 array
->rgItems
= startingPointer
;
724 array
->rgItems
= (BYTE
*)array
+
725 sizeof(struct GenericArray
);
726 nextData
= array
->rgItems
+
727 array
->cItems
* arrayDesc
->itemSize
;
728 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
729 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
734 if (arrayDesc
->hasPointer
)
735 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
736 + arrayDesc
->pointerOffset
) = nextData
;
737 ret
= arrayDesc
->decodeFunc(ptr
,
738 itemSizes
[i
].encodedLen
,
739 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
740 array
->rgItems
+ i
* arrayDesc
->itemSize
,
741 &itemSizes
[i
].size
, &itemDecoded
);
744 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
748 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
749 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
752 if (itemSizes
!= &itemSize
)
753 CryptMemFree(itemSizes
);
758 SetLastError(CRYPT_E_ASN1_BADTAG
);
764 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
765 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
766 * to CRYPT_E_ASN1_CORRUPT.
767 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
770 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
771 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
776 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
778 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
779 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
781 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
782 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
785 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
787 *pcbStructInfo
= bytesNeeded
;
788 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
790 CRYPT_DER_BLOB
*blob
;
792 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
793 pvStructInfo
= *(BYTE
**)pvStructInfo
;
794 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
795 blob
->cbData
= 1 + lenBytes
+ dataLen
;
798 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
799 blob
->pbData
= (BYTE
*)pbEncoded
;
802 assert(blob
->pbData
);
803 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
808 SetLastError(CRYPT_E_ASN1_CORRUPT
);
816 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
817 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
818 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
823 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
824 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
826 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
829 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
830 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
832 if (ret
&& pvStructInfo
)
834 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
841 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
843 temp
= blob
->pbData
[i
];
844 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
845 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
849 TRACE("returning %d (%08x)\n", ret
, GetLastError());
853 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
854 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
855 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
859 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
860 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
864 struct AsnDecodeSequenceItem items
[] = {
865 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
866 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
867 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
868 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
869 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
870 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
871 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
872 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
873 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
874 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
877 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
878 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
879 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
880 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
881 pcbStructInfo
, NULL
, NULL
);
885 SetLastError(STATUS_ACCESS_VIOLATION
);
890 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
894 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
895 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
900 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
902 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
904 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
905 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
907 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
912 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
913 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
917 struct AsnDecodeSequenceItem items
[] = {
918 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
919 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
920 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
921 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
924 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
925 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
930 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
931 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
937 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
939 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
941 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
942 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
943 if (ret
&& pcbDecoded
)
944 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
949 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
950 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
951 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
954 struct AsnDecodeSequenceItem items
[] = {
955 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
956 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
957 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
958 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
959 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
960 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
961 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
962 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
963 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
964 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
966 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
967 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
969 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
970 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
972 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
973 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
974 FALSE
, TRUE
, offsetof(CERT_INFO
,
975 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
976 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
977 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
978 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
979 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
980 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
981 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
982 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
983 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
984 offsetof(CERT_INFO
, rgExtension
), 0 },
987 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
988 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
990 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
991 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
993 if (ret
&& pvStructInfo
)
997 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
998 info
= *(CERT_INFO
**)pvStructInfo
;
1000 info
= (CERT_INFO
*)pvStructInfo
;
1001 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1002 !info
->Subject
.cbData
)
1004 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1005 /* Don't need to deallocate, because it should have failed on the
1006 * first pass (and no memory was allocated.)
1012 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1016 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1017 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1018 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1022 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1023 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1029 /* Unless told not to, first try to decode it as a signed cert. */
1030 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1032 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1034 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1035 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1036 (BYTE
*)&signedCert
, &size
);
1040 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1041 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1042 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1043 pvStructInfo
, pcbStructInfo
);
1044 LocalFree(signedCert
);
1047 /* Failing that, try it as an unsigned cert */
1051 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1052 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1053 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1058 SetLastError(STATUS_ACCESS_VIOLATION
);
1062 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1066 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1067 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1070 struct AsnDecodeSequenceItem items
[] = {
1071 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1072 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1073 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1074 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1075 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1076 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1077 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1078 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1080 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
1082 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1085 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1086 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1087 entry
? entry
->SerialNumber
.pbData
: NULL
);
1088 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1090 WARN("empty CRL entry serial number\n");
1091 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1097 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1098 * been set prior to calling.
1100 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1101 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1104 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1105 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1106 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1107 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1109 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1110 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1112 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1113 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1114 entries
? entries
->rgItems
: NULL
);
1115 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1119 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1120 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1121 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1123 struct AsnDecodeSequenceItem items
[] = {
1124 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1125 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1126 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1127 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1128 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1129 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1130 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1132 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1133 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1134 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1135 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1136 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1137 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1138 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1139 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1140 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1141 offsetof(CRL_INFO
, rgExtension
), 0 },
1145 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1146 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1148 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1149 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1152 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1156 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1157 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1158 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1162 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1163 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1169 /* Unless told not to, first try to decode it as a signed crl. */
1170 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1172 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1174 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1175 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1176 (BYTE
*)&signedCrl
, &size
);
1180 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1181 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1182 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1183 pvStructInfo
, pcbStructInfo
);
1184 LocalFree(signedCrl
);
1187 /* Failing that, try it as an unsigned crl */
1191 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1192 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1193 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1198 SetLastError(STATUS_ACCESS_VIOLATION
);
1202 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1206 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1207 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1212 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1213 pvStructInfo
, *pcbStructInfo
);
1215 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1217 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1218 DWORD bytesNeeded
= sizeof(LPSTR
);
1222 /* The largest possible string for the first two components
1223 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1228 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1229 pbEncoded
[1 + lenBytes
] / 40,
1230 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1232 bytesNeeded
+= strlen(firstTwo
) + 1;
1233 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1234 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1236 /* large enough for ".4000000" */
1240 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1247 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1250 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1257 snprintf(str
, sizeof(str
), ".%d", val
);
1258 bytesNeeded
+= strlen(str
);
1263 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1265 *pcbStructInfo
= bytesNeeded
;
1266 else if (*pcbStructInfo
< bytesNeeded
)
1268 *pcbStructInfo
= bytesNeeded
;
1269 SetLastError(ERROR_MORE_DATA
);
1277 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1280 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1281 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1283 pszObjId
+= strlen(pszObjId
);
1284 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1285 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1289 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1298 sprintf(pszObjId
, ".%d", val
);
1299 pszObjId
+= strlen(pszObjId
);
1303 *(LPSTR
*)pvStructInfo
= NULL
;
1304 *pcbStructInfo
= bytesNeeded
;
1310 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1311 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1315 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1316 pvStructInfo
, *pcbStructInfo
);
1318 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1319 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1320 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1323 SetLastError(CRYPT_E_ASN1_BADTAG
);
1329 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1332 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1333 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1335 struct AsnDecodeSequenceItem items
[] = {
1336 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1337 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1338 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1339 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1340 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1341 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1342 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1343 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1346 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1348 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1352 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1353 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1354 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1355 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1357 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1358 debugstr_a(ext
->pszObjId
));
1359 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1363 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
1364 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1368 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1369 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1370 offsetof(CERT_EXTENSION
, pszObjId
) };
1371 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1373 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1374 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1376 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1377 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1378 exts
? exts
->rgExtension
: NULL
);
1382 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1383 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1384 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1390 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1391 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1392 if (ret
&& pvStructInfo
)
1394 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1395 pcbStructInfo
, *pcbStructInfo
);
1398 CERT_EXTENSIONS
*exts
;
1400 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1401 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1402 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1403 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1404 sizeof(CERT_EXTENSIONS
));
1405 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1406 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1407 pcbStructInfo
, NULL
);
1413 SetLastError(STATUS_ACCESS_VIOLATION
);
1420 /* Warning: this assumes the address of value->Value.pbData is already set, in
1421 * order to avoid overwriting memory. (In some cases, it may change it, if it
1422 * doesn't copy anything to memory.) Be sure to set it correctly!
1424 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1425 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1430 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1432 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1434 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1435 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1437 switch (pbEncoded
[0])
1439 case ASN_OCTETSTRING
:
1440 valueType
= CERT_RDN_OCTET_STRING
;
1441 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1442 bytesNeeded
+= dataLen
;
1444 case ASN_NUMERICSTRING
:
1445 valueType
= CERT_RDN_NUMERIC_STRING
;
1446 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1447 bytesNeeded
+= dataLen
;
1449 case ASN_PRINTABLESTRING
:
1450 valueType
= CERT_RDN_PRINTABLE_STRING
;
1451 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1452 bytesNeeded
+= dataLen
;
1455 valueType
= CERT_RDN_IA5_STRING
;
1456 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1457 bytesNeeded
+= dataLen
;
1460 valueType
= CERT_RDN_T61_STRING
;
1461 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1462 bytesNeeded
+= dataLen
;
1464 case ASN_VIDEOTEXSTRING
:
1465 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1466 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1467 bytesNeeded
+= dataLen
;
1469 case ASN_GRAPHICSTRING
:
1470 valueType
= CERT_RDN_GRAPHIC_STRING
;
1471 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1472 bytesNeeded
+= dataLen
;
1474 case ASN_VISIBLESTRING
:
1475 valueType
= CERT_RDN_VISIBLE_STRING
;
1476 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1477 bytesNeeded
+= dataLen
;
1479 case ASN_GENERALSTRING
:
1480 valueType
= CERT_RDN_GENERAL_STRING
;
1481 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1482 bytesNeeded
+= dataLen
;
1484 case ASN_UNIVERSALSTRING
:
1485 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1486 SetLastError(CRYPT_E_ASN1_BADTAG
);
1489 valueType
= CERT_RDN_BMP_STRING
;
1490 bytesNeeded
+= dataLen
;
1492 case ASN_UTF8STRING
:
1493 valueType
= CERT_RDN_UTF8_STRING
;
1494 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1495 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1498 SetLastError(CRYPT_E_ASN1_BADTAG
);
1503 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1505 *pcbStructInfo
= bytesNeeded
;
1506 else if (*pcbStructInfo
< bytesNeeded
)
1508 *pcbStructInfo
= bytesNeeded
;
1509 SetLastError(ERROR_MORE_DATA
);
1514 *pcbStructInfo
= bytesNeeded
;
1515 value
->dwValueType
= valueType
;
1520 assert(value
->Value
.pbData
);
1521 switch (pbEncoded
[0])
1523 case ASN_OCTETSTRING
:
1524 case ASN_NUMERICSTRING
:
1525 case ASN_PRINTABLESTRING
:
1528 case ASN_VIDEOTEXSTRING
:
1529 case ASN_GRAPHICSTRING
:
1530 case ASN_VISIBLESTRING
:
1531 case ASN_GENERALSTRING
:
1532 value
->Value
.cbData
= dataLen
;
1535 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1536 memcpy(value
->Value
.pbData
,
1537 pbEncoded
+ 1 + lenBytes
, dataLen
);
1539 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1545 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1547 value
->Value
.cbData
= dataLen
;
1548 for (i
= 0; i
< dataLen
/ 2; i
++)
1549 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1550 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1553 case ASN_UTF8STRING
:
1555 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1557 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1558 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1559 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1566 value
->Value
.cbData
= 0;
1567 value
->Value
.pbData
= NULL
;
1574 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1575 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1576 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1582 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1583 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1584 if (ret
&& pvStructInfo
)
1586 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1587 pcbStructInfo
, *pcbStructInfo
);
1590 CERT_NAME_VALUE
*value
;
1592 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1593 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1594 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1595 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1596 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1597 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1598 pcbStructInfo
, NULL
);
1604 SetLastError(STATUS_ACCESS_VIOLATION
);
1611 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1612 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1617 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1619 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1621 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1622 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1624 switch (pbEncoded
[0])
1626 case ASN_NUMERICSTRING
:
1627 valueType
= CERT_RDN_NUMERIC_STRING
;
1628 bytesNeeded
+= dataLen
* 2;
1630 case ASN_PRINTABLESTRING
:
1631 valueType
= CERT_RDN_PRINTABLE_STRING
;
1632 bytesNeeded
+= dataLen
* 2;
1635 valueType
= CERT_RDN_IA5_STRING
;
1636 bytesNeeded
+= dataLen
* 2;
1639 valueType
= CERT_RDN_T61_STRING
;
1640 bytesNeeded
+= dataLen
* 2;
1642 case ASN_VIDEOTEXSTRING
:
1643 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1644 bytesNeeded
+= dataLen
* 2;
1646 case ASN_GRAPHICSTRING
:
1647 valueType
= CERT_RDN_GRAPHIC_STRING
;
1648 bytesNeeded
+= dataLen
* 2;
1650 case ASN_VISIBLESTRING
:
1651 valueType
= CERT_RDN_VISIBLE_STRING
;
1652 bytesNeeded
+= dataLen
* 2;
1654 case ASN_GENERALSTRING
:
1655 valueType
= CERT_RDN_GENERAL_STRING
;
1656 bytesNeeded
+= dataLen
* 2;
1658 case ASN_UNIVERSALSTRING
:
1659 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1660 bytesNeeded
+= dataLen
/ 2;
1663 valueType
= CERT_RDN_BMP_STRING
;
1664 bytesNeeded
+= dataLen
;
1666 case ASN_UTF8STRING
:
1667 valueType
= CERT_RDN_UTF8_STRING
;
1668 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1669 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1672 SetLastError(CRYPT_E_ASN1_BADTAG
);
1677 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1679 *pcbStructInfo
= bytesNeeded
;
1680 else if (*pcbStructInfo
< bytesNeeded
)
1682 *pcbStructInfo
= bytesNeeded
;
1683 SetLastError(ERROR_MORE_DATA
);
1688 *pcbStructInfo
= bytesNeeded
;
1689 value
->dwValueType
= valueType
;
1693 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1695 assert(value
->Value
.pbData
);
1696 switch (pbEncoded
[0])
1698 case ASN_NUMERICSTRING
:
1699 case ASN_PRINTABLESTRING
:
1702 case ASN_VIDEOTEXSTRING
:
1703 case ASN_GRAPHICSTRING
:
1704 case ASN_VISIBLESTRING
:
1705 case ASN_GENERALSTRING
:
1706 value
->Value
.cbData
= dataLen
* 2;
1707 for (i
= 0; i
< dataLen
; i
++)
1708 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1710 case ASN_UNIVERSALSTRING
:
1711 value
->Value
.cbData
= dataLen
/ 2;
1712 for (i
= 0; i
< dataLen
/ 4; i
++)
1713 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1714 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1717 value
->Value
.cbData
= dataLen
;
1718 for (i
= 0; i
< dataLen
/ 2; i
++)
1719 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1720 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1722 case ASN_UTF8STRING
:
1723 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1724 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1725 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1731 value
->Value
.cbData
= 0;
1732 value
->Value
.pbData
= NULL
;
1739 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1740 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1741 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1747 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1748 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1749 if (ret
&& pvStructInfo
)
1751 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1752 pcbStructInfo
, *pcbStructInfo
);
1755 CERT_NAME_VALUE
*value
;
1757 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1758 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1759 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1760 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1761 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1762 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1763 pcbStructInfo
, NULL
);
1769 SetLastError(STATUS_ACCESS_VIOLATION
);
1776 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1777 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1780 struct AsnDecodeSequenceItem items
[] = {
1781 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1782 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1783 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1784 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1785 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1786 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1788 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1790 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1791 pvStructInfo
, *pcbStructInfo
);
1794 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1795 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1796 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1797 attr
? attr
->pszObjId
: NULL
);
1800 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1801 debugstr_a(attr
->pszObjId
));
1802 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1804 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1808 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1809 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1812 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1813 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1814 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1815 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1817 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1818 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1819 rdn
? rdn
->rgRDNAttr
: NULL
);
1823 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1824 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1825 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1831 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1832 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1833 offsetof(CERT_RDN
, rgRDNAttr
) };
1835 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1836 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1840 SetLastError(STATUS_ACCESS_VIOLATION
);
1847 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1848 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1852 struct AsnDecodeSequenceItem items
[] = {
1853 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1854 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1855 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1856 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1857 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1858 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1860 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1862 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1863 pvStructInfo
, *pcbStructInfo
);
1866 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1867 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1868 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1869 attr
? attr
->pszObjId
: NULL
);
1872 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1873 debugstr_a(attr
->pszObjId
));
1874 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1876 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1880 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1881 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1884 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1885 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1886 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1887 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1889 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1890 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1891 rdn
? rdn
->rgRDNAttr
: NULL
);
1895 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1896 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1897 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1903 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1904 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1905 offsetof(CERT_RDN
, rgRDNAttr
) };
1907 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1908 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1912 SetLastError(STATUS_ACCESS_VIOLATION
);
1919 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1922 BOOL ret
= TRUE
, done
= FALSE
;
1923 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
1925 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
1932 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
1935 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1937 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
1939 indefiniteNestingLevels
++;
1940 pbEncoded
+= 1 + lenBytes
;
1941 cbEncoded
-= 1 + lenBytes
;
1942 decoded
+= 1 + lenBytes
;
1943 TRACE("indefiniteNestingLevels = %d\n",
1944 indefiniteNestingLevels
);
1948 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
1949 indefiniteNestingLevels
)
1951 indefiniteNestingLevels
--;
1952 TRACE("indefiniteNestingLevels = %d\n",
1953 indefiniteNestingLevels
);
1955 pbEncoded
+= 1 + lenBytes
+ dataLen
;
1956 cbEncoded
-= 1 + lenBytes
+ dataLen
;
1957 decoded
+= 1 + lenBytes
+ dataLen
;
1958 if (!indefiniteNestingLevels
)
1962 } while (ret
&& !done
);
1963 /* If we haven't found all 0 TLVs, we haven't found the end */
1964 if (ret
&& indefiniteNestingLevels
)
1966 SetLastError(CRYPT_E_ASN1_EOD
);
1970 *pcbDecoded
= decoded
;
1971 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
1975 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
1976 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1980 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
1982 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1983 pvStructInfo
, *pcbStructInfo
);
1985 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
1987 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1988 bytesNeeded
+= encodedLen
;
1990 *pcbStructInfo
= bytesNeeded
;
1991 else if (*pcbStructInfo
< bytesNeeded
)
1993 SetLastError(ERROR_MORE_DATA
);
1994 *pcbStructInfo
= bytesNeeded
;
1999 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
2001 *pcbStructInfo
= bytesNeeded
;
2002 blob
->cbData
= encodedLen
;
2005 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2006 blob
->pbData
= (LPBYTE
)pbEncoded
;
2009 assert(blob
->pbData
);
2010 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2014 blob
->pbData
= NULL
;
2017 *pcbDecoded
= encodedLen
;
2022 static BOOL
CRYPT_DecodeDERArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2023 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2026 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
2027 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2028 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
2030 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2031 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2033 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2034 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2035 array
? array
->rgItems
: NULL
);
2039 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2040 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2043 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2044 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2045 CTL_USAGE
*usage
= (CTL_USAGE
*)pvStructInfo
;
2047 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2048 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2049 usage
? usage
->rgpszUsageIdentifier
: NULL
);
2053 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2054 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2056 struct AsnDecodeSequenceItem items
[] = {
2057 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2058 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2059 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2060 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2061 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
), FALSE
,
2062 TRUE
, offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2065 CTL_ENTRY
*entry
= (CTL_ENTRY
*)pvStructInfo
;
2067 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2070 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2071 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2072 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2076 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2077 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2080 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2081 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2082 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2083 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2085 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2086 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2088 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2089 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2090 entries
? entries
->rgItems
: NULL
);
2094 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2095 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2096 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2100 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2101 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2105 struct AsnDecodeSequenceItem items
[] = {
2106 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2107 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2108 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2109 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2110 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2111 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2112 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2113 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2114 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2115 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2116 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2117 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2118 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2120 { 0, offsetof(CTL_INFO
, NextUpdate
),
2121 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2123 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2124 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2125 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2126 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2127 CRYPT_AsnDecodeCTLEntries
, sizeof(struct GenericArray
),
2128 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2129 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2130 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
2131 offsetof(CTL_INFO
, rgExtension
), 0 },
2134 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2135 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2137 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2138 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2139 pcbStructInfo
, NULL
, NULL
);
2143 SetLastError(STATUS_ACCESS_VIOLATION
);
2149 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2150 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2154 struct AsnDecodeSequenceItem items
[] = {
2155 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2156 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2157 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2158 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2159 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2160 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2162 PCRYPT_SMIME_CAPABILITY capability
= (PCRYPT_SMIME_CAPABILITY
)pvStructInfo
;
2164 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2165 pvStructInfo
, *pcbStructInfo
);
2167 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2168 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2169 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2170 TRACE("returning %d\n", ret
);
2174 static BOOL
CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE
*pbEncoded
,
2175 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2178 struct AsnArrayDescriptor arrayDesc
= { 0,
2179 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2180 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2181 PCRYPT_SMIME_CAPABILITIES capabilities
=
2182 (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2185 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2186 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2187 capabilities
? capabilities
->rgCapability
: NULL
);
2191 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2192 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2193 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2197 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2198 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2205 SetLastError(CRYPT_E_ASN1_EOD
);
2206 else if (pbEncoded
[0] != ASN_SEQUENCEOF
)
2207 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2208 else if ((ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2209 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2213 *pcbStructInfo
= bytesNeeded
;
2214 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2215 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2217 PCRYPT_SMIME_CAPABILITIES capabilities
;
2219 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2220 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2221 capabilities
= (PCRYPT_SMIME_CAPABILITIES
)pvStructInfo
;
2222 capabilities
->rgCapability
=
2223 (PCRYPT_SMIME_CAPABILITY
)((BYTE
*)pvStructInfo
+
2224 sizeof(CRYPT_SMIME_CAPABILITIES
));
2225 ret
= CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded
,
2226 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2227 &bytesNeeded
, NULL
);
2233 SetLastError(STATUS_ACCESS_VIOLATION
);
2236 TRACE("returning %d\n", ret
);
2240 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2241 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2245 struct AsnDecodeSequenceItem items
[] = {
2246 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2247 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2248 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2249 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2250 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
2251 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2253 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2255 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2256 pvStructInfo
, *pcbStructInfo
);
2258 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2259 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2260 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2261 TRACE("returning %d\n", ret
);
2265 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2266 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2267 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2271 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2272 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2278 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2279 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2283 *pcbStructInfo
= bytesNeeded
;
2284 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2285 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2287 PCRYPT_ATTRIBUTE attr
;
2289 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2290 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2291 attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2292 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2293 sizeof(CRYPT_ATTRIBUTE
));
2294 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2295 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2302 SetLastError(STATUS_ACCESS_VIOLATION
);
2305 TRACE("returning %d\n", ret
);
2309 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2310 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2313 struct AsnArrayDescriptor arrayDesc
= { 0,
2314 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2315 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2316 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2319 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2320 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2325 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2326 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2327 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2331 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2332 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2339 SetLastError(CRYPT_E_ASN1_EOD
);
2340 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2341 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2342 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2343 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2347 *pcbStructInfo
= bytesNeeded
;
2348 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2349 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2351 PCRYPT_ATTRIBUTES attrs
;
2353 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2354 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2355 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2356 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2357 sizeof(CRYPT_ATTRIBUTES
));
2358 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2359 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2360 &bytesNeeded
, NULL
);
2366 SetLastError(STATUS_ACCESS_VIOLATION
);
2369 TRACE("returning %d\n", ret
);
2373 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2374 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2376 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
2377 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
2379 struct AsnDecodeSequenceItem items
[] = {
2380 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2381 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2382 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2383 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2384 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2385 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2388 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2389 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2391 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2392 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2393 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2394 if (ret
&& pvStructInfo
)
2396 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2397 debugstr_a(algo
->pszObjId
));
2402 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2403 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2407 struct AsnDecodeSequenceItem items
[] = {
2408 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2409 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2410 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2411 Algorithm
.pszObjId
) },
2412 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2413 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2414 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2416 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2418 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2419 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2420 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2424 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2425 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2426 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2434 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2435 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2438 *pcbStructInfo
= bytesNeeded
;
2439 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2440 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2442 PCERT_PUBLIC_KEY_INFO info
;
2444 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2445 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2446 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2447 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2448 sizeof(CERT_PUBLIC_KEY_INFO
);
2449 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2450 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2451 &bytesNeeded
, NULL
);
2457 SetLastError(STATUS_ACCESS_VIOLATION
);
2464 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2465 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2471 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2474 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2476 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2479 if (pbEncoded
[1] > 1)
2481 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2488 *pcbStructInfo
= sizeof(BOOL
);
2491 else if (*pcbStructInfo
< sizeof(BOOL
))
2493 *pcbStructInfo
= sizeof(BOOL
);
2494 SetLastError(ERROR_MORE_DATA
);
2499 *pcbStructInfo
= sizeof(BOOL
);
2500 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2503 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2507 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2508 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2510 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2511 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2514 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2515 pvStructInfo
, *pcbStructInfo
);
2519 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2522 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2523 if (1 + lenBytes
> cbEncoded
)
2525 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2528 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2530 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2532 case 1: /* rfc822Name */
2533 case 2: /* dNSName */
2534 case 6: /* uniformResourceIdentifier */
2535 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2537 case 4: /* directoryName */
2538 case 7: /* iPAddress */
2539 bytesNeeded
+= dataLen
;
2541 case 8: /* registeredID */
2542 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2546 /* FIXME: ugly, shouldn't need to know internals of OID decode
2547 * function to use it.
2549 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2552 case 0: /* otherName */
2553 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2554 SetLastError(CRYPT_E_ASN1_BADTAG
);
2557 case 3: /* x400Address, unimplemented */
2558 case 5: /* ediPartyName, unimplemented */
2559 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2560 SetLastError(CRYPT_E_ASN1_BADTAG
);
2564 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2565 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2571 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2573 *pcbStructInfo
= bytesNeeded
;
2574 else if (*pcbStructInfo
< bytesNeeded
)
2576 *pcbStructInfo
= bytesNeeded
;
2577 SetLastError(ERROR_MORE_DATA
);
2582 *pcbStructInfo
= bytesNeeded
;
2583 /* MS used values one greater than the asn1 ones.. sigh */
2584 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2585 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2587 case 1: /* rfc822Name */
2588 case 2: /* dNSName */
2589 case 6: /* uniformResourceIdentifier */
2593 for (i
= 0; i
< dataLen
; i
++)
2594 entry
->u
.pwszURL
[i
] =
2595 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2596 entry
->u
.pwszURL
[i
] = 0;
2597 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2598 debugstr_w(entry
->u
.pwszURL
));
2601 case 4: /* directoryName */
2602 entry
->dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
2603 /* The data are memory-equivalent with the IPAddress case,
2606 case 7: /* iPAddress */
2607 /* The next data pointer is in the pwszURL spot, that is,
2608 * the first 4 bytes. Need to move it to the next spot.
2610 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2611 entry
->u
.IPAddress
.cbData
= dataLen
;
2612 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2615 case 8: /* registeredID */
2616 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2617 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2626 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
2627 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2631 struct AsnArrayDescriptor arrayDesc
= { 0,
2632 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2633 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2634 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2636 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2637 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2640 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2641 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2642 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2643 info
? info
->rgAltEntry
: NULL
);
2647 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2648 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
2649 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2654 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2655 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2657 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2660 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
2661 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
2663 if (ret
&& pvStructInfo
)
2665 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2672 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
2674 temp
= blob
->pbData
[i
];
2675 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
2676 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
2680 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2684 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2685 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2686 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2692 struct AsnDecodeSequenceItem items
[] = {
2693 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2694 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2695 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2696 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2697 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2698 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2699 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2700 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2701 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2702 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2703 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2706 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2707 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2708 pcbStructInfo
, NULL
, NULL
);
2712 SetLastError(STATUS_ACCESS_VIOLATION
);
2719 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2720 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2721 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2727 struct AsnDecodeSequenceItem items
[] = {
2728 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2729 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2730 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2731 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2732 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2733 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2734 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2735 AuthorityCertIssuer
.rgAltEntry
), 0 },
2736 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2737 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2738 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2739 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2740 AuthorityCertSerialNumber
.pbData
), 0 },
2743 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2744 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2745 pcbStructInfo
, NULL
, NULL
);
2749 SetLastError(STATUS_ACCESS_VIOLATION
);
2756 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
2757 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2760 struct AsnDecodeSequenceItem items
[] = {
2761 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
2762 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
2763 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
2764 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
2765 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
2766 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
2768 CERT_ACCESS_DESCRIPTION
*descr
= (CERT_ACCESS_DESCRIPTION
*)pvStructInfo
;
2770 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2771 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2772 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
2775 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
2776 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2777 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2781 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2782 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2786 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2787 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
2788 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
2790 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2791 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2795 SetLastError(STATUS_ACCESS_VIOLATION
);
2802 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2803 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2808 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2809 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2811 /* The caller has already checked the tag, no need to check it again.
2812 * Check the outer length is valid:
2814 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
2816 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2819 pbEncoded
+= 1 + lenBytes
;
2820 cbEncoded
-= 1 + lenBytes
;
2821 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2822 cbEncoded
-= 2; /* space for 0 TLV */
2823 /* Check the inner length is valid: */
2824 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
2828 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
2829 pvStructInfo
, pcbStructInfo
, &decodedLen
);
2830 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2832 if (*(pbEncoded
+ decodedLen
) != 0 ||
2833 *(pbEncoded
+ decodedLen
+ 1) != 0)
2835 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2836 *(pbEncoded
+ decodedLen
),
2837 *(pbEncoded
+ decodedLen
+ 1));
2838 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2844 if (ret
&& pcbDecoded
)
2846 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
2847 TRACE("decoded %d bytes\n", *pcbDecoded
);
2854 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
2855 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2858 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2859 struct AsnDecodeSequenceItem items
[] = {
2860 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2861 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2862 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2863 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2864 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2865 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2866 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2870 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2871 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2873 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2874 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2875 pcbDecoded
, info
? info
->pszObjId
: NULL
);
2879 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2880 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2881 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2885 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2886 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2890 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
2891 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
2892 if (ret
&& pvStructInfo
)
2894 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2895 pcbStructInfo
, *pcbStructInfo
);
2898 CRYPT_CONTENT_INFO
*info
;
2900 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2901 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2902 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2903 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2904 sizeof(CRYPT_CONTENT_INFO
));
2905 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
2906 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2907 pcbStructInfo
, NULL
);
2913 SetLastError(STATUS_ACCESS_VIOLATION
);
2919 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2920 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2921 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2924 struct AsnDecodeSequenceItem items
[] = {
2925 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
2926 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2927 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2928 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2929 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2931 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2932 CRYPT_AsnDecodePKCSContentInfoInternal
,
2933 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2934 ContentInfo
.pszObjId
), 0 },
2935 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2936 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2937 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2940 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2941 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
2946 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2947 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2948 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2952 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2953 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2959 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2960 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2963 *pcbStructInfo
= bytesNeeded
;
2964 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2965 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2967 CERT_ALT_NAME_INFO
*name
;
2969 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2970 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2971 name
= (CERT_ALT_NAME_INFO
*)pvStructInfo
;
2972 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
2973 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
2974 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2975 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2976 &bytesNeeded
, NULL
);
2982 SetLastError(STATUS_ACCESS_VIOLATION
);
2989 struct PATH_LEN_CONSTRAINT
2991 BOOL fPathLenConstraint
;
2992 DWORD dwPathLenConstraint
;
2995 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
2996 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3000 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3002 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3003 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3007 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3009 *pcbStructInfo
= bytesNeeded
;
3011 else if (*pcbStructInfo
< bytesNeeded
)
3013 SetLastError(ERROR_MORE_DATA
);
3014 *pcbStructInfo
= bytesNeeded
;
3019 struct PATH_LEN_CONSTRAINT
*constraint
=
3020 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
3022 *pcbStructInfo
= bytesNeeded
;
3023 size
= sizeof(constraint
->dwPathLenConstraint
);
3024 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3025 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3027 constraint
->fPathLenConstraint
= TRUE
;
3028 TRACE("got an int, dwPathLenConstraint is %d\n",
3029 constraint
->dwPathLenConstraint
);
3031 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3035 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3036 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3040 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3041 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3042 offsetof(CERT_NAME_BLOB
, pbData
) };
3043 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
3045 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3046 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3048 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3049 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
3050 entries
? entries
->rgItems
: NULL
);
3051 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3055 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3056 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3057 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3063 struct AsnDecodeSequenceItem items
[] = {
3064 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3065 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3066 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3067 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3068 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3069 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3070 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3071 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3072 sizeof(struct GenericArray
), TRUE
, TRUE
,
3073 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3076 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3077 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3078 pcbStructInfo
, NULL
, NULL
);
3082 SetLastError(STATUS_ACCESS_VIOLATION
);
3089 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3090 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3091 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3097 struct AsnDecodeSequenceItem items
[] = {
3098 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3099 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3100 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3101 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3102 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3105 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3106 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3107 pcbStructInfo
, NULL
, NULL
);
3111 SetLastError(STATUS_ACCESS_VIOLATION
);
3118 #define RSA1_MAGIC 0x31415352
3120 struct DECODED_RSA_PUB_KEY
3123 CRYPT_INTEGER_BLOB modulus
;
3126 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3127 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3128 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3134 struct AsnDecodeSequenceItem items
[] = {
3135 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3136 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3137 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3139 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3140 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3142 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3145 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3146 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3150 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3151 decodedKey
->modulus
.cbData
;
3155 *pcbStructInfo
= bytesNeeded
;
3158 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3159 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3162 RSAPUBKEY
*rsaPubKey
;
3164 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3165 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3166 hdr
= (BLOBHEADER
*)pvStructInfo
;
3167 hdr
->bType
= PUBLICKEYBLOB
;
3168 hdr
->bVersion
= CUR_BLOB_VERSION
;
3170 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3171 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3172 sizeof(BLOBHEADER
));
3173 rsaPubKey
->magic
= RSA1_MAGIC
;
3174 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3175 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3176 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3177 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3178 decodedKey
->modulus
.cbData
);
3180 LocalFree(decodedKey
);
3185 SetLastError(STATUS_ACCESS_VIOLATION
);
3192 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3193 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3197 DWORD bytesNeeded
, dataLen
;
3199 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3200 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3202 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3204 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3206 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3207 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3209 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3211 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3213 *pcbStructInfo
= bytesNeeded
;
3214 else if (*pcbStructInfo
< bytesNeeded
)
3216 SetLastError(ERROR_MORE_DATA
);
3217 *pcbStructInfo
= bytesNeeded
;
3222 CRYPT_DATA_BLOB
*blob
;
3224 *pcbStructInfo
= bytesNeeded
;
3225 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3226 blob
->cbData
= dataLen
;
3227 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3228 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3231 assert(blob
->pbData
);
3233 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3241 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3242 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3243 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3247 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3248 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3256 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3259 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3261 SetLastError(CRYPT_E_ASN1_BADTAG
);
3264 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3265 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3268 *pcbStructInfo
= bytesNeeded
;
3269 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3270 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3272 CRYPT_DATA_BLOB
*blob
;
3274 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3275 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3276 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
3277 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3278 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3279 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3280 &bytesNeeded
, NULL
);
3286 SetLastError(STATUS_ACCESS_VIOLATION
);
3293 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3294 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3298 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3299 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3301 if (pbEncoded
[0] == ASN_BITSTRING
)
3303 DWORD bytesNeeded
, dataLen
;
3304 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3306 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3308 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3309 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3311 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3313 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3315 *pcbStructInfo
= bytesNeeded
;
3316 else if (*pcbStructInfo
< bytesNeeded
)
3318 *pcbStructInfo
= bytesNeeded
;
3319 SetLastError(ERROR_MORE_DATA
);
3324 CRYPT_BIT_BLOB
*blob
;
3326 *pcbStructInfo
= bytesNeeded
;
3327 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3328 blob
->cbData
= dataLen
- 1;
3329 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3330 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3332 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3336 assert(blob
->pbData
);
3339 BYTE mask
= 0xff << blob
->cUnusedBits
;
3341 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3343 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3351 SetLastError(CRYPT_E_ASN1_BADTAG
);
3354 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3358 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3359 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3360 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3364 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3365 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3371 if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3372 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3375 *pcbStructInfo
= bytesNeeded
;
3376 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3377 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3379 CRYPT_BIT_BLOB
*blob
;
3381 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3382 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3383 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3384 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3385 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3386 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3387 &bytesNeeded
, NULL
);
3393 SetLastError(STATUS_ACCESS_VIOLATION
);
3397 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3401 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3402 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3403 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3406 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3407 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3408 DWORD size
= sizeof(buf
);
3410 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3411 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, buf
,
3416 *pcbStructInfo
= sizeof(int);
3417 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3421 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3423 /* initialize to a negative value to sign-extend */
3428 for (i
= 0; i
< blob
->cbData
; i
++)
3431 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3433 memcpy(pvStructInfo
, &val
, sizeof(int));
3436 else if (GetLastError() == ERROR_MORE_DATA
)
3437 SetLastError(CRYPT_E_ASN1_LARGE
);
3441 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3442 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3443 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3453 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3456 else if (pbEncoded
[0] != ASN_INTEGER
)
3458 SetLastError(CRYPT_E_ASN1_BADTAG
);
3462 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3463 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3467 *pcbStructInfo
= bytesNeeded
;
3468 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3469 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3471 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3472 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3473 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3474 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3475 &bytesNeeded
, NULL
);
3481 SetLastError(STATUS_ACCESS_VIOLATION
);
3488 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
3489 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3493 DWORD bytesNeeded
, dataLen
;
3495 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3497 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3499 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3501 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3503 *pcbStructInfo
= bytesNeeded
;
3504 else if (*pcbStructInfo
< bytesNeeded
)
3506 *pcbStructInfo
= bytesNeeded
;
3507 SetLastError(ERROR_MORE_DATA
);
3512 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3514 *pcbStructInfo
= bytesNeeded
;
3515 blob
->cbData
= dataLen
;
3516 assert(blob
->pbData
);
3521 for (i
= 0; i
< blob
->cbData
; i
++)
3523 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3532 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3533 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3534 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3542 if (pbEncoded
[0] != ASN_INTEGER
)
3544 SetLastError(CRYPT_E_ASN1_BADTAG
);
3548 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3549 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3553 *pcbStructInfo
= bytesNeeded
;
3554 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3555 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3557 CRYPT_INTEGER_BLOB
*blob
;
3559 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3560 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3561 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3562 blob
->pbData
= (BYTE
*)pvStructInfo
+
3563 sizeof(CRYPT_INTEGER_BLOB
);
3564 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3565 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3566 &bytesNeeded
, NULL
);
3572 SetLastError(STATUS_ACCESS_VIOLATION
);
3579 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
3580 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3585 if (pbEncoded
[0] == ASN_INTEGER
)
3587 DWORD bytesNeeded
, dataLen
;
3589 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3591 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3594 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3595 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3597 *pcbStructInfo
= bytesNeeded
;
3598 else if (*pcbStructInfo
< bytesNeeded
)
3600 *pcbStructInfo
= bytesNeeded
;
3601 SetLastError(ERROR_MORE_DATA
);
3606 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3608 *pcbStructInfo
= bytesNeeded
;
3609 blob
->cbData
= dataLen
;
3610 assert(blob
->pbData
);
3611 /* remove leading zero byte if it exists */
3612 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3621 for (i
= 0; i
< blob
->cbData
; i
++)
3623 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3632 SetLastError(CRYPT_E_ASN1_BADTAG
);
3638 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3639 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3640 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3648 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
3649 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3652 *pcbStructInfo
= bytesNeeded
;
3653 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3654 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3656 CRYPT_INTEGER_BLOB
*blob
;
3658 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3659 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3660 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3661 blob
->pbData
= (BYTE
*)pvStructInfo
+
3662 sizeof(CRYPT_INTEGER_BLOB
);
3663 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
3664 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3665 &bytesNeeded
, NULL
);
3671 SetLastError(STATUS_ACCESS_VIOLATION
);
3678 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3679 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3680 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3686 *pcbStructInfo
= sizeof(int);
3691 if (pbEncoded
[0] == ASN_ENUMERATED
)
3693 unsigned int val
= 0, i
;
3697 SetLastError(CRYPT_E_ASN1_EOD
);
3700 else if (pbEncoded
[1] == 0)
3702 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3707 /* A little strange looking, but we have to accept a sign byte:
3708 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3709 * assuming a small length is okay here, it has to be in short
3712 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3714 SetLastError(CRYPT_E_ASN1_LARGE
);
3717 for (i
= 0; i
< pbEncoded
[1]; i
++)
3720 val
|= pbEncoded
[2 + i
];
3722 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3723 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3725 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3726 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3727 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3733 SetLastError(CRYPT_E_ASN1_BADTAG
);
3739 SetLastError(STATUS_ACCESS_VIOLATION
);
3746 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3749 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3754 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3756 if (!isdigit(*(pbEncoded))) \
3758 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3764 (word) += *(pbEncoded)++ - '0'; \
3769 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3770 SYSTEMTIME
*sysTime
)
3774 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3776 WORD hours
, minutes
= 0;
3777 BYTE sign
= *pbEncoded
++;
3780 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3781 if (ret
&& hours
>= 24)
3783 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3788 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3789 if (ret
&& minutes
>= 60)
3791 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3799 sysTime
->wHour
+= hours
;
3800 sysTime
->wMinute
+= minutes
;
3804 if (hours
> sysTime
->wHour
)
3807 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3810 sysTime
->wHour
-= hours
;
3811 if (minutes
> sysTime
->wMinute
)
3814 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3817 sysTime
->wMinute
-= minutes
;
3824 #define MIN_ENCODED_TIME_LENGTH 10
3826 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
3827 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3832 if (pbEncoded
[0] == ASN_UTCTIME
)
3835 SetLastError(CRYPT_E_ASN1_EOD
);
3836 else if (pbEncoded
[1] > 0x7f)
3838 /* long-form date strings really can't be valid */
3839 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3843 SYSTEMTIME sysTime
= { 0 };
3844 BYTE len
= pbEncoded
[1];
3846 if (len
< MIN_ENCODED_TIME_LENGTH
)
3847 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3852 *pcbDecoded
= 2 + len
;
3854 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3855 if (sysTime
.wYear
>= 50)
3856 sysTime
.wYear
+= 1900;
3858 sysTime
.wYear
+= 2000;
3859 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3860 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3861 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3862 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3865 if (len
>= 2 && isdigit(*pbEncoded
) &&
3866 isdigit(*(pbEncoded
+ 1)))
3867 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3869 else if (isdigit(*pbEncoded
))
3870 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3873 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3879 *pcbStructInfo
= sizeof(FILETIME
);
3880 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3882 ret
= SystemTimeToFileTime(&sysTime
,
3883 (FILETIME
*)pvStructInfo
);
3889 SetLastError(CRYPT_E_ASN1_BADTAG
);
3893 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3894 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3895 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3903 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3904 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3908 *pcbStructInfo
= bytesNeeded
;
3909 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3910 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3912 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3913 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3914 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3915 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3916 &bytesNeeded
, NULL
);
3922 SetLastError(STATUS_ACCESS_VIOLATION
);
3928 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
3929 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3934 if (pbEncoded
[0] == ASN_GENERALTIME
)
3937 SetLastError(CRYPT_E_ASN1_EOD
);
3938 else if (pbEncoded
[1] > 0x7f)
3940 /* long-form date strings really can't be valid */
3941 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3945 BYTE len
= pbEncoded
[1];
3947 if (len
< MIN_ENCODED_TIME_LENGTH
)
3948 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3951 SYSTEMTIME sysTime
= { 0 };
3955 *pcbDecoded
= 2 + len
;
3957 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3958 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3959 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3960 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3963 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3966 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3968 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3975 /* workaround macro weirdness */
3976 digits
= min(len
, 3);
3977 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3978 sysTime
.wMilliseconds
);
3981 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3987 *pcbStructInfo
= sizeof(FILETIME
);
3988 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3990 ret
= SystemTimeToFileTime(&sysTime
,
3991 (FILETIME
*)pvStructInfo
);
3997 SetLastError(CRYPT_E_ASN1_BADTAG
);
4001 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4002 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4006 InternalDecodeFunc decode
= NULL
;
4008 if (pbEncoded
[0] == ASN_UTCTIME
)
4009 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4010 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4011 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4013 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4014 pcbStructInfo
, pcbDecoded
);
4017 SetLastError(CRYPT_E_ASN1_BADTAG
);
4023 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4024 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4025 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4033 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4034 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4038 *pcbStructInfo
= bytesNeeded
;
4039 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4040 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4042 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4043 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4044 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4045 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4046 &bytesNeeded
, NULL
);
4052 SetLastError(STATUS_ACCESS_VIOLATION
);
4059 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4060 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4061 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4067 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4069 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4071 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4076 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4077 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4079 ptr
= pbEncoded
+ 1 + lenBytes
;
4080 remainingLen
= dataLen
;
4081 while (ret
&& remainingLen
)
4085 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4088 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4090 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4091 ptr
+= 1 + nextLenBytes
+ nextLen
;
4092 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4093 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4094 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4100 CRYPT_SEQUENCE_OF_ANY
*seq
;
4105 *pcbStructInfo
= bytesNeeded
;
4106 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4107 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4109 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4110 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4111 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
4112 seq
->cValue
= cValue
;
4113 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4115 nextPtr
= (BYTE
*)seq
->rgValue
+
4116 cValue
* sizeof(CRYPT_DER_BLOB
);
4117 ptr
= pbEncoded
+ 1 + lenBytes
;
4118 remainingLen
= dataLen
;
4120 while (ret
&& remainingLen
)
4124 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4127 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4129 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4131 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4132 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4135 seq
->rgValue
[i
].pbData
= nextPtr
;
4136 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4138 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4140 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4141 ptr
+= 1 + nextLenBytes
+ nextLen
;
4151 SetLastError(CRYPT_E_ASN1_BADTAG
);
4157 SetLastError(STATUS_ACCESS_VIOLATION
);
4164 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4165 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4170 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4172 DWORD bytesNeeded
, dataLen
;
4174 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4176 struct AsnArrayDescriptor arrayDesc
= {
4177 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
4178 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4179 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4180 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4185 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4186 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4187 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
4188 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4189 * as the sizeof(struct GenericArray), so don't include it in the
4190 * total bytes needed.
4192 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4193 sizeof(CERT_ALT_NAME_INFO
);
4196 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4198 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4200 *pcbStructInfo
= bytesNeeded
;
4201 else if (*pcbStructInfo
< bytesNeeded
)
4203 *pcbStructInfo
= bytesNeeded
;
4204 SetLastError(ERROR_MORE_DATA
);
4209 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
4211 *pcbStructInfo
= bytesNeeded
;
4214 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4215 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4216 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4217 0, NULL
, &name
->u
.FullName
, &nameLen
, NULL
,
4218 name
->u
.FullName
.rgAltEntry
);
4221 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4227 SetLastError(CRYPT_E_ASN1_BADTAG
);
4233 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4234 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4236 struct AsnDecodeSequenceItem items
[] = {
4237 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4238 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4239 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4240 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4241 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4242 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4243 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4244 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4245 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4246 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4250 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4251 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4256 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4257 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4258 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4262 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4263 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4267 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4268 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4269 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4271 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4272 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4276 SetLastError(STATUS_ACCESS_VIOLATION
);
4283 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
4284 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4285 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4289 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4290 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4294 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4295 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
4297 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4298 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4302 SetLastError(STATUS_ACCESS_VIOLATION
);
4309 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4310 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4311 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4315 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4316 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4320 struct AsnDecodeSequenceItem items
[] = {
4321 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4322 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4323 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4324 offsetof(CRL_ISSUING_DIST_POINT
,
4325 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4326 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4327 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4329 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4330 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4332 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4333 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4334 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4335 OnlySomeReasonFlags
.pbData
), 0 },
4336 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4337 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4340 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4341 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4342 pcbStructInfo
, NULL
, NULL
);
4346 SetLastError(STATUS_ACCESS_VIOLATION
);
4353 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
4354 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4359 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4360 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4364 SetLastError(CRYPT_E_ASN1_EOD
);
4367 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
4369 SetLastError(CRYPT_E_ASN1_BADTAG
);
4372 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4373 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
4374 pvStructInfo
? (BYTE
*)pvStructInfo
+ sizeof(BOOL
) : NULL
, pcbStructInfo
,
4376 if (ret
&& pvStructInfo
)
4377 *(BOOL
*)pvStructInfo
= TRUE
;
4378 TRACE("returning %d\n", ret
);
4382 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
4383 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4387 struct AsnDecodeSequenceItem items
[] = {
4388 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
4389 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
4390 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
4391 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
4392 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
4393 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
4394 CRYPT_AsnDecodeMaximum
, sizeof(BOOL
) + sizeof(DWORD
), TRUE
, FALSE
, 0,
4397 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)pvStructInfo
;
4399 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4400 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4402 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4403 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4404 pcbDecoded
, subtree
? (BYTE
*)subtree
->Base
.u
.pwszURL
: NULL
);
4407 TRACE("%d\n", *pcbDecoded
);
4408 if (*pcbDecoded
< cbEncoded
)
4409 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
4410 *(pbEncoded
+ *pcbDecoded
+ 1));
4412 TRACE("returning %d\n", ret
);
4416 static BOOL
CRYPT_AsnDecodeSubtreeArray(const BYTE
*pbEncoded
,
4417 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4421 struct AsnArrayDescriptor arrayDesc
= { 0,
4422 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4423 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4424 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4426 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4427 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4429 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4430 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4431 array
? array
->rgItems
: NULL
);
4436 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
4437 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4438 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4442 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4443 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4447 struct AsnDecodeSequenceItem items
[] = {
4448 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4449 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
4450 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4451 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
4452 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
4453 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4454 CRYPT_AsnDecodeSubtreeArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4455 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
4458 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4459 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4460 pcbStructInfo
, NULL
, NULL
);
4464 SetLastError(STATUS_ACCESS_VIOLATION
);
4470 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
4471 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4475 struct AsnDecodeSequenceItem items
[] = {
4476 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4477 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4479 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4480 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4481 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4483 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
4484 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
4486 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4487 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4489 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4490 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4491 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4492 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4494 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4497 TRACE("returning %d\n", ret
);
4501 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4502 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4505 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4506 struct AsnDecodeSequenceItem items
[] = {
4507 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4508 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4509 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4510 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4511 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4512 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4513 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4514 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4515 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4516 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4517 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4518 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4519 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4520 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4521 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4522 HashEncryptionAlgorithm
.pszObjId
), 0 },
4523 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4524 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4525 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4526 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4527 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4528 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4529 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4533 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4534 pvStructInfo
, *pcbStructInfo
);
4536 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4537 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4538 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
4542 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4543 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4544 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4548 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4549 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4553 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4554 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4555 if (ret
&& pvStructInfo
)
4557 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4558 pcbStructInfo
, *pcbStructInfo
);
4561 CMSG_SIGNER_INFO
*info
;
4563 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4564 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4565 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4566 info
->Issuer
.pbData
= ((BYTE
*)info
+
4567 sizeof(CMSG_SIGNER_INFO
));
4568 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
4569 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4570 pcbStructInfo
, NULL
);
4576 SetLastError(STATUS_ACCESS_VIOLATION
);
4579 TRACE("returning %d\n", ret
);
4583 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
4584 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4587 CERT_ID
*id
= (CERT_ID
*)pvStructInfo
;
4590 if (*pbEncoded
== ASN_SEQUENCEOF
)
4592 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
4593 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
4597 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
4598 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
4599 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4600 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
4602 *pcbStructInfo
= sizeof(CERT_ID
);
4605 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
4607 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
4608 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
4612 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
4613 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
4614 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
4615 sizeof(CRYPT_DATA_BLOB
);
4617 *pcbStructInfo
= sizeof(CERT_ID
);
4621 SetLastError(CRYPT_E_ASN1_BADTAG
);
4625 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
4626 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4629 CMSG_CMS_SIGNER_INFO
*info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4630 struct AsnDecodeSequenceItem items
[] = {
4631 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
4632 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4633 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
4634 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
4635 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
4636 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
4637 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4638 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4639 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4640 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
4641 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4642 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4643 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
4644 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4645 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
4646 HashEncryptionAlgorithm
.pszObjId
), 0 },
4647 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
4648 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4649 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4650 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4651 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
4652 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4653 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4657 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4658 pvStructInfo
, *pcbStructInfo
);
4660 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4661 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4662 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
4666 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
4667 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4668 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4672 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4673 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4677 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
4678 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4679 if (ret
&& pvStructInfo
)
4681 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4682 pcbStructInfo
, *pcbStructInfo
);
4685 CMSG_CMS_SIGNER_INFO
*info
;
4687 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4688 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4689 info
= (CMSG_CMS_SIGNER_INFO
*)pvStructInfo
;
4690 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
4691 sizeof(CMSG_CMS_SIGNER_INFO
));
4692 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
4693 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4694 pcbStructInfo
, NULL
);
4700 SetLastError(STATUS_ACCESS_VIOLATION
);
4703 TRACE("returning %d\n", ret
);
4707 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4708 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4711 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
4712 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
4713 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
4714 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4716 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4717 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4719 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4720 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4721 array
? array
->rgItems
: NULL
);
4725 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4726 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
4727 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
4730 struct AsnDecodeSequenceItem items
[] = {
4731 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
4732 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4733 /* Placeholder for the hash algorithms - redundant with those in the
4734 * signers, so just ignore them.
4736 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
4737 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
4738 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
4739 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
4740 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4741 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
4742 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4743 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
4744 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4745 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
4746 sizeof(struct GenericArray
), TRUE
, TRUE
,
4747 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
4748 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
4749 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4750 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
4753 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4754 pDecodePara
, signedInfo
, *pcbSignedInfo
);
4756 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4757 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
4759 TRACE("returning %d\n", ret
);
4763 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
4764 LPCSTR lpszStructType
)
4766 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4768 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
4769 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
4771 SetLastError(ERROR_FILE_NOT_FOUND
);
4774 if (!HIWORD(lpszStructType
))
4776 switch (LOWORD(lpszStructType
))
4778 case LOWORD(X509_CERT
):
4779 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
4781 case LOWORD(X509_CERT_TO_BE_SIGNED
):
4782 decodeFunc
= CRYPT_AsnDecodeCert
;
4784 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
4785 decodeFunc
= CRYPT_AsnDecodeCRL
;
4787 case LOWORD(X509_EXTENSIONS
):
4788 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4790 case LOWORD(X509_NAME_VALUE
):
4791 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4793 case LOWORD(X509_NAME
):
4794 decodeFunc
= CRYPT_AsnDecodeName
;
4796 case LOWORD(X509_PUBLIC_KEY_INFO
):
4797 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4799 case LOWORD(X509_AUTHORITY_KEY_ID
):
4800 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4802 case LOWORD(X509_ALTERNATE_NAME
):
4803 decodeFunc
= CRYPT_AsnDecodeAltName
;
4805 case LOWORD(X509_BASIC_CONSTRAINTS
):
4806 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4808 case LOWORD(X509_BASIC_CONSTRAINTS2
):
4809 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4811 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
4812 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4814 case LOWORD(X509_UNICODE_NAME
):
4815 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4817 case LOWORD(PKCS_ATTRIBUTE
):
4818 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4820 case LOWORD(X509_UNICODE_NAME_VALUE
):
4821 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4823 case LOWORD(X509_OCTET_STRING
):
4824 decodeFunc
= CRYPT_AsnDecodeOctets
;
4826 case LOWORD(X509_BITS
):
4827 case LOWORD(X509_KEY_USAGE
):
4828 decodeFunc
= CRYPT_AsnDecodeBits
;
4830 case LOWORD(X509_INTEGER
):
4831 decodeFunc
= CRYPT_AsnDecodeInt
;
4833 case LOWORD(X509_MULTI_BYTE_INTEGER
):
4834 decodeFunc
= CRYPT_AsnDecodeInteger
;
4836 case LOWORD(X509_MULTI_BYTE_UINT
):
4837 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4839 case LOWORD(X509_ENUMERATED
):
4840 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4842 case LOWORD(X509_CHOICE_OF_TIME
):
4843 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4845 case LOWORD(X509_AUTHORITY_KEY_ID2
):
4846 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4848 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
4849 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
4851 case LOWORD(PKCS_CONTENT_INFO
):
4852 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4854 case LOWORD(X509_SEQUENCE_OF_ANY
):
4855 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4857 case LOWORD(PKCS_UTC_TIME
):
4858 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4860 case LOWORD(X509_CRL_DIST_POINTS
):
4861 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4863 case LOWORD(X509_ENHANCED_KEY_USAGE
):
4864 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4866 case LOWORD(PKCS_CTL
):
4867 decodeFunc
= CRYPT_AsnDecodeCTL
;
4869 case LOWORD(PKCS_SMIME_CAPABILITIES
):
4870 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4872 case LOWORD(PKCS_ATTRIBUTES
):
4873 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4875 case LOWORD(X509_ISSUING_DIST_POINT
):
4876 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4878 case LOWORD(X509_NAME_CONSTRAINTS
):
4879 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4881 case LOWORD(PKCS7_SIGNER_INFO
):
4882 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4884 case LOWORD(CMS_SIGNER_INFO
):
4885 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
4889 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4890 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4891 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4892 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4893 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
4894 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
4895 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4896 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4897 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4898 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4899 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4900 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4901 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4902 decodeFunc
= CRYPT_AsnDecodeBits
;
4903 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4904 decodeFunc
= CRYPT_AsnDecodeOctets
;
4905 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4906 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4907 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4908 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4909 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4910 decodeFunc
= CRYPT_AsnDecodeAltName
;
4911 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4912 decodeFunc
= CRYPT_AsnDecodeAltName
;
4913 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4914 decodeFunc
= CRYPT_AsnDecodeAltName
;
4915 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4916 decodeFunc
= CRYPT_AsnDecodeAltName
;
4917 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4918 decodeFunc
= CRYPT_AsnDecodeAltName
;
4919 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4920 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4921 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4922 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4923 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4924 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4925 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
4926 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
4927 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
4928 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
4929 else if (!strcmp(lpszStructType
, szOID_CTL
))
4930 decodeFunc
= CRYPT_AsnDecodeCTL
;
4934 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
4935 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4937 static HCRYPTOIDFUNCSET set
= NULL
;
4938 CryptDecodeObjectFunc decodeFunc
= NULL
;
4941 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
4942 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4943 (void **)&decodeFunc
, hFunc
);
4947 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
4948 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4950 static HCRYPTOIDFUNCSET set
= NULL
;
4951 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4954 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4955 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4956 (void **)&decodeFunc
, hFunc
);
4960 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4961 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
4962 DWORD
*pcbStructInfo
)
4965 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
4966 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
4967 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4969 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
4970 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
4971 pvStructInfo
, pcbStructInfo
);
4973 if (!pvStructInfo
&& !pcbStructInfo
)
4975 SetLastError(ERROR_INVALID_PARAMETER
);
4980 SetLastError(CRYPT_E_ASN1_EOD
);
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
);
5032 SetLastError(CRYPT_E_ASN1_EOD
);
5035 if (cbEncoded
> MAX_ENCODED_LEN
)
5037 SetLastError(CRYPT_E_ASN1_LARGE
);
5041 SetLastError(NOERROR
);
5042 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5043 *(BYTE
**)pvStructInfo
= NULL
;
5044 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5047 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5048 debugstr_a(lpszStructType
));
5049 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5053 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5054 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5057 CryptDecodeObjectFunc pCryptDecodeObject
=
5058 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5060 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5061 * directly, as that could cause an infinite loop.
5063 if (pCryptDecodeObject
)
5065 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5067 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5068 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5069 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5070 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5071 ret
= pCryptDecodeObject(dwCertEncodingType
,
5072 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5073 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5076 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5077 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5081 CryptFreeOIDFunctionAddress(hFunc
, 0);
5082 TRACE_(crypt
)("returning %d\n", ret
);