2 * Copyright 2005-2007 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"
38 #define NONAMELESSUNION
45 #include "wine/debug.h"
46 #include "wine/exception.h"
47 #include "crypt32_private.h"
49 /* This is a bit arbitrary, but to set some limit: */
50 #define MAX_ENCODED_LEN 0x02000000
52 #define ASN_FLAGS_MASK 0xe0
53 #define ASN_TYPE_MASK 0x1f
55 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
56 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
64 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
65 DWORD
, DWORD
, void *, DWORD
*);
66 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
67 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
69 /* Internal decoders don't do memory allocation or exception handling, and
70 * they report how many bytes they decoded.
72 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
73 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
75 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
76 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
78 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
82 * time, doesn't do memory allocation, and doesn't do exception handling.
84 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
85 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
87 /* Assumes algo->Parameters.pbData is set ahead of time. */
88 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
89 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
90 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
91 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
92 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
93 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
94 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
96 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
97 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
98 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
99 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
100 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
101 * member has been initialized, doesn't do exception handling, and doesn't do
102 * memory allocation. Also doesn't check tag, assumes the caller has checked
105 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
106 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
108 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
109 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
113 /* Gets the number of length bytes from the given (leading) length byte */
114 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
116 /* Helper function to get the encoded length of the data starting at pbEncoded,
117 * where pbEncoded[0] is the tag. If the data are too short to contain a
118 * length or if the length is too large for cbEncoded, sets an appropriate
119 * error code and returns FALSE. If the encoded length is unknown due to
120 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
122 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
129 SetLastError(CRYPT_E_ASN1_CORRUPT
);
132 else if (pbEncoded
[1] <= 0x7f)
134 if (pbEncoded
[1] + 1 > cbEncoded
)
136 SetLastError(CRYPT_E_ASN1_EOD
);
145 else if (pbEncoded
[1] == 0x80)
147 *len
= CMSG_INDEFINITE_LENGTH
;
152 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
154 if (lenLen
> sizeof(DWORD
) + 1)
156 SetLastError(CRYPT_E_ASN1_LARGE
);
159 else if (lenLen
+ 2 > cbEncoded
)
161 SetLastError(CRYPT_E_ASN1_CORRUPT
);
174 if (out
+ lenLen
+ 1 > cbEncoded
)
176 SetLastError(CRYPT_E_ASN1_EOD
);
189 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
190 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
194 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
195 *len
== CMSG_INDEFINITE_LENGTH
)
197 SetLastError(CRYPT_E_ASN1_CORRUPT
);
203 /* Helper function to check *pcbStructInfo, set it to the required size, and
204 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
205 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
206 * pointer to the newly allocated memory.
208 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
209 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
214 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
216 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
217 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
219 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
220 if (!*(BYTE
**)pvStructInfo
)
223 *pcbStructInfo
= bytesNeeded
;
225 else if (*pcbStructInfo
< bytesNeeded
)
227 *pcbStructInfo
= bytesNeeded
;
228 SetLastError(ERROR_MORE_DATA
);
234 /* Helper function to check *pcbStructInfo and set it to the required size.
235 * Assumes pvStructInfo is not NULL.
237 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
241 if (*pcbStructInfo
< bytesNeeded
)
243 *pcbStructInfo
= bytesNeeded
;
244 SetLastError(ERROR_MORE_DATA
);
249 *pcbStructInfo
= bytesNeeded
;
256 * The expected tag of the item. If tag is 0, decodeFunc is called
257 * regardless of the tag value seen.
259 * A sequence is decoded into a struct. The offset member is the
260 * offset of this item within that struct.
262 * The decoder function to use. If this is NULL, then the member isn't
263 * decoded, but minSize space is reserved for it.
265 * The minimum amount of space occupied after decoding. You must set this.
267 * If true, and the tag doesn't match the expected tag for this item,
268 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
269 * filled with 0 for this member.
270 * hasPointer, pointerOffset:
271 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
272 * the offset within the struct of the data pointer (or to the
273 * first data pointer, if more than one exist).
275 * Used by CRYPT_AsnDecodeSequence, not for your use.
277 struct AsnDecodeSequenceItem
281 InternalDecodeFunc decodeFunc
;
289 /* Decodes the items in a sequence, where the items are described in items,
290 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
291 * pvStructInfo. nextData is a pointer to the memory location at which the
292 * first decoded item with a dynamic pointer should point.
293 * Upon decoding, *cbDecoded is the total number of bytes decoded.
294 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
296 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
297 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
298 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
301 DWORD i
, decoded
= 0;
302 const BYTE
*ptr
= pbEncoded
;
304 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
305 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
307 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
309 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
313 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
314 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
316 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
318 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
320 DWORD itemEncodedLen
;
322 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
323 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
325 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
326 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
328 TRACE("Setting next pointer to %p\n",
330 *(BYTE
**)((BYTE
*)pvStructInfo
+
331 items
[i
].pointerOffset
) = nextData
;
333 if (items
[i
].decodeFunc
)
338 TRACE("decoding item %d\n", i
);
340 TRACE("sizing item %d\n", i
);
341 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
342 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
343 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
344 : NULL
, &items
[i
].size
, &itemDecoded
);
347 /* Account for alignment padding */
348 if (items
[i
].size
% sizeof(DWORD_PTR
))
349 items
[i
].size
+= sizeof(DWORD_PTR
) -
350 items
[i
].size
% sizeof(DWORD_PTR
);
351 TRACE("item %d size: %d\n", i
, items
[i
].size
);
352 if (nextData
&& items
[i
].hasPointer
&&
353 items
[i
].size
> items
[i
].minSize
)
354 nextData
+= items
[i
].size
- items
[i
].minSize
;
355 if (itemDecoded
> itemEncodedLen
)
357 WARN("decoded length %d exceeds encoded %d\n",
358 itemDecoded
, itemEncodedLen
);
359 SetLastError(CRYPT_E_ASN1_CORRUPT
);
364 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
366 if (itemDecoded
> itemEncodedLen
- 2 ||
367 *(ptr
+ itemDecoded
) != 0 ||
368 *(ptr
+ itemDecoded
+ 1) != 0)
370 TRACE("expected 0 TLV\n");
371 SetLastError(CRYPT_E_ASN1_CORRUPT
);
380 decoded
+= itemDecoded
;
381 TRACE("item %d: decoded %d bytes\n", i
,
386 else if (items
[i
].optional
&&
387 GetLastError() == CRYPT_E_ASN1_BADTAG
)
389 TRACE("skipping optional item %d\n", i
);
390 items
[i
].size
= items
[i
].minSize
;
391 SetLastError(NOERROR
);
395 TRACE("item %d failed: %08x\n", i
,
398 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT
);
406 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
407 ptr
+= itemEncodedLen
;
408 decoded
+= itemEncodedLen
;
409 items
[i
].size
= items
[i
].minSize
;
412 else if (items
[i
].optional
)
414 TRACE("skipping optional item %d\n", i
);
415 items
[i
].size
= items
[i
].minSize
;
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i
, ptr
[0], items
[i
].tag
);
421 SetLastError(CRYPT_E_ASN1_BADTAG
);
426 else if (items
[i
].optional
)
428 TRACE("missing optional item %d, skipping\n", i
);
429 items
[i
].size
= items
[i
].minSize
;
433 TRACE("not enough bytes for item %d, failing\n", i
);
434 SetLastError(CRYPT_E_ASN1_CORRUPT
);
439 *cbDecoded
= decoded
;
440 TRACE("returning %d\n", ret
);
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
451 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
452 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
453 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
454 DWORD
*pcbDecoded
, void *startingPointer
)
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
459 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
462 if (pbEncoded
[0] == ASN_SEQUENCE
)
466 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
468 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
469 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
471 cbEncoded
-= 1 + lenBytes
;
472 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
474 else if (cbEncoded
< dataLen
)
476 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
478 SetLastError(CRYPT_E_ASN1_CORRUPT
);
483 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
484 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
485 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
487 if (cbDecoded
> cbEncoded
- 2)
489 /* Not enough space for 0 TLV */
490 SetLastError(CRYPT_E_ASN1_CORRUPT
);
493 else if (*(ptr
+ cbDecoded
) != 0 ||
494 *(ptr
+ cbDecoded
+ 1) != 0)
496 TRACE("expected 0 TLV\n");
497 SetLastError(CRYPT_E_ASN1_CORRUPT
);
504 if (ret
&& cbDecoded
!= dataLen
)
506 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
508 SetLastError(CRYPT_E_ASN1_CORRUPT
);
513 DWORD i
, bytesNeeded
= 0, structSize
= 0;
515 for (i
= 0; i
< cItem
; i
++)
517 bytesNeeded
+= items
[i
].size
;
518 structSize
+= items
[i
].minSize
;
521 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
523 *pcbStructInfo
= bytesNeeded
;
524 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
525 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
529 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
530 pvStructInfo
= *(BYTE
**)pvStructInfo
;
532 nextData
= (BYTE
*)startingPointer
;
534 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
535 memset(pvStructInfo
, 0, structSize
);
536 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
537 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
545 SetLastError(CRYPT_E_ASN1_BADTAG
);
548 TRACE("returning %d (%08x)\n", ret
, GetLastError());
553 * The expected tag of the entire encoded array (usually a variant
554 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
555 * regardless of the tag seen.
557 * used to decode each item in the array
559 * is the minimum size of each decoded item
561 * indicates whether each item has a dynamic pointer
563 * indicates the offset within itemSize at which the pointer exists
565 struct AsnArrayDescriptor
568 InternalDecodeFunc decodeFunc
;
574 struct AsnArrayItemSize
580 /* Decodes an array of like types into a struct GenericArray.
581 * The layout and decoding of the array are described by a struct
582 * AsnArrayDescriptor.
584 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
585 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
586 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
587 DWORD
*pcbDecoded
, void *startingPointer
)
591 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
592 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
595 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
599 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
601 DWORD bytesNeeded
, cItems
= 0, decoded
;
602 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
603 /* There can be arbitrarily many items, but there is often only one.
605 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
607 decoded
= 1 + lenBytes
;
608 bytesNeeded
= sizeof(struct GenericArray
);
612 BOOL doneDecoding
= FALSE
;
614 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
618 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
619 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
624 if (itemLenBytes
!= 1 || ptr
[1] != 0)
626 SetLastError(CRYPT_E_ASN1_CORRUPT
);
633 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
637 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
639 /* Each item decoded may not tolerate extraneous bytes,
640 * so get the length of the next element if known.
642 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
643 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
645 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
646 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
648 itemEncoded
= 1 + itemLenBytes
+ itemDataLen
;
651 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
652 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
657 if (itemSizes
!= &itemSize
)
658 itemSizes
= CryptMemRealloc(itemSizes
,
659 cItems
* sizeof(struct AsnArrayItemSize
));
664 cItems
* sizeof(struct AsnArrayItemSize
));
666 memcpy(itemSizes
, &itemSize
,
671 decoded
+= itemDecoded
;
672 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
673 itemSizes
[cItems
- 1].size
= size
;
686 *pcbDecoded
= decoded
;
688 *pcbStructInfo
= bytesNeeded
;
689 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
690 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
695 struct GenericArray
*array
;
697 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
698 pvStructInfo
= *(BYTE
**)pvStructInfo
;
699 array
= (struct GenericArray
*)pvStructInfo
;
700 array
->cItems
= cItems
;
702 array
->rgItems
= startingPointer
;
704 array
->rgItems
= (BYTE
*)array
+
705 sizeof(struct GenericArray
);
706 nextData
= (BYTE
*)array
->rgItems
+
707 array
->cItems
* arrayDesc
->itemSize
;
708 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
709 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
714 if (arrayDesc
->hasPointer
)
715 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
716 + arrayDesc
->pointerOffset
) = nextData
;
717 ret
= arrayDesc
->decodeFunc(ptr
,
718 itemSizes
[i
].encodedLen
,
719 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
720 array
->rgItems
+ i
* arrayDesc
->itemSize
,
721 &itemSizes
[i
].size
, &itemDecoded
);
724 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
730 if (itemSizes
!= &itemSize
)
731 CryptMemFree(itemSizes
);
736 SetLastError(CRYPT_E_ASN1_BADTAG
);
742 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
743 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
744 * to CRYPT_E_ASN1_CORRUPT.
745 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
748 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
749 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
754 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
756 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
757 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
759 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
760 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
763 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
765 *pcbStructInfo
= bytesNeeded
;
766 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
768 CRYPT_DER_BLOB
*blob
;
770 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
771 pvStructInfo
= *(BYTE
**)pvStructInfo
;
772 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
773 blob
->cbData
= 1 + lenBytes
+ dataLen
;
776 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
777 blob
->pbData
= (BYTE
*)pbEncoded
;
780 assert(blob
->pbData
);
781 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
786 SetLastError(CRYPT_E_ASN1_CORRUPT
);
794 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
795 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
796 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
801 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
802 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
804 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
807 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
808 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
810 if (ret
&& pvStructInfo
)
812 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
819 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
821 temp
= blob
->pbData
[i
];
822 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
823 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
827 TRACE("returning %d (%08x)\n", ret
, GetLastError());
831 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
832 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
833 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
837 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
838 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
842 struct AsnDecodeSequenceItem items
[] = {
843 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
844 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
845 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
846 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
847 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
848 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
849 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
850 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
851 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
852 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
855 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
856 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
857 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
858 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
859 pcbStructInfo
, NULL
, NULL
);
863 SetLastError(STATUS_ACCESS_VIOLATION
);
868 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
872 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
873 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
878 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
880 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
882 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
883 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
885 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
890 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
891 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
895 struct AsnDecodeSequenceItem items
[] = {
896 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
897 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
898 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
899 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
902 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
903 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
908 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
909 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
915 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
917 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
919 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
920 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
921 if (ret
&& pcbDecoded
)
922 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
927 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
928 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
929 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
932 struct AsnDecodeSequenceItem items
[] = {
933 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
934 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
935 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
936 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
937 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
938 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
939 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
940 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
941 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
942 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
944 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
945 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
947 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
948 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
950 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
951 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
952 FALSE
, TRUE
, offsetof(CERT_INFO
,
953 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
954 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
955 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
956 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
957 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
958 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
959 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
960 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
961 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
962 offsetof(CERT_INFO
, rgExtension
), 0 },
965 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
966 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
968 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
969 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
971 if (ret
&& pvStructInfo
)
975 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
976 info
= *(CERT_INFO
**)pvStructInfo
;
978 info
= (CERT_INFO
*)pvStructInfo
;
979 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
980 !info
->Subject
.cbData
)
982 SetLastError(CRYPT_E_ASN1_CORRUPT
);
983 /* Don't need to deallocate, because it should have failed on the
984 * first pass (and no memory was allocated.)
990 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
994 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
995 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
996 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1000 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1001 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1007 /* Unless told not to, first try to decode it as a signed cert. */
1008 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1010 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1012 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1013 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1014 (BYTE
*)&signedCert
, &size
);
1018 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1019 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1020 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1021 pvStructInfo
, pcbStructInfo
);
1022 LocalFree(signedCert
);
1025 /* Failing that, try it as an unsigned cert */
1029 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1030 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1031 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1036 SetLastError(STATUS_ACCESS_VIOLATION
);
1040 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1044 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1045 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1048 struct AsnDecodeSequenceItem items
[] = {
1049 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1050 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1051 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1052 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1053 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1054 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1055 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1056 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1058 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
1060 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1063 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1064 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1065 entry
? entry
->SerialNumber
.pbData
: NULL
);
1069 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1070 * been set prior to calling.
1072 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1073 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1076 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1077 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1078 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1079 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1081 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1082 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1084 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1085 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1086 entries
? entries
->rgItems
: NULL
);
1087 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1091 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1092 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1093 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1095 struct AsnDecodeSequenceItem items
[] = {
1096 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1097 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1098 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1099 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1100 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1101 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1102 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1104 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1105 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1106 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1107 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1108 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1109 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1110 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1111 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1112 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1113 offsetof(CRL_INFO
, rgExtension
), 0 },
1117 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1118 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1120 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1121 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1124 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1128 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1129 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1130 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1134 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1135 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1141 /* Unless told not to, first try to decode it as a signed crl. */
1142 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1144 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1146 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1147 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1148 (BYTE
*)&signedCrl
, &size
);
1152 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1153 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1154 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1155 pvStructInfo
, pcbStructInfo
);
1156 LocalFree(signedCrl
);
1159 /* Failing that, try it as an unsigned crl */
1163 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1164 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1165 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1170 SetLastError(STATUS_ACCESS_VIOLATION
);
1174 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1178 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1179 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1184 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1185 pvStructInfo
, *pcbStructInfo
);
1187 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1189 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1190 DWORD bytesNeeded
= sizeof(LPSTR
);
1194 /* The largest possible string for the first two components
1195 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1200 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1201 pbEncoded
[1 + lenBytes
] / 40,
1202 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1204 bytesNeeded
+= strlen(firstTwo
) + 1;
1205 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1206 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1208 /* large enough for ".4000000" */
1212 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1219 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1222 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1229 snprintf(str
, sizeof(str
), ".%d", val
);
1230 bytesNeeded
+= strlen(str
);
1235 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1237 *pcbStructInfo
= bytesNeeded
;
1238 else if (*pcbStructInfo
< bytesNeeded
)
1240 *pcbStructInfo
= bytesNeeded
;
1241 SetLastError(ERROR_MORE_DATA
);
1249 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1252 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1253 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1255 pszObjId
+= strlen(pszObjId
);
1256 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1257 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1261 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1270 sprintf(pszObjId
, ".%d", val
);
1271 pszObjId
+= strlen(pszObjId
);
1275 *(LPSTR
*)pvStructInfo
= NULL
;
1276 *pcbStructInfo
= bytesNeeded
;
1282 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1283 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1287 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1288 pvStructInfo
, *pcbStructInfo
);
1290 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1291 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1292 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1295 SetLastError(CRYPT_E_ASN1_BADTAG
);
1301 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1304 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1305 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1307 struct AsnDecodeSequenceItem items
[] = {
1308 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1309 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1310 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1311 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1312 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1313 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1314 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1315 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1318 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1320 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1324 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1325 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1326 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1327 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1329 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1330 debugstr_a(ext
->pszObjId
));
1331 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1335 static BOOL
CRYPT_AsnDecodeExtensionsInternal(const BYTE
*pbEncoded
,
1336 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1340 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1341 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1342 offsetof(CERT_EXTENSION
, pszObjId
) };
1343 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1345 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1346 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1348 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1349 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1350 exts
? exts
->rgExtension
: NULL
);
1354 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1355 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1356 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1362 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1363 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1364 if (ret
&& pvStructInfo
)
1366 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1367 pcbStructInfo
, *pcbStructInfo
);
1370 CERT_EXTENSIONS
*exts
;
1372 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1373 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1374 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1375 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1376 sizeof(CERT_EXTENSIONS
));
1377 ret
= CRYPT_AsnDecodeExtensionsInternal(pbEncoded
, cbEncoded
,
1378 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1379 pcbStructInfo
, NULL
);
1385 SetLastError(STATUS_ACCESS_VIOLATION
);
1392 /* Warning: this assumes the address of value->Value.pbData is already set, in
1393 * order to avoid overwriting memory. (In some cases, it may change it, if it
1394 * doesn't copy anything to memory.) Be sure to set it correctly!
1396 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1397 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1402 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1404 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1406 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1407 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1409 switch (pbEncoded
[0])
1411 case ASN_OCTETSTRING
:
1412 valueType
= CERT_RDN_OCTET_STRING
;
1413 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1414 bytesNeeded
+= dataLen
;
1416 case ASN_NUMERICSTRING
:
1417 valueType
= CERT_RDN_NUMERIC_STRING
;
1418 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1419 bytesNeeded
+= dataLen
;
1421 case ASN_PRINTABLESTRING
:
1422 valueType
= CERT_RDN_PRINTABLE_STRING
;
1423 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1424 bytesNeeded
+= dataLen
;
1427 valueType
= CERT_RDN_IA5_STRING
;
1428 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1429 bytesNeeded
+= dataLen
;
1432 valueType
= CERT_RDN_T61_STRING
;
1433 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1434 bytesNeeded
+= dataLen
;
1436 case ASN_VIDEOTEXSTRING
:
1437 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1438 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1439 bytesNeeded
+= dataLen
;
1441 case ASN_GRAPHICSTRING
:
1442 valueType
= CERT_RDN_GRAPHIC_STRING
;
1443 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1444 bytesNeeded
+= dataLen
;
1446 case ASN_VISIBLESTRING
:
1447 valueType
= CERT_RDN_VISIBLE_STRING
;
1448 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1449 bytesNeeded
+= dataLen
;
1451 case ASN_GENERALSTRING
:
1452 valueType
= CERT_RDN_GENERAL_STRING
;
1453 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1454 bytesNeeded
+= dataLen
;
1456 case ASN_UNIVERSALSTRING
:
1457 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1458 SetLastError(CRYPT_E_ASN1_BADTAG
);
1461 valueType
= CERT_RDN_BMP_STRING
;
1462 bytesNeeded
+= dataLen
;
1464 case ASN_UTF8STRING
:
1465 valueType
= CERT_RDN_UTF8_STRING
;
1466 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1467 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1470 SetLastError(CRYPT_E_ASN1_BADTAG
);
1475 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1477 *pcbStructInfo
= bytesNeeded
;
1478 else if (*pcbStructInfo
< bytesNeeded
)
1480 *pcbStructInfo
= bytesNeeded
;
1481 SetLastError(ERROR_MORE_DATA
);
1486 *pcbStructInfo
= bytesNeeded
;
1487 value
->dwValueType
= valueType
;
1492 assert(value
->Value
.pbData
);
1493 switch (pbEncoded
[0])
1495 case ASN_OCTETSTRING
:
1496 case ASN_NUMERICSTRING
:
1497 case ASN_PRINTABLESTRING
:
1500 case ASN_VIDEOTEXSTRING
:
1501 case ASN_GRAPHICSTRING
:
1502 case ASN_VISIBLESTRING
:
1503 case ASN_GENERALSTRING
:
1504 value
->Value
.cbData
= dataLen
;
1507 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1508 memcpy(value
->Value
.pbData
,
1509 pbEncoded
+ 1 + lenBytes
, dataLen
);
1511 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1517 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1519 value
->Value
.cbData
= dataLen
;
1520 for (i
= 0; i
< dataLen
/ 2; i
++)
1521 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1522 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1525 case ASN_UTF8STRING
:
1527 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1529 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1530 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1531 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1538 value
->Value
.cbData
= 0;
1539 value
->Value
.pbData
= NULL
;
1546 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1547 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1548 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1554 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1555 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1556 if (ret
&& pvStructInfo
)
1558 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1559 pcbStructInfo
, *pcbStructInfo
);
1562 CERT_NAME_VALUE
*value
;
1564 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1565 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1566 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1567 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1568 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1569 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1570 pcbStructInfo
, NULL
);
1576 SetLastError(STATUS_ACCESS_VIOLATION
);
1583 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1584 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1589 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1591 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1593 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1594 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1596 switch (pbEncoded
[0])
1598 case ASN_NUMERICSTRING
:
1599 valueType
= CERT_RDN_NUMERIC_STRING
;
1600 bytesNeeded
+= dataLen
* 2;
1602 case ASN_PRINTABLESTRING
:
1603 valueType
= CERT_RDN_PRINTABLE_STRING
;
1604 bytesNeeded
+= dataLen
* 2;
1607 valueType
= CERT_RDN_IA5_STRING
;
1608 bytesNeeded
+= dataLen
* 2;
1611 valueType
= CERT_RDN_T61_STRING
;
1612 bytesNeeded
+= dataLen
* 2;
1614 case ASN_VIDEOTEXSTRING
:
1615 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1616 bytesNeeded
+= dataLen
* 2;
1618 case ASN_GRAPHICSTRING
:
1619 valueType
= CERT_RDN_GRAPHIC_STRING
;
1620 bytesNeeded
+= dataLen
* 2;
1622 case ASN_VISIBLESTRING
:
1623 valueType
= CERT_RDN_VISIBLE_STRING
;
1624 bytesNeeded
+= dataLen
* 2;
1626 case ASN_GENERALSTRING
:
1627 valueType
= CERT_RDN_GENERAL_STRING
;
1628 bytesNeeded
+= dataLen
* 2;
1630 case ASN_UNIVERSALSTRING
:
1631 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1632 bytesNeeded
+= dataLen
/ 2;
1635 valueType
= CERT_RDN_BMP_STRING
;
1636 bytesNeeded
+= dataLen
;
1638 case ASN_UTF8STRING
:
1639 valueType
= CERT_RDN_UTF8_STRING
;
1640 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1641 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1644 SetLastError(CRYPT_E_ASN1_BADTAG
);
1649 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1651 *pcbStructInfo
= bytesNeeded
;
1652 else if (*pcbStructInfo
< bytesNeeded
)
1654 *pcbStructInfo
= bytesNeeded
;
1655 SetLastError(ERROR_MORE_DATA
);
1660 *pcbStructInfo
= bytesNeeded
;
1661 value
->dwValueType
= valueType
;
1665 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1667 assert(value
->Value
.pbData
);
1668 switch (pbEncoded
[0])
1670 case ASN_NUMERICSTRING
:
1671 case ASN_PRINTABLESTRING
:
1674 case ASN_VIDEOTEXSTRING
:
1675 case ASN_GRAPHICSTRING
:
1676 case ASN_VISIBLESTRING
:
1677 case ASN_GENERALSTRING
:
1678 value
->Value
.cbData
= dataLen
* 2;
1679 for (i
= 0; i
< dataLen
; i
++)
1680 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1682 case ASN_UNIVERSALSTRING
:
1683 value
->Value
.cbData
= dataLen
/ 2;
1684 for (i
= 0; i
< dataLen
/ 4; i
++)
1685 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1686 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1689 value
->Value
.cbData
= dataLen
;
1690 for (i
= 0; i
< dataLen
/ 2; i
++)
1691 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1692 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1694 case ASN_UTF8STRING
:
1695 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1696 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1697 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1703 value
->Value
.cbData
= 0;
1704 value
->Value
.pbData
= NULL
;
1711 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1712 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1713 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1719 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1720 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1721 if (ret
&& pvStructInfo
)
1723 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1724 pcbStructInfo
, *pcbStructInfo
);
1727 CERT_NAME_VALUE
*value
;
1729 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1730 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1731 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1732 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1733 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1734 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1735 pcbStructInfo
, NULL
);
1741 SetLastError(STATUS_ACCESS_VIOLATION
);
1748 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1749 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1752 struct AsnDecodeSequenceItem items
[] = {
1753 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1754 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1755 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1756 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1757 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1758 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1760 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1762 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1763 pvStructInfo
, *pcbStructInfo
);
1766 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1767 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1768 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1769 attr
? attr
->pszObjId
: NULL
);
1772 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1773 debugstr_a(attr
->pszObjId
));
1774 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1776 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1780 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1781 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1784 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1785 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1786 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1787 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1789 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1790 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1791 rdn
? rdn
->rgRDNAttr
: NULL
);
1795 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1796 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1797 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1803 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1804 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1805 offsetof(CERT_RDN
, rgRDNAttr
) };
1807 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1808 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1812 SetLastError(STATUS_ACCESS_VIOLATION
);
1819 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1820 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1824 struct AsnDecodeSequenceItem items
[] = {
1825 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1826 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1827 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1828 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1829 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1830 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1832 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1834 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1835 pvStructInfo
, *pcbStructInfo
);
1838 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1839 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1840 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1841 attr
? attr
->pszObjId
: NULL
);
1844 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1845 debugstr_a(attr
->pszObjId
));
1846 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1848 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1852 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1853 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1856 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1857 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1858 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1859 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1861 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1862 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1863 rdn
? rdn
->rgRDNAttr
: NULL
);
1867 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1868 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1869 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1875 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1876 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1877 offsetof(CERT_RDN
, rgRDNAttr
) };
1879 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1880 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1884 SetLastError(STATUS_ACCESS_VIOLATION
);
1891 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1894 BOOL ret
= TRUE
, done
= FALSE
;
1895 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
1897 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
1904 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
1907 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1909 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
1911 indefiniteNestingLevels
++;
1912 pbEncoded
+= 1 + lenBytes
;
1913 cbEncoded
-= 1 + lenBytes
;
1914 decoded
+= 1 + lenBytes
;
1915 TRACE("indefiniteNestingLevels = %d\n",
1916 indefiniteNestingLevels
);
1920 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
1921 indefiniteNestingLevels
)
1923 indefiniteNestingLevels
--;
1924 TRACE("indefiniteNestingLevels = %d\n",
1925 indefiniteNestingLevels
);
1927 pbEncoded
+= 1 + lenBytes
+ dataLen
;
1928 cbEncoded
-= 1 + lenBytes
+ dataLen
;
1929 decoded
+= 1 + lenBytes
+ dataLen
;
1930 if (!indefiniteNestingLevels
)
1934 } while (ret
&& !done
);
1935 /* If we haven't found all 0 TLVs, we haven't found the end */
1936 if (ret
&& indefiniteNestingLevels
)
1938 SetLastError(CRYPT_E_ASN1_EOD
);
1942 *pcbDecoded
= decoded
;
1943 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
1947 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
1948 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1952 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
1954 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1955 pvStructInfo
, *pcbStructInfo
);
1957 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
1959 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1960 bytesNeeded
+= encodedLen
;
1962 *pcbStructInfo
= bytesNeeded
;
1963 else if (*pcbStructInfo
< bytesNeeded
)
1965 SetLastError(ERROR_MORE_DATA
);
1966 *pcbStructInfo
= bytesNeeded
;
1971 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1973 *pcbStructInfo
= bytesNeeded
;
1974 blob
->cbData
= encodedLen
;
1975 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1976 blob
->pbData
= (LPBYTE
)pbEncoded
;
1979 assert(blob
->pbData
);
1980 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1984 *pcbDecoded
= encodedLen
;
1989 static BOOL
CRYPT_DecodeDERArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1990 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1993 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
1994 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
1995 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
1997 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1998 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2000 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2001 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2002 array
? array
->rgItems
: NULL
);
2006 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2007 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2011 struct AsnDecodeSequenceItem items
[] = {
2012 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2013 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2014 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2015 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2016 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
2017 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2019 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2021 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2022 pvStructInfo
, *pcbStructInfo
);
2024 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2025 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2026 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2027 TRACE("returning %d\n", ret
);
2031 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2032 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2033 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2037 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2038 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2044 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2045 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2049 *pcbStructInfo
= bytesNeeded
;
2050 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2051 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2053 PCRYPT_ATTRIBUTE attr
;
2055 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2056 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2057 attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
2058 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2059 sizeof(CRYPT_ATTRIBUTE
));
2060 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2061 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2068 SetLastError(STATUS_ACCESS_VIOLATION
);
2071 TRACE("returning %d\n", ret
);
2075 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2076 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2079 struct AsnArrayDescriptor arrayDesc
= { 0,
2080 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2081 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2082 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2085 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2086 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, attrs
? attrs
->rgAttr
:
2091 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2092 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2093 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2097 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2098 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2105 SetLastError(CRYPT_E_ASN1_EOD
);
2106 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2107 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2108 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2109 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2113 *pcbStructInfo
= bytesNeeded
;
2114 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2115 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2117 PCRYPT_ATTRIBUTES attrs
;
2119 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2120 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2121 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2122 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2123 sizeof(CRYPT_ATTRIBUTES
));
2124 ret
= CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded
,
2125 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2126 &bytesNeeded
, NULL
);
2132 SetLastError(STATUS_ACCESS_VIOLATION
);
2135 TRACE("returning %d\n", ret
);
2139 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2140 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2142 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
2143 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
2145 struct AsnDecodeSequenceItem items
[] = {
2146 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2147 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2148 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2149 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2150 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2151 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2154 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2155 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2157 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2158 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2159 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2160 if (ret
&& pvStructInfo
)
2162 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2163 debugstr_a(algo
->pszObjId
));
2168 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2169 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2173 struct AsnDecodeSequenceItem items
[] = {
2174 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2175 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2176 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2177 Algorithm
.pszObjId
) },
2178 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2179 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2180 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2182 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2184 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2185 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2186 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2190 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2191 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2192 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2200 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2201 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2204 *pcbStructInfo
= bytesNeeded
;
2205 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2206 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2208 PCERT_PUBLIC_KEY_INFO info
;
2210 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2211 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2212 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2213 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2214 sizeof(CERT_PUBLIC_KEY_INFO
);
2215 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2216 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2217 &bytesNeeded
, NULL
);
2223 SetLastError(STATUS_ACCESS_VIOLATION
);
2230 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2231 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2237 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2240 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2242 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2245 if (pbEncoded
[1] > 1)
2247 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2254 *pcbStructInfo
= sizeof(BOOL
);
2257 else if (*pcbStructInfo
< sizeof(BOOL
))
2259 *pcbStructInfo
= sizeof(BOOL
);
2260 SetLastError(ERROR_MORE_DATA
);
2265 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2268 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2272 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2273 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2275 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2276 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2279 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2280 pvStructInfo
, *pcbStructInfo
);
2284 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2287 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2288 if (1 + lenBytes
> cbEncoded
)
2290 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2293 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2295 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2297 case 1: /* rfc822Name */
2298 case 2: /* dNSName */
2299 case 6: /* uniformResourceIdentifier */
2300 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2302 case 4: /* directoryName */
2303 case 7: /* iPAddress */
2304 bytesNeeded
+= dataLen
;
2306 case 8: /* registeredID */
2307 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2311 /* FIXME: ugly, shouldn't need to know internals of OID decode
2312 * function to use it.
2314 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2317 case 0: /* otherName */
2318 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2319 SetLastError(CRYPT_E_ASN1_BADTAG
);
2322 case 3: /* x400Address, unimplemented */
2323 case 5: /* ediPartyName, unimplemented */
2324 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2325 SetLastError(CRYPT_E_ASN1_BADTAG
);
2329 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2330 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2336 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2338 *pcbStructInfo
= bytesNeeded
;
2339 else if (*pcbStructInfo
< bytesNeeded
)
2341 *pcbStructInfo
= bytesNeeded
;
2342 SetLastError(ERROR_MORE_DATA
);
2347 *pcbStructInfo
= bytesNeeded
;
2348 /* MS used values one greater than the asn1 ones.. sigh */
2349 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2350 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2352 case 1: /* rfc822Name */
2353 case 2: /* dNSName */
2354 case 6: /* uniformResourceIdentifier */
2358 for (i
= 0; i
< dataLen
; i
++)
2359 entry
->u
.pwszURL
[i
] =
2360 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2361 entry
->u
.pwszURL
[i
] = 0;
2362 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2363 debugstr_w(entry
->u
.pwszURL
));
2366 case 4: /* directoryName */
2367 entry
->dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
2368 /* The data are memory-equivalent with the IPAddress case,
2371 case 7: /* iPAddress */
2372 /* The next data pointer is in the pwszURL spot, that is,
2373 * the first 4 bytes. Need to move it to the next spot.
2375 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2376 entry
->u
.IPAddress
.cbData
= dataLen
;
2377 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2380 case 8: /* registeredID */
2381 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2382 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2391 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
2392 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2396 struct AsnArrayDescriptor arrayDesc
= { 0,
2397 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2398 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2399 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2401 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2402 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2405 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2406 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2407 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2408 info
? info
->rgAltEntry
: NULL
);
2412 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2413 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
2414 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2419 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2420 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2422 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2425 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
2426 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
2428 if (ret
&& pvStructInfo
)
2430 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2437 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
2439 temp
= blob
->pbData
[i
];
2440 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
2441 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
2445 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2449 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2450 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2451 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2457 struct AsnDecodeSequenceItem items
[] = {
2458 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2459 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2460 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2461 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2462 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2463 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2464 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2465 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2466 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2467 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2468 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2471 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2472 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2473 pcbStructInfo
, NULL
, NULL
);
2477 SetLastError(STATUS_ACCESS_VIOLATION
);
2484 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2485 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2486 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2492 struct AsnDecodeSequenceItem items
[] = {
2493 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2494 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2495 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2496 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2497 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2498 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2499 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2500 AuthorityCertIssuer
.rgAltEntry
), 0 },
2501 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2502 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2503 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2504 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2505 AuthorityCertSerialNumber
.pbData
), 0 },
2508 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2509 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2510 pcbStructInfo
, NULL
, NULL
);
2514 SetLastError(STATUS_ACCESS_VIOLATION
);
2521 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2522 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2527 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2528 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2530 /* The caller has already checked the tag, no need to check it again.
2531 * Check the outer length is valid:
2533 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
2535 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2538 pbEncoded
+= 1 + lenBytes
;
2539 cbEncoded
-= 1 + lenBytes
;
2540 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2541 cbEncoded
-= 2; /* space for 0 TLV */
2542 /* Check the inner length is valid: */
2543 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
2547 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
2548 pvStructInfo
, pcbStructInfo
, &decodedLen
);
2549 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2551 if (*(pbEncoded
+ decodedLen
) != 0 ||
2552 *(pbEncoded
+ decodedLen
+ 1) != 0)
2554 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2555 *(pbEncoded
+ decodedLen
),
2556 *(pbEncoded
+ decodedLen
+ 1));
2557 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2563 if (ret
&& pcbDecoded
)
2565 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
2566 TRACE("decoded %d bytes\n", *pcbDecoded
);
2573 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
2574 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2577 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2578 struct AsnDecodeSequenceItem items
[] = {
2579 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2580 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2581 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2582 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2583 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2584 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2585 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2589 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2590 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2592 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2593 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2594 pcbDecoded
, info
? info
->pszObjId
: NULL
);
2598 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2599 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2600 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2604 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2605 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2609 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
2610 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
2611 if (ret
&& pvStructInfo
)
2613 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2614 pcbStructInfo
, *pcbStructInfo
);
2617 CRYPT_CONTENT_INFO
*info
;
2619 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2620 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2621 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2622 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2623 sizeof(CRYPT_CONTENT_INFO
));
2624 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
2625 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2626 pcbStructInfo
, NULL
);
2632 SetLastError(STATUS_ACCESS_VIOLATION
);
2638 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2639 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2640 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2643 struct AsnDecodeSequenceItem items
[] = {
2644 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
2645 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2646 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2647 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2648 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2650 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2651 CRYPT_AsnDecodePKCSContentInfoInternal
,
2652 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2653 ContentInfo
.pszObjId
), 0 },
2654 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2655 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2656 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2659 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2660 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
2665 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2666 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2667 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2671 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2672 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2678 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2679 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2682 *pcbStructInfo
= bytesNeeded
;
2683 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2684 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2686 CERT_ALT_NAME_INFO
*name
;
2688 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2689 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2690 name
= (CERT_ALT_NAME_INFO
*)pvStructInfo
;
2691 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
2692 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
2693 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
2694 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2695 &bytesNeeded
, NULL
);
2701 SetLastError(STATUS_ACCESS_VIOLATION
);
2708 struct PATH_LEN_CONSTRAINT
2710 BOOL fPathLenConstraint
;
2711 DWORD dwPathLenConstraint
;
2714 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
2715 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2719 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
2721 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2722 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2726 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
2728 *pcbStructInfo
= bytesNeeded
;
2730 else if (*pcbStructInfo
< bytesNeeded
)
2732 SetLastError(ERROR_MORE_DATA
);
2733 *pcbStructInfo
= bytesNeeded
;
2738 struct PATH_LEN_CONSTRAINT
*constraint
=
2739 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2741 size
= sizeof(constraint
->dwPathLenConstraint
);
2742 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
2743 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
2745 constraint
->fPathLenConstraint
= TRUE
;
2746 TRACE("got an int, dwPathLenConstraint is %d\n",
2747 constraint
->dwPathLenConstraint
);
2749 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2753 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
2754 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2758 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2759 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2760 offsetof(CERT_NAME_BLOB
, pbData
) };
2761 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2763 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2764 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2766 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2767 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
2768 entries
? entries
->rgItems
: NULL
);
2769 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2773 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2774 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2775 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2781 struct AsnDecodeSequenceItem items
[] = {
2782 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2783 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2784 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2785 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2786 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2787 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2788 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2789 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2790 sizeof(struct GenericArray
), TRUE
, TRUE
,
2791 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2794 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2795 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2796 pcbStructInfo
, NULL
, NULL
);
2800 SetLastError(STATUS_ACCESS_VIOLATION
);
2807 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2808 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2809 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2815 struct AsnDecodeSequenceItem items
[] = {
2816 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2817 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2818 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2819 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2820 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2823 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2824 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2825 pcbStructInfo
, NULL
, NULL
);
2829 SetLastError(STATUS_ACCESS_VIOLATION
);
2836 #define RSA1_MAGIC 0x31415352
2838 struct DECODED_RSA_PUB_KEY
2841 CRYPT_INTEGER_BLOB modulus
;
2844 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2845 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2846 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2852 struct AsnDecodeSequenceItem items
[] = {
2853 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2854 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2855 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2857 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2858 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2860 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2863 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2864 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
2868 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2869 decodedKey
->modulus
.cbData
;
2873 *pcbStructInfo
= bytesNeeded
;
2876 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2877 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2880 RSAPUBKEY
*rsaPubKey
;
2882 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2883 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2884 hdr
= (BLOBHEADER
*)pvStructInfo
;
2885 hdr
->bType
= PUBLICKEYBLOB
;
2886 hdr
->bVersion
= CUR_BLOB_VERSION
;
2888 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2889 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2890 sizeof(BLOBHEADER
));
2891 rsaPubKey
->magic
= RSA1_MAGIC
;
2892 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2893 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2894 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2895 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2896 decodedKey
->modulus
.cbData
);
2898 LocalFree(decodedKey
);
2903 SetLastError(STATUS_ACCESS_VIOLATION
);
2910 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
2911 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2915 DWORD bytesNeeded
, dataLen
;
2917 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2918 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2920 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2922 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2924 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2925 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2927 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2929 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2931 *pcbStructInfo
= bytesNeeded
;
2932 else if (*pcbStructInfo
< bytesNeeded
)
2934 SetLastError(ERROR_MORE_DATA
);
2935 *pcbStructInfo
= bytesNeeded
;
2940 CRYPT_DATA_BLOB
*blob
;
2942 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2943 blob
->cbData
= dataLen
;
2944 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2945 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2948 assert(blob
->pbData
);
2950 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2958 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2959 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2960 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2964 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2965 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2973 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2976 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2978 SetLastError(CRYPT_E_ASN1_BADTAG
);
2981 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
2982 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2985 *pcbStructInfo
= bytesNeeded
;
2986 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2987 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2989 CRYPT_DATA_BLOB
*blob
;
2991 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2992 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2993 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2994 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2995 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
2996 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2997 &bytesNeeded
, NULL
);
3003 SetLastError(STATUS_ACCESS_VIOLATION
);
3010 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3011 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3015 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3016 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3018 if (pbEncoded
[0] == ASN_BITSTRING
)
3020 DWORD bytesNeeded
, dataLen
;
3021 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3023 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3025 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3026 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3028 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3030 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3032 *pcbStructInfo
= bytesNeeded
;
3033 else if (*pcbStructInfo
< bytesNeeded
)
3035 *pcbStructInfo
= bytesNeeded
;
3036 SetLastError(ERROR_MORE_DATA
);
3041 CRYPT_BIT_BLOB
*blob
;
3043 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3044 blob
->cbData
= dataLen
- 1;
3045 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3046 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3048 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3052 assert(blob
->pbData
);
3055 BYTE mask
= 0xff << blob
->cUnusedBits
;
3057 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3059 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3067 SetLastError(CRYPT_E_ASN1_BADTAG
);
3070 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3074 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3075 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3076 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3080 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3081 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3087 if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3088 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3091 *pcbStructInfo
= bytesNeeded
;
3092 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3093 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3095 CRYPT_BIT_BLOB
*blob
;
3097 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3098 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3099 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3100 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3101 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3102 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3103 &bytesNeeded
, NULL
);
3109 SetLastError(STATUS_ACCESS_VIOLATION
);
3113 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3117 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3118 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3121 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3122 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3123 DWORD size
= sizeof(buf
);
3125 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3126 if (pbEncoded
[0] != ASN_INTEGER
)
3128 SetLastError(CRYPT_E_ASN1_BADTAG
);
3132 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
, 0, &buf
,
3137 *pcbStructInfo
= sizeof(int);
3138 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3142 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3144 /* initialize to a negative value to sign-extend */
3149 for (i
= 0; i
< blob
->cbData
; i
++)
3152 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3154 memcpy(pvStructInfo
, &val
, sizeof(int));
3157 else if (GetLastError() == ERROR_MORE_DATA
)
3158 SetLastError(CRYPT_E_ASN1_LARGE
);
3162 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3163 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3164 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3172 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3173 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3177 *pcbStructInfo
= bytesNeeded
;
3178 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3179 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3181 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3182 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3183 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3184 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3185 &bytesNeeded
, NULL
);
3191 SetLastError(STATUS_ACCESS_VIOLATION
);
3198 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
3199 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3203 DWORD bytesNeeded
, dataLen
;
3205 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3207 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3209 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3211 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3213 *pcbStructInfo
= bytesNeeded
;
3214 else if (*pcbStructInfo
< bytesNeeded
)
3216 *pcbStructInfo
= bytesNeeded
;
3217 SetLastError(ERROR_MORE_DATA
);
3222 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3224 blob
->cbData
= dataLen
;
3225 assert(blob
->pbData
);
3230 for (i
= 0; i
< blob
->cbData
; i
++)
3232 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3241 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3242 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3243 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3251 if (pbEncoded
[0] != ASN_INTEGER
)
3253 SetLastError(CRYPT_E_ASN1_BADTAG
);
3257 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3258 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3262 *pcbStructInfo
= bytesNeeded
;
3263 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3264 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3266 CRYPT_INTEGER_BLOB
*blob
;
3268 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3269 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3270 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3271 blob
->pbData
= (BYTE
*)pvStructInfo
+
3272 sizeof(CRYPT_INTEGER_BLOB
);
3273 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3274 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3275 &bytesNeeded
, NULL
);
3281 SetLastError(STATUS_ACCESS_VIOLATION
);
3288 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
3289 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3294 if (pbEncoded
[0] == ASN_INTEGER
)
3296 DWORD bytesNeeded
, dataLen
;
3298 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3300 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3303 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3304 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3306 *pcbStructInfo
= bytesNeeded
;
3307 else if (*pcbStructInfo
< bytesNeeded
)
3309 *pcbStructInfo
= bytesNeeded
;
3310 SetLastError(ERROR_MORE_DATA
);
3315 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3317 blob
->cbData
= dataLen
;
3318 assert(blob
->pbData
);
3319 /* remove leading zero byte if it exists */
3320 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3329 for (i
= 0; i
< blob
->cbData
; i
++)
3331 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3340 SetLastError(CRYPT_E_ASN1_BADTAG
);
3346 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3347 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3348 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3356 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
3357 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3360 *pcbStructInfo
= bytesNeeded
;
3361 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3362 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3364 CRYPT_INTEGER_BLOB
*blob
;
3366 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3367 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3368 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3369 blob
->pbData
= (BYTE
*)pvStructInfo
+
3370 sizeof(CRYPT_INTEGER_BLOB
);
3371 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
3372 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
3373 &bytesNeeded
, NULL
);
3379 SetLastError(STATUS_ACCESS_VIOLATION
);
3386 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3387 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3388 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3394 *pcbStructInfo
= sizeof(int);
3399 if (pbEncoded
[0] == ASN_ENUMERATED
)
3401 unsigned int val
= 0, i
;
3405 SetLastError(CRYPT_E_ASN1_EOD
);
3408 else if (pbEncoded
[1] == 0)
3410 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3415 /* A little strange looking, but we have to accept a sign byte:
3416 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3417 * assuming a small length is okay here, it has to be in short
3420 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3422 SetLastError(CRYPT_E_ASN1_LARGE
);
3425 for (i
= 0; i
< pbEncoded
[1]; i
++)
3428 val
|= pbEncoded
[2 + i
];
3430 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3431 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3433 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3434 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3435 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3441 SetLastError(CRYPT_E_ASN1_BADTAG
);
3447 SetLastError(STATUS_ACCESS_VIOLATION
);
3454 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3457 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3462 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3464 if (!isdigit(*(pbEncoded))) \
3466 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3472 (word) += *(pbEncoded)++ - '0'; \
3477 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3478 SYSTEMTIME
*sysTime
)
3482 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3484 WORD hours
, minutes
= 0;
3485 BYTE sign
= *pbEncoded
++;
3488 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3489 if (ret
&& hours
>= 24)
3491 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3496 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3497 if (ret
&& minutes
>= 60)
3499 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3507 sysTime
->wHour
+= hours
;
3508 sysTime
->wMinute
+= minutes
;
3512 if (hours
> sysTime
->wHour
)
3515 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3518 sysTime
->wHour
-= hours
;
3519 if (minutes
> sysTime
->wMinute
)
3522 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3525 sysTime
->wMinute
-= minutes
;
3532 #define MIN_ENCODED_TIME_LENGTH 10
3534 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
3535 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3540 if (pbEncoded
[0] == ASN_UTCTIME
)
3543 SetLastError(CRYPT_E_ASN1_EOD
);
3544 else if (pbEncoded
[1] > 0x7f)
3546 /* long-form date strings really can't be valid */
3547 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3551 SYSTEMTIME sysTime
= { 0 };
3552 BYTE len
= pbEncoded
[1];
3554 if (len
< MIN_ENCODED_TIME_LENGTH
)
3555 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3560 *pcbDecoded
= 2 + len
;
3562 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3563 if (sysTime
.wYear
>= 50)
3564 sysTime
.wYear
+= 1900;
3566 sysTime
.wYear
+= 2000;
3567 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3568 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3569 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3570 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3573 if (len
>= 2 && isdigit(*pbEncoded
) &&
3574 isdigit(*(pbEncoded
+ 1)))
3575 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3577 else if (isdigit(*pbEncoded
))
3578 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3581 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3587 *pcbStructInfo
= sizeof(FILETIME
);
3588 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3590 ret
= SystemTimeToFileTime(&sysTime
,
3591 (FILETIME
*)pvStructInfo
);
3597 SetLastError(CRYPT_E_ASN1_BADTAG
);
3601 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3602 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3603 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3611 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3612 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3616 *pcbStructInfo
= bytesNeeded
;
3617 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3618 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3620 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3621 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3622 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3623 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3624 &bytesNeeded
, NULL
);
3630 SetLastError(STATUS_ACCESS_VIOLATION
);
3636 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
3637 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3642 if (pbEncoded
[0] == ASN_GENERALTIME
)
3645 SetLastError(CRYPT_E_ASN1_EOD
);
3646 else if (pbEncoded
[1] > 0x7f)
3648 /* long-form date strings really can't be valid */
3649 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3653 BYTE len
= pbEncoded
[1];
3655 if (len
< MIN_ENCODED_TIME_LENGTH
)
3656 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3659 SYSTEMTIME sysTime
= { 0 };
3663 *pcbDecoded
= 2 + len
;
3665 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3666 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3667 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3668 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3671 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3674 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3676 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3683 /* workaround macro weirdness */
3684 digits
= min(len
, 3);
3685 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3686 sysTime
.wMilliseconds
);
3689 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3695 *pcbStructInfo
= sizeof(FILETIME
);
3696 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3698 ret
= SystemTimeToFileTime(&sysTime
,
3699 (FILETIME
*)pvStructInfo
);
3705 SetLastError(CRYPT_E_ASN1_BADTAG
);
3709 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
3710 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3714 InternalDecodeFunc decode
= NULL
;
3716 if (pbEncoded
[0] == ASN_UTCTIME
)
3717 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
3718 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3719 decode
= CRYPT_AsnDecodeGeneralizedTime
;
3721 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
3722 pcbStructInfo
, pcbDecoded
);
3725 SetLastError(CRYPT_E_ASN1_BADTAG
);
3731 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3732 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3733 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3741 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
3742 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3746 *pcbStructInfo
= bytesNeeded
;
3747 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3748 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3750 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3751 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3752 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
3753 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3754 &bytesNeeded
, NULL
);
3760 SetLastError(STATUS_ACCESS_VIOLATION
);
3767 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3768 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3769 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3775 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3777 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3779 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3784 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3785 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3787 ptr
= pbEncoded
+ 1 + lenBytes
;
3788 remainingLen
= dataLen
;
3789 while (ret
&& remainingLen
)
3793 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3796 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3798 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3799 ptr
+= 1 + nextLenBytes
+ nextLen
;
3800 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3801 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3802 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3808 CRYPT_SEQUENCE_OF_ANY
*seq
;
3812 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3813 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3815 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3816 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3817 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3818 seq
->cValue
= cValue
;
3819 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3821 nextPtr
= (BYTE
*)seq
->rgValue
+
3822 cValue
* sizeof(CRYPT_DER_BLOB
);
3823 ptr
= pbEncoded
+ 1 + lenBytes
;
3824 remainingLen
= dataLen
;
3826 while (ret
&& remainingLen
)
3830 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3833 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3835 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3837 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3838 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3841 seq
->rgValue
[i
].pbData
= nextPtr
;
3842 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3844 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3846 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3847 ptr
+= 1 + nextLenBytes
+ nextLen
;
3857 SetLastError(CRYPT_E_ASN1_BADTAG
);
3863 SetLastError(STATUS_ACCESS_VIOLATION
);
3870 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
3871 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3876 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3878 DWORD bytesNeeded
, dataLen
;
3880 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3882 struct AsnArrayDescriptor arrayDesc
= {
3883 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3884 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3885 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3886 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3892 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3893 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3894 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
3895 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3898 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3900 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3902 *pcbStructInfo
= bytesNeeded
;
3903 else if (*pcbStructInfo
< bytesNeeded
)
3905 *pcbStructInfo
= bytesNeeded
;
3906 SetLastError(ERROR_MORE_DATA
);
3911 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3915 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3916 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3917 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3918 0, NULL
, &name
->u
.FullName
, pcbStructInfo
, NULL
,
3919 name
->u
.FullName
.rgAltEntry
);
3922 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3928 SetLastError(CRYPT_E_ASN1_BADTAG
);
3934 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3935 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3937 struct AsnDecodeSequenceItem items
[] = {
3938 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3939 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3940 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3941 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3942 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3943 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3944 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3945 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3946 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3947 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3951 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3952 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3957 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3958 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3959 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3963 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3964 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3968 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3969 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3970 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3972 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3973 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3977 SetLastError(STATUS_ACCESS_VIOLATION
);
3984 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3985 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3986 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3990 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3991 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3995 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3996 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3998 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3999 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4003 SetLastError(STATUS_ACCESS_VIOLATION
);
4010 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4011 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4012 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4016 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4017 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4021 struct AsnDecodeSequenceItem items
[] = {
4022 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4023 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4024 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4025 offsetof(CRL_ISSUING_DIST_POINT
,
4026 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4027 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4028 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4030 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4031 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4033 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4034 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4035 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4036 OnlySomeReasonFlags
.pbData
), 0 },
4037 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4038 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4041 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4042 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4043 pcbStructInfo
, NULL
, NULL
);
4047 SetLastError(STATUS_ACCESS_VIOLATION
);
4054 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
4055 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4059 struct AsnDecodeSequenceItem items
[] = {
4060 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4061 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4063 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4064 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4065 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4067 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
4068 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
4070 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4071 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4073 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4074 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4075 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4076 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4078 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4081 TRACE("returning %d\n", ret
);
4085 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4086 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4089 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4090 struct AsnDecodeSequenceItem items
[] = {
4091 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4092 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4093 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4094 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4095 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4096 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4097 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4098 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4099 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4100 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4101 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4102 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4103 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4104 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4105 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4106 HashEncryptionAlgorithm
.pszObjId
), 0 },
4107 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4108 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4109 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4110 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4111 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4112 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4113 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4117 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4118 pvStructInfo
, *pcbStructInfo
);
4120 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4121 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4122 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
4126 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4127 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4128 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4132 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4133 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4137 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4138 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4139 if (ret
&& pvStructInfo
)
4141 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4142 pcbStructInfo
, *pcbStructInfo
);
4145 CMSG_SIGNER_INFO
*info
;
4147 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4148 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4149 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4150 info
->Issuer
.pbData
= ((BYTE
*)info
+
4151 sizeof(CMSG_SIGNER_INFO
));
4152 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
4153 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4154 pcbStructInfo
, NULL
);
4160 SetLastError(STATUS_ACCESS_VIOLATION
);
4163 TRACE("returning %d\n", ret
);
4167 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4168 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4171 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
4172 CRYPT_AsnDecodePKCSSignerInfoInternal
, sizeof(CMSG_SIGNER_INFO
), TRUE
,
4173 offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
) };
4174 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4176 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4177 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4179 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4180 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4181 array
? array
->rgItems
: NULL
);
4185 BOOL
CRYPT_AsnDecodePKCSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4186 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
4187 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
4190 struct AsnDecodeSequenceItem items
[] = {
4191 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
4192 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4193 /* Placeholder for the hash algorithms - redundant with those in the
4194 * signers, so just ignore them.
4196 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
4197 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
4198 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
4199 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
4200 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4201 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
4202 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4203 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
4204 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4205 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
4206 sizeof(struct GenericArray
), TRUE
, TRUE
,
4207 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
4208 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
4209 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4210 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
4213 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4214 pDecodePara
, signedInfo
, *pcbSignedInfo
);
4216 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4217 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
4219 TRACE("returning %d\n", ret
);
4223 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
4224 LPCSTR lpszStructType
)
4226 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4228 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
4229 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
4231 SetLastError(ERROR_FILE_NOT_FOUND
);
4234 if (!HIWORD(lpszStructType
))
4236 switch (LOWORD(lpszStructType
))
4238 case (WORD
)X509_CERT
:
4239 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
4241 case (WORD
)X509_CERT_TO_BE_SIGNED
:
4242 decodeFunc
= CRYPT_AsnDecodeCert
;
4244 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
4245 decodeFunc
= CRYPT_AsnDecodeCRL
;
4247 case (WORD
)X509_EXTENSIONS
:
4248 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4250 case (WORD
)X509_NAME_VALUE
:
4251 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4253 case (WORD
)X509_NAME
:
4254 decodeFunc
= CRYPT_AsnDecodeName
;
4256 case (WORD
)X509_PUBLIC_KEY_INFO
:
4257 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4259 case (WORD
)X509_AUTHORITY_KEY_ID
:
4260 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4262 case (WORD
)X509_ALTERNATE_NAME
:
4263 decodeFunc
= CRYPT_AsnDecodeAltName
;
4265 case (WORD
)X509_BASIC_CONSTRAINTS
:
4266 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4268 case (WORD
)X509_BASIC_CONSTRAINTS2
:
4269 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4271 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
4272 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4274 case (WORD
)X509_UNICODE_NAME
:
4275 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4277 case (WORD
)PKCS_ATTRIBUTE
:
4278 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4280 case (WORD
)X509_UNICODE_NAME_VALUE
:
4281 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4283 case (WORD
)X509_OCTET_STRING
:
4284 decodeFunc
= CRYPT_AsnDecodeOctets
;
4286 case (WORD
)X509_BITS
:
4287 case (WORD
)X509_KEY_USAGE
:
4288 decodeFunc
= CRYPT_AsnDecodeBits
;
4290 case (WORD
)X509_INTEGER
:
4291 decodeFunc
= CRYPT_AsnDecodeInt
;
4293 case (WORD
)X509_MULTI_BYTE_INTEGER
:
4294 decodeFunc
= CRYPT_AsnDecodeInteger
;
4296 case (WORD
)X509_MULTI_BYTE_UINT
:
4297 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4299 case (WORD
)X509_ENUMERATED
:
4300 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4302 case (WORD
)X509_CHOICE_OF_TIME
:
4303 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4305 case (WORD
)X509_AUTHORITY_KEY_ID2
:
4306 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4308 case (WORD
)PKCS_CONTENT_INFO
:
4309 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4311 case (WORD
)X509_SEQUENCE_OF_ANY
:
4312 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4314 case (WORD
)PKCS_UTC_TIME
:
4315 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4317 case (WORD
)X509_CRL_DIST_POINTS
:
4318 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4320 case (WORD
)X509_ENHANCED_KEY_USAGE
:
4321 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4323 case (WORD
)PKCS_ATTRIBUTES
:
4324 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4326 case (WORD
)X509_ISSUING_DIST_POINT
:
4327 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4329 case (WORD
)PKCS7_SIGNER_INFO
:
4330 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4334 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4335 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4336 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4337 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4338 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4339 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4340 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4341 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4342 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4343 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4344 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4345 decodeFunc
= CRYPT_AsnDecodeBits
;
4346 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4347 decodeFunc
= CRYPT_AsnDecodeOctets
;
4348 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4349 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4350 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4351 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4352 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4353 decodeFunc
= CRYPT_AsnDecodeAltName
;
4354 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4355 decodeFunc
= CRYPT_AsnDecodeAltName
;
4356 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4357 decodeFunc
= CRYPT_AsnDecodeAltName
;
4358 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4359 decodeFunc
= CRYPT_AsnDecodeAltName
;
4360 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4361 decodeFunc
= CRYPT_AsnDecodeAltName
;
4362 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4363 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4364 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4365 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4366 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4367 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4371 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
4372 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4374 static HCRYPTOIDFUNCSET set
= NULL
;
4375 CryptDecodeObjectFunc decodeFunc
= NULL
;
4378 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
4379 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4380 (void **)&decodeFunc
, hFunc
);
4384 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
4385 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4387 static HCRYPTOIDFUNCSET set
= NULL
;
4388 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4391 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4392 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4393 (void **)&decodeFunc
, hFunc
);
4397 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4398 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
4399 DWORD
*pcbStructInfo
)
4402 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
4403 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
4404 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4406 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
4407 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
4408 pvStructInfo
, pcbStructInfo
);
4410 if (!pvStructInfo
&& !pcbStructInfo
)
4412 SetLastError(ERROR_INVALID_PARAMETER
);
4417 SetLastError(CRYPT_E_ASN1_EOD
);
4420 if (cbEncoded
> MAX_ENCODED_LEN
)
4422 SetLastError(CRYPT_E_ASN1_LARGE
);
4426 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
4429 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4430 debugstr_a(lpszStructType
));
4431 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
4432 lpszStructType
, &hFunc
);
4433 if (!pCryptDecodeObject
)
4434 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
4435 lpszStructType
, &hFunc
);
4437 if (pCryptDecodeObject
)
4438 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4439 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4440 else if (pCryptDecodeObjectEx
)
4441 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
4442 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4443 pvStructInfo
, pcbStructInfo
);
4445 CryptFreeOIDFunctionAddress(hFunc
, 0);
4446 TRACE_(crypt
)("returning %d\n", ret
);
4450 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4451 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4452 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4455 CryptDecodeObjectExFunc decodeFunc
;
4456 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4458 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4459 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
4460 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4462 if (!pvStructInfo
&& !pcbStructInfo
)
4464 SetLastError(ERROR_INVALID_PARAMETER
);
4469 SetLastError(CRYPT_E_ASN1_EOD
);
4472 if (cbEncoded
> MAX_ENCODED_LEN
)
4474 SetLastError(CRYPT_E_ASN1_LARGE
);
4478 SetLastError(NOERROR
);
4479 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
4480 *(BYTE
**)pvStructInfo
= NULL
;
4481 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
4484 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4485 debugstr_a(lpszStructType
));
4486 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
4490 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
4491 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4494 CryptDecodeObjectFunc pCryptDecodeObject
=
4495 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
4497 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4498 * directly, as that could cause an infinite loop.
4500 if (pCryptDecodeObject
)
4502 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4504 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4505 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
4506 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4507 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
4508 ret
= pCryptDecodeObject(dwCertEncodingType
,
4509 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
4510 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
4513 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4514 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4518 CryptFreeOIDFunctionAddress(hFunc
, 0);
4519 TRACE_(crypt
)("returning %d\n", ret
);