2 * Copyright 2005 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 is
21 * undocumented, 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
31 * http://msdn.microsoft.com/library/en-us/seccrypto/security/constants_for_cryptencodeobject_and_cryptdecodeobject.asp
39 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
66 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
67 DWORD
, DWORD
, void *, DWORD
*);
68 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
69 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
71 /* Prototypes for built-in decoders. They follow the Ex style prototypes.
72 * The dwCertEncodingType and lpszStructType are ignored by the built-in
73 * functions, but the parameters are retained to simplify CryptDecodeObjectEx,
74 * since it must call functions in external DLLs that follow these signatures.
76 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
77 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
78 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
79 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
80 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
81 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
82 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
83 * time, doesn't do memory allocation, and doesn't do exception handling.
84 * (This isn't intended to be the externally-called one.)
86 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
87 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
88 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
89 /* Assumes algo->Parameters.pbData is set ahead of time. Internal func. */
90 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
91 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
92 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
93 /* Internal function */
94 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
95 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
96 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
97 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
98 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
99 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
100 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
101 /* Like CRYPT_AsnDecodeBits, but assumes the CRYPT_INTEGER_BLOB's pbData
102 * member has been initialized, doesn't do exception handling, and doesn't do
105 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
106 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
107 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
108 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
109 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
110 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
111 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
112 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
113 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
114 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
115 * member has been initialized, doesn't do exception handling, and doesn't do
116 * memory allocation. Also doesn't check tag, assumes the caller has checked
119 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
120 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
121 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
122 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
123 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
124 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
125 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
126 void *pvStructInfo
, DWORD
*pcbStructInfo
);
128 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
129 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
130 DWORD
*pcbStructInfo
)
132 static HCRYPTOIDFUNCSET set
= NULL
;
134 CryptDecodeObjectFunc pCryptDecodeObject
;
135 HCRYPTOIDFUNCADDR hFunc
;
137 TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
138 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
139 pvStructInfo
, pcbStructInfo
);
141 if (!pvStructInfo
&& !pcbStructInfo
)
143 SetLastError(ERROR_INVALID_PARAMETER
);
147 /* Try registered DLL first.. */
149 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
150 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
151 (void **)&pCryptDecodeObject
, &hFunc
);
152 if (pCryptDecodeObject
)
154 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
155 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
156 CryptFreeOIDFunctionAddress(hFunc
, 0);
160 /* If not, use CryptDecodeObjectEx */
161 ret
= CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
, pbEncoded
,
162 cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
167 /* Gets the number of length bytes from the given (leading) length byte */
168 #define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
170 /* Helper function to get the encoded length of the data starting at pbEncoded,
171 * where pbEncoded[0] is the tag. If the data are too short to contain a
172 * length or if the length is too large for cbEncoded, sets an appropriate
173 * error code and returns FALSE.
175 static BOOL WINAPI
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
182 SetLastError(CRYPT_E_ASN1_CORRUPT
);
185 else if (pbEncoded
[1] <= 0x7f)
187 if (pbEncoded
[1] + 1 > cbEncoded
)
189 SetLastError(CRYPT_E_ASN1_EOD
);
200 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
202 if (lenLen
> sizeof(DWORD
) + 1)
204 SetLastError(CRYPT_E_ASN1_LARGE
);
207 else if (lenLen
+ 2 > cbEncoded
)
209 SetLastError(CRYPT_E_ASN1_CORRUPT
);
222 if (out
+ lenLen
+ 1 > cbEncoded
)
224 SetLastError(CRYPT_E_ASN1_EOD
);
237 /* Helper function to check *pcbStructInfo, set it to the required size, and
238 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
239 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
240 * pointer to the newly allocated memory.
242 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
243 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
248 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
250 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
251 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
253 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
254 if (!*(BYTE
**)pvStructInfo
)
257 *pcbStructInfo
= bytesNeeded
;
259 else if (*pcbStructInfo
< bytesNeeded
)
261 *pcbStructInfo
= bytesNeeded
;
262 SetLastError(ERROR_MORE_DATA
);
269 * The expected tag of the item. If tag is 0, decodeFunc is called
270 * regardless of the tag value seen.
272 * A sequence is decoded into a struct. The offset member is the
273 * offset of this item within that struct.
275 * The decoder function to use. If this is NULL, then the member isn't
276 * decoded, but minSize space is reserved for it.
278 * The minimum amount of space occupied after decoding. You must set this.
280 * If true, and the tag doesn't match the expected tag for this item,
281 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
282 * filled with 0 for this member.
283 * hasPointer, pointerOffset, minSize:
284 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
285 * the offset within the (outer) struct of the data pointer (or to the
286 * first data pointer, if more than one exist).
288 * Used by CRYPT_AsnDecodeSequence, not for your use.
290 struct AsnDecodeSequenceItem
294 CryptDecodeObjectExFunc decodeFunc
;
302 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
303 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
304 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
)
310 ptr
= pbEncoded
+ 1 + GET_LEN_BYTES(pbEncoded
[1]);
311 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
313 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
317 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
320 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
322 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
324 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
326 TRACE("Setting next pointer to %p\n",
328 *(BYTE
**)((BYTE
*)pvStructInfo
+
329 items
[i
].pointerOffset
) = nextData
;
331 if (items
[i
].decodeFunc
)
334 TRACE("decoding item %d\n", i
);
336 TRACE("sizing item %d\n", i
);
337 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
338 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
339 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
340 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
341 : NULL
, &items
[i
].size
);
344 if (nextData
&& items
[i
].hasPointer
&&
345 items
[i
].size
> items
[i
].minSize
)
347 nextData
+= items
[i
].size
- items
[i
].minSize
;
348 /* align nextData to DWORD boundaries */
349 if (items
[i
].size
% sizeof(DWORD
))
350 nextData
+= sizeof(DWORD
) - items
[i
].size
%
353 /* Account for alignment padding */
354 if (items
[i
].size
% sizeof(DWORD
))
355 items
[i
].size
+= sizeof(DWORD
) -
356 items
[i
].size
% sizeof(DWORD
);
357 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
359 else if (items
[i
].optional
&&
360 GetLastError() == CRYPT_E_ASN1_BADTAG
)
362 TRACE("skipping optional item %d\n", i
);
363 items
[i
].size
= items
[i
].minSize
;
364 SetLastError(NOERROR
);
368 TRACE("item %d failed: %08x\n", i
,
372 items
[i
].size
= items
[i
].minSize
;
374 else if (items
[i
].optional
)
376 TRACE("skipping optional item %d\n", i
);
377 items
[i
].size
= items
[i
].minSize
;
381 TRACE("tag %02x doesn't match expected %02x\n",
382 ptr
[0], items
[i
].tag
);
383 SetLastError(CRYPT_E_ASN1_BADTAG
);
388 else if (items
[i
].optional
)
390 TRACE("missing optional item %d, skipping\n", i
);
391 items
[i
].size
= items
[i
].minSize
;
395 TRACE("not enough bytes for item %d, failing\n", i
);
396 SetLastError(CRYPT_E_ASN1_CORRUPT
);
400 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
402 TRACE("%d remaining bytes, failing\n", cbEncoded
-
404 SetLastError(CRYPT_E_ASN1_CORRUPT
);
410 /* This decodes an arbitrary sequence into a contiguous block of memory
411 * (basically, a struct.) Each element being decoded is described by a struct
412 * AsnDecodeSequenceItem, see above.
413 * startingPointer is an optional pointer to the first place where dynamic
414 * data will be stored. If you know the starting offset, you may pass it
415 * here. Otherwise, pass NULL, and one will be inferred from the items.
416 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
417 * If any undecoded data are left over, fails with CRYPT_E_ASN1_CORRUPT.
419 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
420 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
421 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
422 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
426 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
427 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
430 if (pbEncoded
[0] == ASN_SEQUENCE
)
434 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
438 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, pbEncoded
,
439 cbEncoded
, dwFlags
, NULL
, NULL
);
442 DWORD bytesNeeded
= 0, structSize
= 0;
444 for (i
= 0; i
< cItem
; i
++)
446 bytesNeeded
+= items
[i
].size
;
447 structSize
+= items
[i
].minSize
;
450 *pcbStructInfo
= bytesNeeded
;
451 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
452 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
456 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
457 pvStructInfo
= *(BYTE
**)pvStructInfo
;
459 nextData
= (BYTE
*)startingPointer
;
461 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
462 memset(pvStructInfo
, 0, structSize
);
463 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
464 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
);
471 SetLastError(CRYPT_E_ASN1_BADTAG
);
474 TRACE("returning %d (%08x)\n", ret
, GetLastError());
479 * The expected tag of the entire encoded array (usually a variant
480 * of ASN_SETOF or ASN_SEQUENCEOF.)
482 * used to decode each item in the array
484 * is the minimum size of each decoded item
486 * indicates whether each item has a dynamic pointer
488 * indicates the offset within itemSize at which the pointer exists
490 struct AsnArrayDescriptor
493 CryptDecodeObjectExFunc decodeFunc
;
499 struct AsnArrayItemSize
505 /* Decodes an array of like types into a struct GenericArray.
506 * The layout and decoding of the array are described by a struct
507 * AsnArrayDescriptor.
509 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
510 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
511 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
512 void *startingPointer
)
516 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
517 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
520 if (pbEncoded
[0] == arrayDesc
->tag
)
524 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
526 DWORD bytesNeeded
, cItems
= 0;
527 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
528 /* There can be arbitrarily many items, but there is often only one.
530 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
532 bytesNeeded
= sizeof(struct GenericArray
);
537 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
538 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
540 DWORD itemLenBytes
, itemDataLen
, size
;
542 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
543 /* Each item decoded may not tolerate extraneous bytes, so
544 * get the length of the next element and pass it directly.
546 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
549 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
550 1 + itemLenBytes
+ itemDataLen
,
551 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
558 if (itemSizes
!= &itemSize
)
559 itemSizes
= CryptMemRealloc(itemSizes
,
560 cItems
* sizeof(struct AsnArrayItemSize
));
565 cItems
* sizeof(struct AsnArrayItemSize
));
567 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
571 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
573 itemSizes
[cItems
- 1].size
= size
;
575 ret
= CRYPT_GetLen(ptr
,
576 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
578 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
588 *pcbStructInfo
= bytesNeeded
;
589 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
590 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
595 struct GenericArray
*array
;
597 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
598 pvStructInfo
= *(BYTE
**)pvStructInfo
;
599 array
= (struct GenericArray
*)pvStructInfo
;
600 array
->cItems
= cItems
;
602 array
->rgItems
= startingPointer
;
604 array
->rgItems
= (BYTE
*)array
+
605 sizeof(struct GenericArray
);
606 nextData
= (BYTE
*)array
->rgItems
+
607 array
->cItems
* arrayDesc
->itemSize
;
608 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
609 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
612 if (arrayDesc
->hasPointer
)
613 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
614 + arrayDesc
->pointerOffset
) = nextData
;
615 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
616 itemSizes
[i
].encodedLen
,
617 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
618 array
->rgItems
+ i
* arrayDesc
->itemSize
,
624 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
625 ret
= CRYPT_GetLen(ptr
,
626 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
628 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
633 if (itemSizes
!= &itemSize
)
634 CryptMemFree(itemSizes
);
639 SetLastError(CRYPT_E_ASN1_BADTAG
);
645 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
646 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
647 * to CRYPT_E_ASN1_CORRUPT.
648 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
651 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
652 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
653 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
658 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
660 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
661 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
663 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
664 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
667 *pcbStructInfo
= bytesNeeded
;
668 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
669 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
671 CRYPT_DER_BLOB
*blob
;
673 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
674 pvStructInfo
= *(BYTE
**)pvStructInfo
;
675 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
676 blob
->cbData
= 1 + lenBytes
+ dataLen
;
679 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
680 blob
->pbData
= (BYTE
*)pbEncoded
;
683 assert(blob
->pbData
);
684 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
689 SetLastError(CRYPT_E_ASN1_CORRUPT
);
697 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
698 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
699 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
700 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
704 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
705 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
707 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
710 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
711 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
712 pvStructInfo
, pcbStructInfo
);
713 if (ret
&& pvStructInfo
)
715 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
722 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
724 temp
= blob
->pbData
[i
];
725 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
726 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
730 TRACE("returning %d (%08x)\n", ret
, GetLastError());
734 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
735 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
736 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
740 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
741 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
745 struct AsnDecodeSequenceItem items
[] = {
746 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
747 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
748 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
749 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
750 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
751 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
752 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
753 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
754 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
755 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
758 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
759 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
760 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
761 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
762 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
766 SetLastError(STATUS_ACCESS_VIOLATION
);
771 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
775 /* Internal function */
776 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
777 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
778 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
783 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
785 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
787 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
788 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
789 pvStructInfo
, pcbStructInfo
);
794 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
795 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
796 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
800 struct AsnDecodeSequenceItem items
[] = {
801 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
802 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
803 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
804 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
807 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
808 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
809 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
813 /* Internal function */
814 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
815 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
816 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
821 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
823 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
825 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
826 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
827 pDecodePara
, pvStructInfo
, pcbStructInfo
);
832 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
833 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
834 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
837 struct AsnDecodeSequenceItem items
[] = {
838 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
839 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
840 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
841 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
842 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
843 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
844 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
845 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
846 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
847 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
849 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
850 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
852 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
853 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
855 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
856 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
857 FALSE
, TRUE
, offsetof(CERT_INFO
,
858 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
859 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
860 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
861 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
862 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
863 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
864 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
865 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
866 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
867 offsetof(CERT_INFO
, rgExtension
), 0 },
870 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
871 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
873 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
874 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
875 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
877 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
881 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
882 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
883 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
887 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
888 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
892 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
895 /* First try to decode it as a signed cert. */
896 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
897 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
898 (BYTE
*)&signedCert
, &size
);
902 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
903 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
904 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
, pvStructInfo
,
906 LocalFree(signedCert
);
908 /* Failing that, try it as an unsigned cert */
912 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
913 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
914 pDecodePara
, pvStructInfo
, pcbStructInfo
);
919 SetLastError(STATUS_ACCESS_VIOLATION
);
924 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
928 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
929 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
930 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
933 struct AsnDecodeSequenceItem items
[] = {
934 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
935 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
936 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
937 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
938 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
939 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
940 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
941 offsetof(CRL_ENTRY
, rgExtension
), 0 },
943 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
945 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
948 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
949 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
950 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
954 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
955 * been set prior to calling.
957 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
958 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
959 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
962 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
963 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
964 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
965 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
967 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
968 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
970 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
971 pDecodePara
, pvStructInfo
, pcbStructInfo
,
972 entries
? entries
->rgItems
: NULL
);
973 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
977 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
978 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
979 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
981 struct AsnDecodeSequenceItem items
[] = {
982 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
983 CRYPT_AsnDecodeInt
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
984 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
985 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
986 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
987 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
988 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
990 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
991 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
992 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
993 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
994 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
995 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
996 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
997 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
998 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
999 offsetof(CRL_INFO
, rgExtension
), 0 },
1003 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1004 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1006 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1007 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1008 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1010 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1014 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1015 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1016 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1020 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1021 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1025 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1028 /* First try to decode it as a signed crl. */
1029 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
1030 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1031 (BYTE
*)&signedCrl
, &size
);
1035 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1036 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1037 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1038 pvStructInfo
, pcbStructInfo
);
1039 LocalFree(signedCrl
);
1041 /* Failing that, try it as an unsigned crl */
1045 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1046 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1047 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1052 SetLastError(STATUS_ACCESS_VIOLATION
);
1057 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1061 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
1062 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1063 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1067 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1068 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1070 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1074 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1076 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1077 DWORD bytesNeeded
= sizeof(LPSTR
);
1081 /* The largest possible string for the first two components
1082 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1087 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1088 pbEncoded
[1 + lenBytes
] / 40,
1089 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1091 bytesNeeded
+= strlen(firstTwo
) + 1;
1092 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1093 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1095 /* large enough for ".4000000" */
1099 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1106 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1109 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1116 snprintf(str
, sizeof(str
), ".%d", val
);
1117 bytesNeeded
+= strlen(str
);
1122 *pcbStructInfo
= bytesNeeded
;
1123 else if (*pcbStructInfo
< bytesNeeded
)
1125 *pcbStructInfo
= bytesNeeded
;
1126 SetLastError(ERROR_MORE_DATA
);
1134 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1137 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1138 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1140 pszObjId
+= strlen(pszObjId
);
1141 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1142 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1146 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1155 sprintf(pszObjId
, ".%d", val
);
1156 pszObjId
+= strlen(pszObjId
);
1160 *(LPSTR
*)pvStructInfo
= NULL
;
1161 *pcbStructInfo
= bytesNeeded
;
1168 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1171 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1172 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1173 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1175 struct AsnDecodeSequenceItem items
[] = {
1176 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1177 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1178 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1179 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1180 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1181 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1182 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1183 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1186 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1188 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1192 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1193 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1194 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1195 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1197 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1198 debugstr_a(ext
->pszObjId
));
1199 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1203 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1204 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1205 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1208 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1209 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1210 offsetof(CERT_EXTENSION
, pszObjId
) };
1211 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1213 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1214 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1216 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1217 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1221 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1222 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1223 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1229 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1230 lpszStructType
, pbEncoded
, cbEncoded
,
1231 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1232 if (ret
&& pvStructInfo
)
1234 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1235 pcbStructInfo
, *pcbStructInfo
);
1238 CERT_EXTENSIONS
*exts
;
1240 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1241 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1242 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1243 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1244 sizeof(CERT_EXTENSIONS
));
1245 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1246 lpszStructType
, pbEncoded
, cbEncoded
,
1247 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1254 SetLastError(STATUS_ACCESS_VIOLATION
);
1261 /* Warning: this assumes the address of value->Value.pbData is already set, in
1262 * order to avoid overwriting memory. (In some cases, it may change it, if it
1263 * doesn't copy anything to memory.) Be sure to set it correctly!
1265 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1266 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1267 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1271 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1273 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1275 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1276 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1278 switch (pbEncoded
[0])
1280 case ASN_OCTETSTRING
:
1281 valueType
= CERT_RDN_OCTET_STRING
;
1282 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1283 bytesNeeded
+= dataLen
;
1285 case ASN_NUMERICSTRING
:
1286 valueType
= CERT_RDN_NUMERIC_STRING
;
1287 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1288 bytesNeeded
+= dataLen
;
1290 case ASN_PRINTABLESTRING
:
1291 valueType
= CERT_RDN_PRINTABLE_STRING
;
1292 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1293 bytesNeeded
+= dataLen
;
1296 valueType
= CERT_RDN_IA5_STRING
;
1297 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1298 bytesNeeded
+= dataLen
;
1301 valueType
= CERT_RDN_T61_STRING
;
1302 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1303 bytesNeeded
+= dataLen
;
1305 case ASN_VIDEOTEXSTRING
:
1306 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1307 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1308 bytesNeeded
+= dataLen
;
1310 case ASN_GRAPHICSTRING
:
1311 valueType
= CERT_RDN_GRAPHIC_STRING
;
1312 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1313 bytesNeeded
+= dataLen
;
1315 case ASN_VISIBLESTRING
:
1316 valueType
= CERT_RDN_VISIBLE_STRING
;
1317 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1318 bytesNeeded
+= dataLen
;
1320 case ASN_GENERALSTRING
:
1321 valueType
= CERT_RDN_GENERAL_STRING
;
1322 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1323 bytesNeeded
+= dataLen
;
1325 case ASN_UNIVERSALSTRING
:
1326 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1327 SetLastError(CRYPT_E_ASN1_BADTAG
);
1330 valueType
= CERT_RDN_BMP_STRING
;
1331 bytesNeeded
+= dataLen
;
1333 case ASN_UTF8STRING
:
1334 valueType
= CERT_RDN_UTF8_STRING
;
1335 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1336 (LPSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1339 SetLastError(CRYPT_E_ASN1_BADTAG
);
1344 *pcbStructInfo
= bytesNeeded
;
1345 else if (*pcbStructInfo
< bytesNeeded
)
1347 *pcbStructInfo
= bytesNeeded
;
1348 SetLastError(ERROR_MORE_DATA
);
1353 *pcbStructInfo
= bytesNeeded
;
1354 value
->dwValueType
= valueType
;
1359 assert(value
->Value
.pbData
);
1360 switch (pbEncoded
[0])
1362 case ASN_OCTETSTRING
:
1363 case ASN_NUMERICSTRING
:
1364 case ASN_PRINTABLESTRING
:
1367 case ASN_VIDEOTEXSTRING
:
1368 case ASN_GRAPHICSTRING
:
1369 case ASN_VISIBLESTRING
:
1370 case ASN_GENERALSTRING
:
1371 value
->Value
.cbData
= dataLen
;
1374 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1375 memcpy(value
->Value
.pbData
,
1376 pbEncoded
+ 1 + lenBytes
, dataLen
);
1378 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1384 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1386 value
->Value
.cbData
= dataLen
;
1387 for (i
= 0; i
< dataLen
/ 2; i
++)
1388 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1389 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1392 case ASN_UTF8STRING
:
1394 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1396 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1397 (LPSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1398 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1405 value
->Value
.cbData
= 0;
1406 value
->Value
.pbData
= NULL
;
1413 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1414 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1415 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1421 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1422 lpszStructType
, pbEncoded
, cbEncoded
,
1423 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1424 if (ret
&& pvStructInfo
)
1426 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1427 pcbStructInfo
, *pcbStructInfo
);
1430 CERT_NAME_VALUE
*value
;
1432 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1433 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1434 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1435 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1436 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1437 lpszStructType
, pbEncoded
, cbEncoded
,
1438 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1445 SetLastError(STATUS_ACCESS_VIOLATION
);
1452 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1453 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1454 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1455 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1459 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1461 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1463 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1464 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1466 switch (pbEncoded
[0])
1468 case ASN_NUMERICSTRING
:
1469 valueType
= CERT_RDN_NUMERIC_STRING
;
1470 bytesNeeded
+= dataLen
* 2;
1472 case ASN_PRINTABLESTRING
:
1473 valueType
= CERT_RDN_PRINTABLE_STRING
;
1474 bytesNeeded
+= dataLen
* 2;
1477 valueType
= CERT_RDN_IA5_STRING
;
1478 bytesNeeded
+= dataLen
* 2;
1481 valueType
= CERT_RDN_T61_STRING
;
1482 bytesNeeded
+= dataLen
* 2;
1484 case ASN_VIDEOTEXSTRING
:
1485 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1486 bytesNeeded
+= dataLen
* 2;
1488 case ASN_GRAPHICSTRING
:
1489 valueType
= CERT_RDN_GRAPHIC_STRING
;
1490 bytesNeeded
+= dataLen
* 2;
1492 case ASN_VISIBLESTRING
:
1493 valueType
= CERT_RDN_VISIBLE_STRING
;
1494 bytesNeeded
+= dataLen
* 2;
1496 case ASN_GENERALSTRING
:
1497 valueType
= CERT_RDN_GENERAL_STRING
;
1498 bytesNeeded
+= dataLen
* 2;
1500 case ASN_UNIVERSALSTRING
:
1501 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1502 bytesNeeded
+= dataLen
/ 2;
1505 valueType
= CERT_RDN_BMP_STRING
;
1506 bytesNeeded
+= dataLen
;
1508 case ASN_UTF8STRING
:
1509 valueType
= CERT_RDN_UTF8_STRING
;
1510 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1511 (LPSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1514 SetLastError(CRYPT_E_ASN1_BADTAG
);
1519 *pcbStructInfo
= bytesNeeded
;
1520 else if (*pcbStructInfo
< bytesNeeded
)
1522 *pcbStructInfo
= bytesNeeded
;
1523 SetLastError(ERROR_MORE_DATA
);
1528 *pcbStructInfo
= bytesNeeded
;
1529 value
->dwValueType
= valueType
;
1533 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1535 assert(value
->Value
.pbData
);
1536 switch (pbEncoded
[0])
1538 case ASN_NUMERICSTRING
:
1539 case ASN_PRINTABLESTRING
:
1542 case ASN_VIDEOTEXSTRING
:
1543 case ASN_GRAPHICSTRING
:
1544 case ASN_VISIBLESTRING
:
1545 case ASN_GENERALSTRING
:
1546 value
->Value
.cbData
= dataLen
* 2;
1547 for (i
= 0; i
< dataLen
; i
++)
1548 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1550 case ASN_UNIVERSALSTRING
:
1551 value
->Value
.cbData
= dataLen
/ 2;
1552 for (i
= 0; i
< dataLen
/ 4; i
++)
1553 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1554 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1557 value
->Value
.cbData
= dataLen
;
1558 for (i
= 0; i
< dataLen
/ 2; i
++)
1559 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1560 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1562 case ASN_UTF8STRING
:
1563 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1564 (LPSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1565 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1571 value
->Value
.cbData
= 0;
1572 value
->Value
.pbData
= NULL
;
1579 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1580 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1581 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1587 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1588 lpszStructType
, pbEncoded
, cbEncoded
,
1589 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1590 if (ret
&& pvStructInfo
)
1592 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1593 pcbStructInfo
, *pcbStructInfo
);
1596 CERT_NAME_VALUE
*value
;
1598 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1599 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1600 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1601 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1602 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1603 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1604 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1611 SetLastError(STATUS_ACCESS_VIOLATION
);
1618 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1619 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1620 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1623 struct AsnDecodeSequenceItem items
[] = {
1624 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1625 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1626 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1627 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1628 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1629 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1631 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1633 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1634 pvStructInfo
, *pcbStructInfo
);
1637 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1638 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1639 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1640 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1643 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1644 debugstr_a(attr
->pszObjId
));
1645 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1647 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1651 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1652 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1653 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1656 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1657 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1658 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1659 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1661 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1662 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1666 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1667 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1668 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1674 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1675 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1676 offsetof(CERT_RDN
, rgRDNAttr
) };
1678 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1679 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1683 SetLastError(STATUS_ACCESS_VIOLATION
);
1690 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType
,
1691 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1692 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1695 struct AsnDecodeSequenceItem items
[] = {
1696 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1697 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1698 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1699 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1700 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1701 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1703 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1705 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1706 pvStructInfo
, *pcbStructInfo
);
1709 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1710 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1711 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1712 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1715 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1716 debugstr_a(attr
->pszObjId
));
1717 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1719 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1723 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType
,
1724 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1725 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1728 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1729 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1730 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1731 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1733 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1734 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1738 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1739 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1740 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1746 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1747 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1748 offsetof(CERT_RDN
, rgRDNAttr
) };
1750 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1751 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1755 SetLastError(STATUS_ACCESS_VIOLATION
);
1762 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1763 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1764 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1767 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1769 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1770 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1772 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1773 bytesNeeded
+= cbEncoded
;
1775 *pcbStructInfo
= bytesNeeded
;
1776 else if (*pcbStructInfo
< bytesNeeded
)
1778 SetLastError(ERROR_MORE_DATA
);
1779 *pcbStructInfo
= bytesNeeded
;
1784 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1786 *pcbStructInfo
= bytesNeeded
;
1787 blob
->cbData
= cbEncoded
;
1788 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1789 blob
->pbData
= (LPBYTE
)pbEncoded
;
1792 assert(blob
->pbData
);
1793 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1799 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1800 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1801 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1803 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1804 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1806 struct AsnDecodeSequenceItem items
[] = {
1807 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1808 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1809 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1810 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1811 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1812 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1815 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1816 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1818 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1819 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1820 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1821 if (ret
&& pvStructInfo
)
1823 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1824 debugstr_a(algo
->pszObjId
));
1829 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1830 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1831 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1834 struct AsnDecodeSequenceItem items
[] = {
1835 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1836 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1837 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
1838 Algorithm
.pszObjId
) },
1839 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
1840 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1841 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
1843 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1845 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1846 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1847 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
1848 info
->Algorithm
.Parameters
.pbData
: NULL
);
1852 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
1853 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1854 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1862 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1863 lpszStructType
, pbEncoded
, cbEncoded
,
1864 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1867 *pcbStructInfo
= bytesNeeded
;
1868 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1869 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1871 PCERT_PUBLIC_KEY_INFO info
;
1873 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1874 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1875 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1876 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
1877 sizeof(CERT_PUBLIC_KEY_INFO
);
1878 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1879 lpszStructType
, pbEncoded
, cbEncoded
,
1880 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1887 SetLastError(STATUS_ACCESS_VIOLATION
);
1894 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
1895 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1896 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1902 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1905 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
1907 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1910 if (pbEncoded
[1] > 1)
1912 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1917 *pcbStructInfo
= sizeof(BOOL
);
1920 else if (*pcbStructInfo
< sizeof(BOOL
))
1922 *pcbStructInfo
= sizeof(BOOL
);
1923 SetLastError(ERROR_MORE_DATA
);
1928 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
1931 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1935 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
1936 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1937 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1939 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
1940 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
1943 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1944 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1948 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1951 if ((pbEncoded
[0] & ASN_FLAGS_MASK
) != ASN_CONTEXT
)
1953 SetLastError(CRYPT_E_ASN1_BADTAG
);
1956 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1957 if (1 + lenBytes
> cbEncoded
)
1959 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1962 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1964 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
1966 case 1: /* rfc822Name */
1967 case 2: /* dNSName */
1968 case 6: /* uniformResourceIdentifier */
1969 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
1971 case 7: /* iPAddress */
1972 bytesNeeded
+= dataLen
;
1974 case 8: /* registeredID */
1975 /* FIXME: decode as OID */
1976 case 0: /* otherName */
1977 case 4: /* directoryName */
1979 SetLastError(CRYPT_E_ASN1_BADTAG
);
1982 case 3: /* x400Address, unimplemented */
1983 case 5: /* ediPartyName, unimplemented */
1984 SetLastError(CRYPT_E_ASN1_BADTAG
);
1988 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1994 *pcbStructInfo
= bytesNeeded
;
1995 else if (*pcbStructInfo
< bytesNeeded
)
1997 *pcbStructInfo
= bytesNeeded
;
1998 SetLastError(ERROR_MORE_DATA
);
2003 *pcbStructInfo
= bytesNeeded
;
2004 /* MS used values one greater than the asn1 ones.. sigh */
2005 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2006 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2008 case 1: /* rfc822Name */
2009 case 2: /* dNSName */
2010 case 6: /* uniformResourceIdentifier */
2014 for (i
= 0; i
< dataLen
; i
++)
2015 entry
->u
.pwszURL
[i
] =
2016 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2017 entry
->u
.pwszURL
[i
] = 0;
2018 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2019 debugstr_w(entry
->u
.pwszURL
));
2022 case 7: /* iPAddress */
2023 /* The next data pointer is in the pwszURL spot, that is,
2024 * the first 4 bytes. Need to move it to the next spot.
2026 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2027 entry
->u
.IPAddress
.cbData
= dataLen
;
2028 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2038 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2039 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2040 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2043 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2044 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2045 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2046 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2048 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2049 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2052 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2053 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2054 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
2058 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2059 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2060 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2066 struct AsnDecodeSequenceItem items
[] = {
2067 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2068 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2069 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2070 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2071 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2072 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2073 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2074 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2075 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2076 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2077 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2080 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2081 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2082 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2086 SetLastError(STATUS_ACCESS_VIOLATION
);
2093 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2094 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2095 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2099 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2100 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2104 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2105 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2106 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2108 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2109 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2113 SetLastError(STATUS_ACCESS_VIOLATION
);
2120 struct PATH_LEN_CONSTRAINT
2122 BOOL fPathLenConstraint
;
2123 DWORD dwPathLenConstraint
;
2126 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2127 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2128 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2132 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2133 pvStructInfo
, *pcbStructInfo
);
2137 if (pbEncoded
[0] == ASN_INTEGER
)
2139 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2142 *pcbStructInfo
= bytesNeeded
;
2143 else if (*pcbStructInfo
< bytesNeeded
)
2145 SetLastError(ERROR_MORE_DATA
);
2146 *pcbStructInfo
= bytesNeeded
;
2151 struct PATH_LEN_CONSTRAINT
*constraint
=
2152 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2153 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2155 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
2156 pbEncoded
, cbEncoded
, 0, NULL
,
2157 &constraint
->dwPathLenConstraint
, &size
);
2159 constraint
->fPathLenConstraint
= TRUE
;
2160 TRACE("got an int, dwPathLenConstraint is %d\n",
2161 constraint
->dwPathLenConstraint
);
2166 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2170 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2174 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2175 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2176 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2179 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2180 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2181 offsetof(CERT_NAME_BLOB
, pbData
) };
2182 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2184 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2185 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2187 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2188 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2189 entries
? entries
->rgItems
: NULL
);
2190 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2194 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2195 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2196 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2202 struct AsnDecodeSequenceItem items
[] = {
2203 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2204 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2205 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2206 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2207 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2208 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2209 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2210 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2211 sizeof(struct GenericArray
), TRUE
, TRUE
,
2212 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2215 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2216 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2217 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2221 SetLastError(STATUS_ACCESS_VIOLATION
);
2228 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2229 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2230 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2236 struct AsnDecodeSequenceItem items
[] = {
2237 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2238 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2239 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2240 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2241 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2244 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2245 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2246 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2250 SetLastError(STATUS_ACCESS_VIOLATION
);
2257 #define RSA1_MAGIC 0x31415352
2259 struct DECODED_RSA_PUB_KEY
2262 CRYPT_INTEGER_BLOB modulus
;
2265 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2266 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2267 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2273 struct AsnDecodeSequenceItem items
[] = {
2274 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2275 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2276 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2278 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2279 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2281 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2284 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2285 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2286 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
2289 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2290 decodedKey
->modulus
.cbData
;
2294 *pcbStructInfo
= bytesNeeded
;
2297 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2298 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2301 RSAPUBKEY
*rsaPubKey
;
2303 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2304 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2305 hdr
= (BLOBHEADER
*)pvStructInfo
;
2306 hdr
->bType
= PUBLICKEYBLOB
;
2307 hdr
->bVersion
= CUR_BLOB_VERSION
;
2309 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2310 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2311 sizeof(BLOBHEADER
));
2312 rsaPubKey
->magic
= RSA1_MAGIC
;
2313 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2314 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2315 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2316 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2317 decodedKey
->modulus
.cbData
);
2319 LocalFree(decodedKey
);
2324 SetLastError(STATUS_ACCESS_VIOLATION
);
2331 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2332 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2333 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2336 DWORD bytesNeeded
, dataLen
;
2338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2339 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2341 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2343 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2344 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2346 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2348 *pcbStructInfo
= bytesNeeded
;
2349 else if (*pcbStructInfo
< bytesNeeded
)
2351 SetLastError(ERROR_MORE_DATA
);
2352 *pcbStructInfo
= bytesNeeded
;
2357 CRYPT_DATA_BLOB
*blob
;
2358 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2360 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2361 blob
->cbData
= dataLen
;
2362 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2363 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2366 assert(blob
->pbData
);
2368 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2376 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2377 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2378 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2382 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2383 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2391 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2394 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2396 SetLastError(CRYPT_E_ASN1_BADTAG
);
2399 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2400 lpszStructType
, pbEncoded
, cbEncoded
,
2401 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2404 *pcbStructInfo
= bytesNeeded
;
2405 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2406 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2408 CRYPT_DATA_BLOB
*blob
;
2410 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2411 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2412 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2413 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2414 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2415 lpszStructType
, pbEncoded
, cbEncoded
,
2416 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2423 SetLastError(STATUS_ACCESS_VIOLATION
);
2430 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2431 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2432 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2436 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2437 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2439 if (pbEncoded
[0] == ASN_BITSTRING
)
2441 DWORD bytesNeeded
, dataLen
;
2443 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2445 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2446 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2448 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2450 *pcbStructInfo
= bytesNeeded
;
2451 else if (*pcbStructInfo
< bytesNeeded
)
2453 *pcbStructInfo
= bytesNeeded
;
2454 SetLastError(ERROR_MORE_DATA
);
2459 CRYPT_BIT_BLOB
*blob
;
2461 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2462 blob
->cbData
= dataLen
- 1;
2463 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2464 GET_LEN_BYTES(pbEncoded
[1]));
2465 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2467 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2468 GET_LEN_BYTES(pbEncoded
[1]);
2472 assert(blob
->pbData
);
2475 BYTE mask
= 0xff << blob
->cUnusedBits
;
2477 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2478 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2479 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2487 SetLastError(CRYPT_E_ASN1_BADTAG
);
2490 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2494 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2495 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2496 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2500 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2501 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2507 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2508 lpszStructType
, pbEncoded
, cbEncoded
,
2509 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2512 *pcbStructInfo
= bytesNeeded
;
2513 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2514 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2516 CRYPT_BIT_BLOB
*blob
;
2518 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2519 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2520 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2521 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2522 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2523 lpszStructType
, pbEncoded
, cbEncoded
,
2524 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2531 SetLastError(STATUS_ACCESS_VIOLATION
);
2535 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2539 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2540 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2541 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2547 *pcbStructInfo
= sizeof(int);
2552 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2553 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2554 DWORD size
= sizeof(buf
);
2556 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2557 if (pbEncoded
[0] != ASN_INTEGER
)
2559 SetLastError(CRYPT_E_ASN1_BADTAG
);
2563 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2564 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
,
2568 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2569 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2573 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2574 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2575 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2577 /* initialize to a negative value to sign-extend */
2582 for (i
= 0; i
< blob
->cbData
; i
++)
2585 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2587 memcpy(pvStructInfo
, &val
, sizeof(int));
2590 else if (GetLastError() == ERROR_MORE_DATA
)
2591 SetLastError(CRYPT_E_ASN1_LARGE
);
2595 SetLastError(STATUS_ACCESS_VIOLATION
);
2602 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2603 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2604 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2607 DWORD bytesNeeded
, dataLen
;
2609 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2611 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2613 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2615 *pcbStructInfo
= bytesNeeded
;
2616 else if (*pcbStructInfo
< bytesNeeded
)
2618 *pcbStructInfo
= bytesNeeded
;
2619 SetLastError(ERROR_MORE_DATA
);
2624 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2626 blob
->cbData
= dataLen
;
2627 assert(blob
->pbData
);
2632 for (i
= 0; i
< blob
->cbData
; i
++)
2634 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2643 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
2644 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2645 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2653 if (pbEncoded
[0] != ASN_INTEGER
)
2655 SetLastError(CRYPT_E_ASN1_BADTAG
);
2659 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2660 lpszStructType
, pbEncoded
, cbEncoded
,
2661 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
);
2665 *pcbStructInfo
= bytesNeeded
;
2666 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2667 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2669 CRYPT_INTEGER_BLOB
*blob
;
2671 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2672 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2673 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2674 blob
->pbData
= (BYTE
*)pvStructInfo
+
2675 sizeof(CRYPT_INTEGER_BLOB
);
2676 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2677 lpszStructType
, pbEncoded
, cbEncoded
,
2678 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2685 SetLastError(STATUS_ACCESS_VIOLATION
);
2692 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
2693 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2694 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2695 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2699 if (pbEncoded
[0] == ASN_INTEGER
)
2701 DWORD bytesNeeded
, dataLen
;
2703 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2705 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2707 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2709 *pcbStructInfo
= bytesNeeded
;
2710 else if (*pcbStructInfo
< bytesNeeded
)
2712 *pcbStructInfo
= bytesNeeded
;
2713 SetLastError(ERROR_MORE_DATA
);
2718 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2720 blob
->cbData
= dataLen
;
2721 assert(blob
->pbData
);
2722 /* remove leading zero byte if it exists */
2723 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
2732 for (i
= 0; i
< blob
->cbData
; i
++)
2734 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2743 SetLastError(CRYPT_E_ASN1_BADTAG
);
2749 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
2750 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2751 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2759 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2760 lpszStructType
, pbEncoded
, cbEncoded
,
2761 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2764 *pcbStructInfo
= bytesNeeded
;
2765 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2766 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2768 CRYPT_INTEGER_BLOB
*blob
;
2770 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2771 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2772 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2773 blob
->pbData
= (BYTE
*)pvStructInfo
+
2774 sizeof(CRYPT_INTEGER_BLOB
);
2775 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2776 lpszStructType
, pbEncoded
, cbEncoded
,
2777 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2784 SetLastError(STATUS_ACCESS_VIOLATION
);
2791 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
2792 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2793 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2799 *pcbStructInfo
= sizeof(int);
2804 if (pbEncoded
[0] == ASN_ENUMERATED
)
2806 unsigned int val
= 0, i
;
2810 SetLastError(CRYPT_E_ASN1_EOD
);
2813 else if (pbEncoded
[1] == 0)
2815 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2820 /* A little strange looking, but we have to accept a sign byte:
2821 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
2822 * assuming a small length is okay here, it has to be in short
2825 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
2827 SetLastError(CRYPT_E_ASN1_LARGE
);
2830 for (i
= 0; i
< pbEncoded
[1]; i
++)
2833 val
|= pbEncoded
[2 + i
];
2835 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2836 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
2838 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2839 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2840 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
2846 SetLastError(CRYPT_E_ASN1_BADTAG
);
2852 SetLastError(STATUS_ACCESS_VIOLATION
);
2859 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
2862 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
2867 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
2869 if (!isdigit(*(pbEncoded))) \
2871 SetLastError(CRYPT_E_ASN1_CORRUPT); \
2877 (word) += *(pbEncoded)++ - '0'; \
2882 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
2883 SYSTEMTIME
*sysTime
)
2890 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
2892 WORD hours
, minutes
= 0;
2893 BYTE sign
= *pbEncoded
++;
2896 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
2897 if (ret
&& hours
>= 24)
2899 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2904 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
2905 if (ret
&& minutes
>= 60)
2907 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2915 sysTime
->wHour
+= hours
;
2916 sysTime
->wMinute
+= minutes
;
2920 if (hours
> sysTime
->wHour
)
2923 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
2926 sysTime
->wHour
-= hours
;
2927 if (minutes
> sysTime
->wMinute
)
2930 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
2933 sysTime
->wMinute
-= minutes
;
2940 SetLastError(STATUS_ACCESS_VIOLATION
);
2947 #define MIN_ENCODED_TIME_LENGTH 10
2949 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
2950 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2951 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2957 *pcbStructInfo
= sizeof(FILETIME
);
2963 if (pbEncoded
[0] == ASN_UTCTIME
)
2967 SetLastError(CRYPT_E_ASN1_EOD
);
2970 else if (pbEncoded
[1] > 0x7f)
2972 /* long-form date strings really can't be valid */
2973 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2978 SYSTEMTIME sysTime
= { 0 };
2979 BYTE len
= pbEncoded
[1];
2981 if (len
< MIN_ENCODED_TIME_LENGTH
)
2983 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2989 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
2990 if (sysTime
.wYear
>= 50)
2991 sysTime
.wYear
+= 1900;
2993 sysTime
.wYear
+= 2000;
2994 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
2995 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
2996 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
2997 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3000 if (len
>= 2 && isdigit(*pbEncoded
) &&
3001 isdigit(*(pbEncoded
+ 1)))
3002 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3004 else if (isdigit(*pbEncoded
))
3005 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3008 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3011 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3012 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3015 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3016 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3017 ret
= SystemTimeToFileTime(&sysTime
,
3018 (FILETIME
*)pvStructInfo
);
3025 SetLastError(CRYPT_E_ASN1_BADTAG
);
3031 SetLastError(STATUS_ACCESS_VIOLATION
);
3038 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
3039 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3040 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3046 *pcbStructInfo
= sizeof(FILETIME
);
3052 if (pbEncoded
[0] == ASN_GENERALTIME
)
3056 SetLastError(CRYPT_E_ASN1_EOD
);
3059 else if (pbEncoded
[1] > 0x7f)
3061 /* long-form date strings really can't be valid */
3062 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3067 BYTE len
= pbEncoded
[1];
3069 if (len
< MIN_ENCODED_TIME_LENGTH
)
3071 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3076 SYSTEMTIME sysTime
= { 0 };
3079 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3080 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3081 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3082 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3085 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3088 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3090 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3097 /* workaround macro weirdness */
3098 digits
= min(len
, 3);
3099 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3100 sysTime
.wMilliseconds
);
3103 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3106 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3107 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3110 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3111 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3112 ret
= SystemTimeToFileTime(&sysTime
,
3113 (FILETIME
*)pvStructInfo
);
3120 SetLastError(CRYPT_E_ASN1_BADTAG
);
3126 SetLastError(STATUS_ACCESS_VIOLATION
);
3133 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3134 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3135 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3141 if (pbEncoded
[0] == ASN_UTCTIME
)
3142 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
3143 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3145 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3146 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
3147 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
3148 pvStructInfo
, pcbStructInfo
);
3151 SetLastError(CRYPT_E_ASN1_BADTAG
);
3157 SetLastError(STATUS_ACCESS_VIOLATION
);
3164 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3165 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3166 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3172 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3174 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3176 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3181 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3182 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3184 ptr
= pbEncoded
+ 1 + lenBytes
;
3185 remainingLen
= dataLen
;
3186 while (ret
&& remainingLen
)
3190 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3193 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3195 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3196 ptr
+= 1 + nextLenBytes
+ nextLen
;
3197 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3198 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3199 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3205 CRYPT_SEQUENCE_OF_ANY
*seq
;
3209 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3210 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3212 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3213 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3214 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3215 seq
->cValue
= cValue
;
3216 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3218 nextPtr
= (BYTE
*)seq
->rgValue
+
3219 cValue
* sizeof(CRYPT_DER_BLOB
);
3220 ptr
= pbEncoded
+ 1 + lenBytes
;
3221 remainingLen
= dataLen
;
3223 while (ret
&& remainingLen
)
3227 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3230 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3232 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3234 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3235 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3238 seq
->rgValue
[i
].pbData
= nextPtr
;
3239 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3241 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3243 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3244 ptr
+= 1 + nextLenBytes
+ nextLen
;
3254 SetLastError(CRYPT_E_ASN1_BADTAG
);
3260 SetLastError(STATUS_ACCESS_VIOLATION
);
3267 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3268 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3269 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3273 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3275 DWORD bytesNeeded
, dataLen
;
3277 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3279 struct AsnArrayDescriptor arrayDesc
= {
3280 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3281 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3282 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3283 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3289 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3290 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3291 0, NULL
, NULL
, &nameLen
, NULL
);
3292 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3295 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3297 *pcbStructInfo
= bytesNeeded
;
3298 else if (*pcbStructInfo
< bytesNeeded
)
3300 *pcbStructInfo
= bytesNeeded
;
3301 SetLastError(ERROR_MORE_DATA
);
3306 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3310 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3311 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3312 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3313 0, NULL
, &name
->u
.FullName
, pcbStructInfo
,
3314 name
->u
.FullName
.rgAltEntry
);
3317 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3323 SetLastError(CRYPT_E_ASN1_BADTAG
);
3329 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
3330 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3331 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3333 struct AsnDecodeSequenceItem items
[] = {
3334 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3335 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3336 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3337 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3338 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3339 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3340 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3341 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3342 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3343 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3347 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3348 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3349 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3353 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3354 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3355 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3359 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3360 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3364 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3365 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3366 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3368 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3369 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3373 SetLastError(STATUS_ACCESS_VIOLATION
);
3380 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3381 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3382 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3386 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3387 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3391 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3392 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3394 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3395 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3399 SetLastError(STATUS_ACCESS_VIOLATION
);
3406 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3407 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3408 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3412 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3413 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3417 struct AsnDecodeSequenceItem items
[] = {
3418 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3419 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3420 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3421 offsetof(CRL_ISSUING_DIST_POINT
,
3422 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3423 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3424 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3426 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
3427 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3429 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
3430 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
3431 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
3432 OnlySomeReasonFlags
.pbData
), 0 },
3433 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
3434 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
3437 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3438 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3439 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3443 SetLastError(STATUS_ACCESS_VIOLATION
);
3450 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
3451 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3452 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3454 static HCRYPTOIDFUNCSET set
= NULL
;
3456 CryptDecodeObjectExFunc decodeFunc
= NULL
;
3457 HCRYPTOIDFUNCADDR hFunc
= NULL
;
3459 TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
3460 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
3461 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3463 if (!pvStructInfo
&& !pcbStructInfo
)
3465 SetLastError(ERROR_INVALID_PARAMETER
);
3468 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
3469 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
3471 SetLastError(ERROR_FILE_NOT_FOUND
);
3476 SetLastError(CRYPT_E_ASN1_EOD
);
3479 if (cbEncoded
> MAX_ENCODED_LEN
)
3481 SetLastError(CRYPT_E_ASN1_LARGE
);
3485 SetLastError(NOERROR
);
3486 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
3487 *(BYTE
**)pvStructInfo
= NULL
;
3488 if (!HIWORD(lpszStructType
))
3490 switch (LOWORD(lpszStructType
))
3492 case (WORD
)X509_CERT
:
3493 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
3495 case (WORD
)X509_CERT_TO_BE_SIGNED
:
3496 decodeFunc
= CRYPT_AsnDecodeCert
;
3498 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
3499 decodeFunc
= CRYPT_AsnDecodeCRL
;
3501 case (WORD
)X509_EXTENSIONS
:
3502 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3504 case (WORD
)X509_NAME_VALUE
:
3505 decodeFunc
= CRYPT_AsnDecodeNameValue
;
3507 case (WORD
)X509_NAME
:
3508 decodeFunc
= CRYPT_AsnDecodeName
;
3510 case (WORD
)X509_PUBLIC_KEY_INFO
:
3511 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
3513 case (WORD
)X509_AUTHORITY_KEY_ID
:
3514 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3516 case (WORD
)X509_ALTERNATE_NAME
:
3517 decodeFunc
= CRYPT_AsnDecodeAltName
;
3519 case (WORD
)X509_BASIC_CONSTRAINTS
:
3520 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3522 case (WORD
)X509_BASIC_CONSTRAINTS2
:
3523 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3525 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
3526 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
3528 case (WORD
)X509_UNICODE_NAME
:
3529 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
3531 case (WORD
)X509_UNICODE_NAME_VALUE
:
3532 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
3534 case (WORD
)X509_OCTET_STRING
:
3535 decodeFunc
= CRYPT_AsnDecodeOctets
;
3537 case (WORD
)X509_BITS
:
3538 case (WORD
)X509_KEY_USAGE
:
3539 decodeFunc
= CRYPT_AsnDecodeBits
;
3541 case (WORD
)X509_INTEGER
:
3542 decodeFunc
= CRYPT_AsnDecodeInt
;
3544 case (WORD
)X509_MULTI_BYTE_INTEGER
:
3545 decodeFunc
= CRYPT_AsnDecodeInteger
;
3547 case (WORD
)X509_MULTI_BYTE_UINT
:
3548 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
3550 case (WORD
)X509_ENUMERATED
:
3551 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3553 case (WORD
)X509_CHOICE_OF_TIME
:
3554 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
3556 case (WORD
)X509_SEQUENCE_OF_ANY
:
3557 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
3559 case (WORD
)PKCS_UTC_TIME
:
3560 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3562 case (WORD
)X509_CRL_DIST_POINTS
:
3563 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3565 case (WORD
)X509_ENHANCED_KEY_USAGE
:
3566 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3568 case (WORD
)X509_ISSUING_DIST_POINT
:
3569 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3572 FIXME("%d: unimplemented\n", LOWORD(lpszStructType
));
3575 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
3576 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3577 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
3578 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3579 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
3580 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3581 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
3582 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3583 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
3584 decodeFunc
= CRYPT_AsnDecodeBits
;
3585 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
3586 decodeFunc
= CRYPT_AsnDecodeOctets
;
3587 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
3588 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3589 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
3590 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3591 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
3592 decodeFunc
= CRYPT_AsnDecodeAltName
;
3593 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
3594 decodeFunc
= CRYPT_AsnDecodeAltName
;
3595 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
3596 decodeFunc
= CRYPT_AsnDecodeAltName
;
3597 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
3598 decodeFunc
= CRYPT_AsnDecodeAltName
;
3599 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
3600 decodeFunc
= CRYPT_AsnDecodeAltName
;
3601 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
3602 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3603 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
3604 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3605 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
3606 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3608 TRACE("OID %s not found or unimplemented, looking for DLL\n",
3609 debugstr_a(lpszStructType
));
3613 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
3614 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
3615 (void **)&decodeFunc
, &hFunc
);
3618 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
3619 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3621 SetLastError(ERROR_FILE_NOT_FOUND
);
3623 CryptFreeOIDFunctionAddress(hFunc
, 0);