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
118 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
119 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
120 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
121 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
122 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
123 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
124 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
125 void *pvStructInfo
, DWORD
*pcbStructInfo
);
127 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
128 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
129 DWORD
*pcbStructInfo
)
131 static HCRYPTOIDFUNCSET set
= NULL
;
133 CryptDecodeObjectFunc pCryptDecodeObject
;
134 HCRYPTOIDFUNCADDR hFunc
;
136 TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p)\n", dwCertEncodingType
,
137 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
138 pvStructInfo
, pcbStructInfo
);
140 if (!pvStructInfo
&& !pcbStructInfo
)
142 SetLastError(ERROR_INVALID_PARAMETER
);
146 /* Try registered DLL first.. */
148 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
149 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
150 (void **)&pCryptDecodeObject
, &hFunc
);
151 if (pCryptDecodeObject
)
153 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
154 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
155 CryptFreeOIDFunctionAddress(hFunc
, 0);
159 /* If not, use CryptDecodeObjectEx */
160 ret
= CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
, pbEncoded
,
161 cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
166 /* Gets the number of length bytes from the given (leading) length byte */
167 #define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
169 /* Helper function to get the encoded length of the data starting at pbEncoded,
170 * where pbEncoded[0] is the tag. If the data are too short to contain a
171 * length or if the length is too large for cbEncoded, sets an appropriate
172 * error code and returns FALSE.
174 static BOOL WINAPI
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
181 SetLastError(CRYPT_E_ASN1_CORRUPT
);
184 else if (pbEncoded
[1] <= 0x7f)
186 if (pbEncoded
[1] + 1 > cbEncoded
)
188 SetLastError(CRYPT_E_ASN1_EOD
);
199 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
201 if (lenLen
> sizeof(DWORD
) + 1)
203 SetLastError(CRYPT_E_ASN1_LARGE
);
206 else if (lenLen
+ 2 > cbEncoded
)
208 SetLastError(CRYPT_E_ASN1_CORRUPT
);
221 if (out
+ lenLen
+ 1 > cbEncoded
)
223 SetLastError(CRYPT_E_ASN1_EOD
);
236 /* Helper function to check *pcbStructInfo, set it to the required size, and
237 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
238 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
239 * pointer to the newly allocated memory.
241 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
242 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
247 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
249 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
250 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
252 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
253 if (!*(BYTE
**)pvStructInfo
)
256 *pcbStructInfo
= bytesNeeded
;
258 else if (*pcbStructInfo
< bytesNeeded
)
260 *pcbStructInfo
= bytesNeeded
;
261 SetLastError(ERROR_MORE_DATA
);
268 * The expected tag of the item. If tag is 0, decodeFunc is called
269 * regardless of the tag value seen.
271 * A sequence is decoded into a struct. The offset member is the
272 * offset of this item within that struct.
274 * The decoder function to use. If this is NULL, then the member isn't
275 * decoded, but minSize space is reserved for it.
277 * The minimum amount of space occupied after decoding. You must set this.
279 * If true, and the tag doesn't match the expected tag for this item,
280 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
281 * filled with 0 for this member.
282 * hasPointer, pointerOffset, minSize:
283 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
284 * the offset within the (outer) struct of the data pointer (or to the
285 * first data pointer, if more than one exist).
287 * Used by CRYPT_AsnDecodeSequence, not for your use.
289 struct AsnDecodeSequenceItem
293 CryptDecodeObjectExFunc decodeFunc
;
301 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
302 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
303 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
)
309 ptr
= pbEncoded
+ 1 + GET_LEN_BYTES(pbEncoded
[1]);
310 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
312 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
316 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
319 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
321 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
323 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
325 TRACE("Setting next pointer to %p\n",
327 *(BYTE
**)((BYTE
*)pvStructInfo
+
328 items
[i
].pointerOffset
) = nextData
;
330 if (items
[i
].decodeFunc
)
333 TRACE("decoding item %ld\n", i
);
335 TRACE("sizing item %ld\n", i
);
336 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
337 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
338 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
339 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
340 : NULL
, &items
[i
].size
);
343 if (nextData
&& items
[i
].hasPointer
&&
344 items
[i
].size
> items
[i
].minSize
)
346 nextData
+= items
[i
].size
- items
[i
].minSize
;
347 /* align nextData to DWORD boundaries */
348 if (items
[i
].size
% sizeof(DWORD
))
349 nextData
+= sizeof(DWORD
) - items
[i
].size
%
352 /* Account for alignment padding */
353 if (items
[i
].size
% sizeof(DWORD
))
354 items
[i
].size
+= sizeof(DWORD
) -
355 items
[i
].size
% sizeof(DWORD
);
356 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
358 else if (items
[i
].optional
&&
359 GetLastError() == CRYPT_E_ASN1_BADTAG
)
361 TRACE("skipping optional item %ld\n", i
);
362 items
[i
].size
= items
[i
].minSize
;
363 SetLastError(NOERROR
);
367 TRACE("item %ld failed: %08lx\n", i
,
371 items
[i
].size
= items
[i
].minSize
;
373 else if (items
[i
].optional
)
375 TRACE("skipping optional item %ld\n", i
);
376 items
[i
].size
= items
[i
].minSize
;
380 TRACE("tag %02x doesn't match expected %02x\n",
381 ptr
[0], items
[i
].tag
);
382 SetLastError(CRYPT_E_ASN1_BADTAG
);
387 else if (items
[i
].optional
)
389 TRACE("missing optional item %ld, skipping\n", i
);
390 items
[i
].size
= items
[i
].minSize
;
394 TRACE("not enough bytes for item %ld, failing\n", i
);
395 SetLastError(CRYPT_E_ASN1_CORRUPT
);
399 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
401 TRACE("%ld remaining bytes, failing\n", cbEncoded
-
403 SetLastError(CRYPT_E_ASN1_CORRUPT
);
409 /* This decodes an arbitrary sequence into a contiguous block of memory
410 * (basically, a struct.) Each element being decoded is described by a struct
411 * AsnDecodeSequenceItem, see above.
412 * startingPointer is an optional pointer to the first place where dynamic
413 * data will be stored. If you know the starting offset, you may pass it
414 * here. Otherwise, pass NULL, and one will be inferred from the items.
415 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
416 * If any undecoded data are left over, fails with CRYPT_E_ASN1_CORRUPT.
418 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
419 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
420 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
421 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
425 TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %ld, %p\n", items
, cItem
, pbEncoded
,
426 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
429 if (pbEncoded
[0] == ASN_SEQUENCE
)
433 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
437 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, pbEncoded
,
438 cbEncoded
, dwFlags
, NULL
, NULL
);
441 DWORD bytesNeeded
= 0, structSize
= 0;
443 for (i
= 0; i
< cItem
; i
++)
445 bytesNeeded
+= items
[i
].size
;
446 structSize
+= items
[i
].minSize
;
449 *pcbStructInfo
= bytesNeeded
;
450 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
451 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
455 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
456 pvStructInfo
= *(BYTE
**)pvStructInfo
;
458 nextData
= (BYTE
*)startingPointer
;
460 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
461 memset(pvStructInfo
, 0, structSize
);
462 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
463 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
);
470 SetLastError(CRYPT_E_ASN1_BADTAG
);
473 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
478 * The expected tag of the entire encoded array (usually a variant
479 * of ASN_SETOF or ASN_SEQUENCEOF.)
481 * used to decode each item in the array
483 * is the minimum size of each decoded item
485 * indicates whether each item has a dynamic pointer
487 * indicates the offset within itemSize at which the pointer exists
489 struct AsnArrayDescriptor
492 CryptDecodeObjectExFunc decodeFunc
;
498 struct AsnArrayItemSize
504 /* Decodes an array of like types into a struct GenericArray.
505 * The layout and decoding of the array are described by a struct
506 * AsnArrayDescriptor.
508 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
509 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
510 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
511 void *startingPointer
)
515 TRACE("%p, %p, %ld, %08lx, %p, %p, %ld, %p\n", arrayDesc
, pbEncoded
,
516 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
519 if (pbEncoded
[0] == arrayDesc
->tag
)
523 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
525 DWORD bytesNeeded
, cItems
= 0;
526 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
527 /* There can be arbitrarily many items, but there is often only one.
529 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
531 bytesNeeded
= sizeof(struct GenericArray
);
536 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
537 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
539 DWORD itemLenBytes
, itemDataLen
, size
;
541 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
542 /* Each item decoded may not tolerate extraneous bytes, so
543 * get the length of the next element and pass it directly.
545 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
548 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
549 1 + itemLenBytes
+ itemDataLen
,
550 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
557 if (itemSizes
!= &itemSize
)
558 itemSizes
= CryptMemRealloc(itemSizes
,
559 cItems
* sizeof(struct AsnArrayItemSize
));
564 cItems
* sizeof(struct AsnArrayItemSize
));
566 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
570 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
572 itemSizes
[cItems
- 1].size
= size
;
574 ret
= CRYPT_GetLen(ptr
,
575 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
577 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
587 *pcbStructInfo
= bytesNeeded
;
588 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
589 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
594 struct GenericArray
*array
;
596 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
597 pvStructInfo
= *(BYTE
**)pvStructInfo
;
598 array
= (struct GenericArray
*)pvStructInfo
;
599 array
->cItems
= cItems
;
601 array
->rgItems
= startingPointer
;
603 array
->rgItems
= (BYTE
*)array
+
604 sizeof(struct GenericArray
);
605 nextData
= (BYTE
*)array
->rgItems
+
606 array
->cItems
* arrayDesc
->itemSize
;
607 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
608 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
611 if (arrayDesc
->hasPointer
)
612 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
613 + arrayDesc
->pointerOffset
) = nextData
;
614 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
615 itemSizes
[i
].encodedLen
,
616 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
617 array
->rgItems
+ i
* arrayDesc
->itemSize
,
623 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
624 ret
= CRYPT_GetLen(ptr
,
625 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
627 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
632 if (itemSizes
!= &itemSize
)
633 CryptMemFree(itemSizes
);
638 SetLastError(CRYPT_E_ASN1_BADTAG
);
644 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
645 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
646 * to CRYPT_E_ASN1_CORRUPT.
647 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
650 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
651 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
652 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
657 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
659 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
660 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
662 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
663 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
666 *pcbStructInfo
= bytesNeeded
;
667 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
668 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
670 CRYPT_DER_BLOB
*blob
;
672 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
673 pvStructInfo
= *(BYTE
**)pvStructInfo
;
674 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
675 blob
->cbData
= 1 + lenBytes
+ dataLen
;
678 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
679 blob
->pbData
= (BYTE
*)pbEncoded
;
682 assert(blob
->pbData
);
683 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
688 SetLastError(CRYPT_E_ASN1_CORRUPT
);
696 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
697 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
698 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
699 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
703 TRACE("(%p, %ld, 0x%08lx, %p, %p, %ld)\n", pbEncoded
, cbEncoded
, dwFlags
,
704 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
706 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
709 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
710 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
711 pvStructInfo
, pcbStructInfo
);
712 if (ret
&& pvStructInfo
)
714 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
721 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
723 temp
= blob
->pbData
[i
];
724 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
725 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
729 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
733 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
734 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
735 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
739 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
740 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
744 struct AsnDecodeSequenceItem items
[] = {
745 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
746 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
747 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
748 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
749 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
750 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
751 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
752 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
753 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
754 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
757 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
758 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
759 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
760 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
761 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
765 SetLastError(STATUS_ACCESS_VIOLATION
);
770 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
774 /* Internal function */
775 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
776 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
777 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
782 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
784 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
786 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
787 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
788 pvStructInfo
, pcbStructInfo
);
793 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
794 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
795 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
799 struct AsnDecodeSequenceItem items
[] = {
800 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
801 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
802 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
803 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
806 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
807 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
808 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
812 /* Internal function */
813 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
814 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
815 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
820 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
822 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
824 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
825 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
826 pDecodePara
, pvStructInfo
, pcbStructInfo
);
831 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
832 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
833 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
836 struct AsnDecodeSequenceItem items
[] = {
837 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
838 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
839 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
840 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
841 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
842 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
843 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
844 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
845 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
846 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
848 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
849 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
851 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
852 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
854 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
855 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
856 FALSE
, TRUE
, offsetof(CERT_INFO
,
857 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
858 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
859 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
860 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
861 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
862 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
863 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
864 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
865 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
866 offsetof(CERT_INFO
, rgExtension
), 0 },
869 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
870 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
872 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
873 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
874 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
876 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
880 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
881 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
882 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
886 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
887 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
891 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
894 /* First try to decode it as a signed cert. */
895 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
896 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
897 (BYTE
*)&signedCert
, &size
);
901 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
902 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
903 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
, pvStructInfo
,
905 LocalFree(signedCert
);
907 /* Failing that, try it as an unsigned cert */
911 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
912 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
913 pDecodePara
, pvStructInfo
, pcbStructInfo
);
918 SetLastError(STATUS_ACCESS_VIOLATION
);
923 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
927 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
928 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
929 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
932 struct AsnDecodeSequenceItem items
[] = {
933 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
934 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
935 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
936 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
937 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
938 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
939 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
940 offsetof(CRL_ENTRY
, rgExtension
), 0 },
942 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
944 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
947 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
948 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
949 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
953 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
954 * been set prior to calling.
956 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
957 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
958 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
961 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
962 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
963 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
964 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
966 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
967 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
969 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
970 pDecodePara
, pvStructInfo
, pcbStructInfo
,
971 entries
? entries
->rgItems
: NULL
);
972 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
976 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
977 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
978 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
980 struct AsnDecodeSequenceItem items
[] = {
981 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
982 CRYPT_AsnDecodeInt
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
983 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
984 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
985 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
986 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
987 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
989 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
990 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
991 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
992 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
993 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
994 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
995 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
996 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
997 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
998 offsetof(CRL_INFO
, rgExtension
), 0 },
1002 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1003 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1005 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1006 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1007 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1009 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1013 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1014 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1015 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1019 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1020 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1024 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1027 /* First try to decode it as a signed crl. */
1028 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
1029 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1030 (BYTE
*)&signedCrl
, &size
);
1034 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1035 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1036 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1037 pvStructInfo
, pcbStructInfo
);
1038 LocalFree(signedCrl
);
1040 /* Failing that, try it as an unsigned crl */
1044 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1045 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1046 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1051 SetLastError(STATUS_ACCESS_VIOLATION
);
1056 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1060 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
1061 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1062 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1066 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1067 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1069 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1073 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1075 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1076 DWORD bytesNeeded
= sizeof(LPSTR
);
1080 /* The largest possible string for the first two components
1081 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1086 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1087 pbEncoded
[1 + lenBytes
] / 40,
1088 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1090 bytesNeeded
+= strlen(firstTwo
) + 1;
1091 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1092 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1094 /* large enough for ".4000000" */
1098 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1105 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1108 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1115 snprintf(str
, sizeof(str
), ".%d", val
);
1116 bytesNeeded
+= strlen(str
);
1121 *pcbStructInfo
= bytesNeeded
;
1122 else if (*pcbStructInfo
< bytesNeeded
)
1124 *pcbStructInfo
= bytesNeeded
;
1125 SetLastError(ERROR_MORE_DATA
);
1133 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1136 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1137 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1139 pszObjId
+= strlen(pszObjId
);
1140 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1141 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1145 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1154 sprintf(pszObjId
, ".%d", val
);
1155 pszObjId
+= strlen(pszObjId
);
1159 *(LPSTR
*)pvStructInfo
= NULL
;
1160 *pcbStructInfo
= bytesNeeded
;
1167 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1170 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1171 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1172 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1174 struct AsnDecodeSequenceItem items
[] = {
1175 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1176 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1177 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1178 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1179 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1180 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1181 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1182 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1185 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1187 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1191 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1192 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1193 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1194 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1196 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1197 debugstr_a(ext
->pszObjId
));
1198 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1202 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1203 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1204 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1207 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1208 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1209 offsetof(CERT_EXTENSION
, pszObjId
) };
1210 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1212 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1213 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1215 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1216 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1220 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1221 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1222 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1228 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1229 lpszStructType
, pbEncoded
, cbEncoded
,
1230 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1231 if (ret
&& pvStructInfo
)
1233 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1234 pcbStructInfo
, *pcbStructInfo
);
1237 CERT_EXTENSIONS
*exts
;
1239 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1240 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1241 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1242 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1243 sizeof(CERT_EXTENSIONS
));
1244 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1245 lpszStructType
, pbEncoded
, cbEncoded
,
1246 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1253 SetLastError(STATUS_ACCESS_VIOLATION
);
1260 /* Warning: this assumes the address of value->Value.pbData is already set, in
1261 * order to avoid overwriting memory. (In some cases, it may change it, if it
1262 * doesn't copy anything to memory.) Be sure to set it correctly!
1264 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1265 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1266 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1270 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1272 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1274 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1275 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1277 switch (pbEncoded
[0])
1279 case ASN_OCTETSTRING
:
1280 valueType
= CERT_RDN_OCTET_STRING
;
1281 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1282 bytesNeeded
+= dataLen
;
1284 case ASN_NUMERICSTRING
:
1285 valueType
= CERT_RDN_NUMERIC_STRING
;
1286 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1287 bytesNeeded
+= dataLen
;
1289 case ASN_PRINTABLESTRING
:
1290 valueType
= CERT_RDN_PRINTABLE_STRING
;
1291 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1292 bytesNeeded
+= dataLen
;
1295 valueType
= CERT_RDN_IA5_STRING
;
1296 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1297 bytesNeeded
+= dataLen
;
1300 valueType
= CERT_RDN_T61_STRING
;
1301 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1302 bytesNeeded
+= dataLen
;
1304 case ASN_VIDEOTEXSTRING
:
1305 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1306 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1307 bytesNeeded
+= dataLen
;
1309 case ASN_GRAPHICSTRING
:
1310 valueType
= CERT_RDN_GRAPHIC_STRING
;
1311 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1312 bytesNeeded
+= dataLen
;
1314 case ASN_VISIBLESTRING
:
1315 valueType
= CERT_RDN_VISIBLE_STRING
;
1316 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1317 bytesNeeded
+= dataLen
;
1319 case ASN_GENERALSTRING
:
1320 valueType
= CERT_RDN_GENERAL_STRING
;
1321 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1322 bytesNeeded
+= dataLen
;
1324 case ASN_UNIVERSALSTRING
:
1325 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1326 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
);
1345 *pcbStructInfo
= bytesNeeded
;
1346 else if (*pcbStructInfo
< bytesNeeded
)
1348 *pcbStructInfo
= bytesNeeded
;
1349 SetLastError(ERROR_MORE_DATA
);
1354 *pcbStructInfo
= bytesNeeded
;
1355 value
->dwValueType
= valueType
;
1360 assert(value
->Value
.pbData
);
1361 switch (pbEncoded
[0])
1363 case ASN_OCTETSTRING
:
1364 case ASN_NUMERICSTRING
:
1365 case ASN_PRINTABLESTRING
:
1368 case ASN_VIDEOTEXSTRING
:
1369 case ASN_GRAPHICSTRING
:
1370 case ASN_VISIBLESTRING
:
1371 case ASN_GENERALSTRING
:
1372 value
->Value
.cbData
= dataLen
;
1375 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1376 memcpy(value
->Value
.pbData
,
1377 pbEncoded
+ 1 + lenBytes
, dataLen
);
1379 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1385 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1387 value
->Value
.cbData
= dataLen
;
1388 for (i
= 0; i
< dataLen
/ 2; i
++)
1389 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1390 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1393 case ASN_UTF8STRING
:
1395 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1397 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1398 (LPSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1399 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1406 value
->Value
.cbData
= 0;
1407 value
->Value
.pbData
= NULL
;
1415 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1416 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1417 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1423 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1424 lpszStructType
, pbEncoded
, cbEncoded
,
1425 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1426 if (ret
&& pvStructInfo
)
1428 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1429 pcbStructInfo
, *pcbStructInfo
);
1432 CERT_NAME_VALUE
*value
;
1434 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1435 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1436 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1437 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1438 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1439 lpszStructType
, pbEncoded
, cbEncoded
,
1440 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1447 SetLastError(STATUS_ACCESS_VIOLATION
);
1454 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1455 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1456 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1457 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1461 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1463 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1465 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1466 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1468 switch (pbEncoded
[0])
1470 case ASN_NUMERICSTRING
:
1471 valueType
= CERT_RDN_NUMERIC_STRING
;
1472 bytesNeeded
+= dataLen
* 2;
1474 case ASN_PRINTABLESTRING
:
1475 valueType
= CERT_RDN_PRINTABLE_STRING
;
1476 bytesNeeded
+= dataLen
* 2;
1479 valueType
= CERT_RDN_IA5_STRING
;
1480 bytesNeeded
+= dataLen
* 2;
1483 valueType
= CERT_RDN_T61_STRING
;
1484 bytesNeeded
+= dataLen
* 2;
1486 case ASN_VIDEOTEXSTRING
:
1487 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1488 bytesNeeded
+= dataLen
* 2;
1490 case ASN_GRAPHICSTRING
:
1491 valueType
= CERT_RDN_GRAPHIC_STRING
;
1492 bytesNeeded
+= dataLen
* 2;
1494 case ASN_VISIBLESTRING
:
1495 valueType
= CERT_RDN_VISIBLE_STRING
;
1496 bytesNeeded
+= dataLen
* 2;
1498 case ASN_GENERALSTRING
:
1499 valueType
= CERT_RDN_GENERAL_STRING
;
1500 bytesNeeded
+= dataLen
* 2;
1502 case ASN_UNIVERSALSTRING
:
1503 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1504 bytesNeeded
+= dataLen
/ 2;
1507 valueType
= CERT_RDN_BMP_STRING
;
1508 bytesNeeded
+= dataLen
;
1510 case ASN_UTF8STRING
:
1511 valueType
= CERT_RDN_UTF8_STRING
;
1512 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1513 (LPSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1516 SetLastError(CRYPT_E_ASN1_BADTAG
);
1522 *pcbStructInfo
= bytesNeeded
;
1523 else if (*pcbStructInfo
< bytesNeeded
)
1525 *pcbStructInfo
= bytesNeeded
;
1526 SetLastError(ERROR_MORE_DATA
);
1531 *pcbStructInfo
= bytesNeeded
;
1532 value
->dwValueType
= valueType
;
1536 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1538 assert(value
->Value
.pbData
);
1539 switch (pbEncoded
[0])
1541 case ASN_NUMERICSTRING
:
1542 case ASN_PRINTABLESTRING
:
1545 case ASN_VIDEOTEXSTRING
:
1546 case ASN_GRAPHICSTRING
:
1547 case ASN_VISIBLESTRING
:
1548 case ASN_GENERALSTRING
:
1549 value
->Value
.cbData
= dataLen
* 2;
1550 for (i
= 0; i
< dataLen
; i
++)
1551 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1553 case ASN_UNIVERSALSTRING
:
1554 value
->Value
.cbData
= dataLen
/ 2;
1555 for (i
= 0; i
< dataLen
/ 4; i
++)
1556 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1557 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1560 value
->Value
.cbData
= dataLen
;
1561 for (i
= 0; i
< dataLen
/ 2; i
++)
1562 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1563 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1565 case ASN_UTF8STRING
:
1566 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1567 (LPSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1568 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1574 value
->Value
.cbData
= 0;
1575 value
->Value
.pbData
= NULL
;
1583 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1584 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1585 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1591 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1592 lpszStructType
, pbEncoded
, cbEncoded
,
1593 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1594 if (ret
&& pvStructInfo
)
1596 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1597 pcbStructInfo
, *pcbStructInfo
);
1600 CERT_NAME_VALUE
*value
;
1602 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1603 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1604 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1605 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1606 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1607 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1608 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1615 SetLastError(STATUS_ACCESS_VIOLATION
);
1622 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1623 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1624 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1627 struct AsnDecodeSequenceItem items
[] = {
1628 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1629 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1630 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1631 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1632 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1633 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1635 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1637 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1638 pvStructInfo
, *pcbStructInfo
);
1641 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1642 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1643 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1644 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1647 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1648 debugstr_a(attr
->pszObjId
));
1649 TRACE("attr->dwValueType is %ld\n", attr
->dwValueType
);
1651 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1655 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1656 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1657 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1660 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1661 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1662 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1663 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1665 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1666 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1670 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1671 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1672 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1678 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1679 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1680 offsetof(CERT_RDN
, rgRDNAttr
) };
1682 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1683 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1687 SetLastError(STATUS_ACCESS_VIOLATION
);
1694 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType
,
1695 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1696 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1699 struct AsnDecodeSequenceItem items
[] = {
1700 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1701 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1702 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1703 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1704 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1705 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1707 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1709 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1710 pvStructInfo
, *pcbStructInfo
);
1713 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1714 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1715 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1716 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1719 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1720 debugstr_a(attr
->pszObjId
));
1721 TRACE("attr->dwValueType is %ld\n", attr
->dwValueType
);
1723 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1727 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType
,
1728 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1729 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1732 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1733 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1734 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1735 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1737 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1738 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1742 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1743 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1744 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1750 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1751 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1752 offsetof(CERT_RDN
, rgRDNAttr
) };
1754 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1755 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1759 SetLastError(STATUS_ACCESS_VIOLATION
);
1766 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1767 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1768 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1771 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1773 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1774 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1776 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1777 bytesNeeded
+= cbEncoded
;
1779 *pcbStructInfo
= bytesNeeded
;
1780 else if (*pcbStructInfo
< bytesNeeded
)
1782 SetLastError(ERROR_MORE_DATA
);
1783 *pcbStructInfo
= bytesNeeded
;
1788 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1790 *pcbStructInfo
= bytesNeeded
;
1791 blob
->cbData
= cbEncoded
;
1792 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1793 blob
->pbData
= (LPBYTE
)pbEncoded
;
1796 assert(blob
->pbData
);
1797 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1803 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1804 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1805 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1807 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1808 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1810 struct AsnDecodeSequenceItem items
[] = {
1811 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1812 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1813 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1814 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1815 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1816 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1819 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1820 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1822 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1823 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1824 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1825 if (ret
&& pvStructInfo
)
1827 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1828 debugstr_a(algo
->pszObjId
));
1833 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1834 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1835 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1838 struct AsnDecodeSequenceItem items
[] = {
1839 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1840 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1841 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
1842 Algorithm
.pszObjId
) },
1843 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
1844 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1845 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
1847 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1849 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1850 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1851 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
1852 info
->Algorithm
.Parameters
.pbData
: NULL
);
1856 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
1857 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1858 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1866 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1867 lpszStructType
, pbEncoded
, cbEncoded
,
1868 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1871 *pcbStructInfo
= bytesNeeded
;
1872 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1873 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1875 PCERT_PUBLIC_KEY_INFO info
;
1877 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1878 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1879 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1880 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
1881 sizeof(CERT_PUBLIC_KEY_INFO
);
1882 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1883 lpszStructType
, pbEncoded
, cbEncoded
,
1884 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1891 SetLastError(STATUS_ACCESS_VIOLATION
);
1898 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
1899 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1900 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1906 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1909 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
1911 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1914 if (pbEncoded
[1] > 1)
1916 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1921 *pcbStructInfo
= sizeof(BOOL
);
1924 else if (*pcbStructInfo
< sizeof(BOOL
))
1926 *pcbStructInfo
= sizeof(BOOL
);
1927 SetLastError(ERROR_MORE_DATA
);
1932 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
1935 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1939 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
1940 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1941 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1943 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
1944 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
1947 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1948 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1952 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1955 if ((pbEncoded
[0] & ASN_FLAGS_MASK
) != ASN_CONTEXT
)
1957 SetLastError(CRYPT_E_ASN1_BADTAG
);
1960 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1961 if (1 + lenBytes
> cbEncoded
)
1963 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1966 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1968 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
1970 case 1: /* rfc822Name */
1971 case 2: /* dNSName */
1972 case 6: /* uniformResourceIdentifier */
1973 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
1975 case 7: /* iPAddress */
1976 bytesNeeded
+= dataLen
;
1978 case 8: /* registeredID */
1979 /* FIXME: decode as OID */
1980 case 0: /* otherName */
1981 case 4: /* directoryName */
1983 SetLastError(CRYPT_E_ASN1_BADTAG
);
1986 case 3: /* x400Address, unimplemented */
1987 case 5: /* ediPartyName, unimplemented */
1988 SetLastError(CRYPT_E_ASN1_BADTAG
);
1992 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1998 *pcbStructInfo
= bytesNeeded
;
1999 else if (*pcbStructInfo
< bytesNeeded
)
2001 *pcbStructInfo
= bytesNeeded
;
2002 SetLastError(ERROR_MORE_DATA
);
2007 *pcbStructInfo
= bytesNeeded
;
2008 /* MS used values one greater than the asn1 ones.. sigh */
2009 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2010 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2012 case 1: /* rfc822Name */
2013 case 2: /* dNSName */
2014 case 6: /* uniformResourceIdentifier */
2018 for (i
= 0; i
< dataLen
; i
++)
2019 entry
->u
.pwszURL
[i
] =
2020 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2021 entry
->u
.pwszURL
[i
] = 0;
2022 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2023 debugstr_w(entry
->u
.pwszURL
));
2026 case 7: /* iPAddress */
2027 /* The next data pointer is in the pwszURL spot, that is,
2028 * the first 4 bytes. Need to move it to the next spot.
2030 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2031 entry
->u
.IPAddress
.cbData
= dataLen
;
2032 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2042 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2043 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2044 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2047 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2048 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2049 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2050 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2052 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2053 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2056 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2057 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2058 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
2062 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2063 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2064 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2068 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2069 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2073 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2074 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2075 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2077 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2078 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2082 SetLastError(STATUS_ACCESS_VIOLATION
);
2089 struct PATH_LEN_CONSTRAINT
2091 BOOL fPathLenConstraint
;
2092 DWORD dwPathLenConstraint
;
2095 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2096 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2097 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2101 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2102 pvStructInfo
, *pcbStructInfo
);
2106 if (pbEncoded
[0] == ASN_INTEGER
)
2108 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2111 *pcbStructInfo
= bytesNeeded
;
2112 else if (*pcbStructInfo
< bytesNeeded
)
2114 SetLastError(ERROR_MORE_DATA
);
2115 *pcbStructInfo
= bytesNeeded
;
2120 struct PATH_LEN_CONSTRAINT
*constraint
=
2121 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2122 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2124 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
2125 pbEncoded
, cbEncoded
, 0, NULL
,
2126 &constraint
->dwPathLenConstraint
, &size
);
2128 constraint
->fPathLenConstraint
= TRUE
;
2129 TRACE("got an int, dwPathLenConstraint is %ld\n",
2130 constraint
->dwPathLenConstraint
);
2135 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2139 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
2143 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2144 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2145 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2148 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2149 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2150 offsetof(CERT_NAME_BLOB
, pbData
) };
2151 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2153 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2154 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2156 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2157 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2158 entries
? entries
->rgItems
: NULL
);
2159 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
2163 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2164 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2165 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2171 struct AsnDecodeSequenceItem items
[] = {
2172 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2173 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2174 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2175 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2176 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2177 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2178 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2179 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2180 sizeof(struct GenericArray
), TRUE
, TRUE
,
2181 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2184 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2185 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2186 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2190 SetLastError(STATUS_ACCESS_VIOLATION
);
2197 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2198 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2199 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2205 struct AsnDecodeSequenceItem items
[] = {
2206 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2207 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2208 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2209 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2210 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2213 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2214 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2215 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2219 SetLastError(STATUS_ACCESS_VIOLATION
);
2226 #define RSA1_MAGIC 0x31415352
2228 struct DECODED_RSA_PUB_KEY
2231 CRYPT_INTEGER_BLOB modulus
;
2234 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2235 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2236 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2242 struct AsnDecodeSequenceItem items
[] = {
2243 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2244 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2245 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2247 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2248 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2250 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2253 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2254 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2255 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
2258 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2259 decodedKey
->modulus
.cbData
;
2263 *pcbStructInfo
= bytesNeeded
;
2266 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2267 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2270 RSAPUBKEY
*rsaPubKey
;
2272 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2273 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2274 hdr
= (BLOBHEADER
*)pvStructInfo
;
2275 hdr
->bType
= PUBLICKEYBLOB
;
2276 hdr
->bVersion
= CUR_BLOB_VERSION
;
2278 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2279 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2280 sizeof(BLOBHEADER
));
2281 rsaPubKey
->magic
= RSA1_MAGIC
;
2282 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2283 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2284 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2285 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2286 decodedKey
->modulus
.cbData
);
2288 LocalFree(decodedKey
);
2293 SetLastError(STATUS_ACCESS_VIOLATION
);
2300 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2301 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2302 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2305 DWORD bytesNeeded
, dataLen
;
2307 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2308 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2310 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2312 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2313 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2315 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2317 *pcbStructInfo
= bytesNeeded
;
2318 else if (*pcbStructInfo
< bytesNeeded
)
2320 SetLastError(ERROR_MORE_DATA
);
2321 *pcbStructInfo
= bytesNeeded
;
2326 CRYPT_DATA_BLOB
*blob
;
2327 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2329 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2330 blob
->cbData
= dataLen
;
2331 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2332 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2335 assert(blob
->pbData
);
2337 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2345 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2346 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2347 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2351 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2352 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2360 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2363 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2365 SetLastError(CRYPT_E_ASN1_BADTAG
);
2368 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2369 lpszStructType
, pbEncoded
, cbEncoded
,
2370 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2373 *pcbStructInfo
= bytesNeeded
;
2374 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2375 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2377 CRYPT_DATA_BLOB
*blob
;
2379 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2380 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2381 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2382 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2383 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2384 lpszStructType
, pbEncoded
, cbEncoded
,
2385 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2392 SetLastError(STATUS_ACCESS_VIOLATION
);
2399 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2400 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2401 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2405 TRACE("(%p, %ld, 0x%08lx, %p, %p, %ld)\n", pbEncoded
, cbEncoded
, dwFlags
,
2406 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2408 if (pbEncoded
[0] == ASN_BITSTRING
)
2410 DWORD bytesNeeded
, dataLen
;
2412 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2414 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2415 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2417 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2419 *pcbStructInfo
= bytesNeeded
;
2420 else if (*pcbStructInfo
< bytesNeeded
)
2422 *pcbStructInfo
= bytesNeeded
;
2423 SetLastError(ERROR_MORE_DATA
);
2428 CRYPT_BIT_BLOB
*blob
;
2430 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2431 blob
->cbData
= dataLen
- 1;
2432 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2433 GET_LEN_BYTES(pbEncoded
[1]));
2434 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2436 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2437 GET_LEN_BYTES(pbEncoded
[1]);
2441 assert(blob
->pbData
);
2444 BYTE mask
= 0xff << blob
->cUnusedBits
;
2446 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2447 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2448 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2456 SetLastError(CRYPT_E_ASN1_BADTAG
);
2459 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
2463 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2464 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2465 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2469 TRACE("(%p, %ld, 0x%08lx, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2470 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2476 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2477 lpszStructType
, pbEncoded
, cbEncoded
,
2478 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2481 *pcbStructInfo
= bytesNeeded
;
2482 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2483 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2485 CRYPT_BIT_BLOB
*blob
;
2487 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2488 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2489 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2490 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2491 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2492 lpszStructType
, pbEncoded
, cbEncoded
,
2493 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2500 SetLastError(STATUS_ACCESS_VIOLATION
);
2504 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
2508 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2509 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2510 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2516 *pcbStructInfo
= sizeof(int);
2521 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2522 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2523 DWORD size
= sizeof(buf
);
2525 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2526 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2527 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
, &size
);
2530 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2531 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2535 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2536 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2537 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2539 /* initialize to a negative value to sign-extend */
2544 for (i
= 0; i
< blob
->cbData
; i
++)
2547 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2549 memcpy(pvStructInfo
, &val
, sizeof(int));
2552 else if (GetLastError() == ERROR_MORE_DATA
)
2553 SetLastError(CRYPT_E_ASN1_LARGE
);
2557 SetLastError(STATUS_ACCESS_VIOLATION
);
2564 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2565 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2566 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2570 if (pbEncoded
[0] == ASN_INTEGER
)
2572 DWORD bytesNeeded
, dataLen
;
2574 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2576 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2578 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2580 *pcbStructInfo
= bytesNeeded
;
2581 else if (*pcbStructInfo
< bytesNeeded
)
2583 *pcbStructInfo
= bytesNeeded
;
2584 SetLastError(ERROR_MORE_DATA
);
2589 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2591 blob
->cbData
= dataLen
;
2592 assert(blob
->pbData
);
2597 for (i
= 0; i
< blob
->cbData
; i
++)
2599 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2608 SetLastError(CRYPT_E_ASN1_BADTAG
);
2614 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
2615 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2616 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2624 if ((ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2625 lpszStructType
, pbEncoded
, cbEncoded
,
2626 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2629 *pcbStructInfo
= bytesNeeded
;
2630 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2631 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2633 CRYPT_INTEGER_BLOB
*blob
;
2635 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2636 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2637 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2638 blob
->pbData
= (BYTE
*)pvStructInfo
+
2639 sizeof(CRYPT_INTEGER_BLOB
);
2640 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2641 lpszStructType
, pbEncoded
, cbEncoded
,
2642 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2649 SetLastError(STATUS_ACCESS_VIOLATION
);
2656 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
2657 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2658 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2659 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2663 if (pbEncoded
[0] == ASN_INTEGER
)
2665 DWORD bytesNeeded
, dataLen
;
2667 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2669 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2671 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2673 *pcbStructInfo
= bytesNeeded
;
2674 else if (*pcbStructInfo
< bytesNeeded
)
2676 *pcbStructInfo
= bytesNeeded
;
2677 SetLastError(ERROR_MORE_DATA
);
2682 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2684 blob
->cbData
= dataLen
;
2685 assert(blob
->pbData
);
2686 /* remove leading zero byte if it exists */
2687 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
2696 for (i
= 0; i
< blob
->cbData
; i
++)
2698 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2707 SetLastError(CRYPT_E_ASN1_BADTAG
);
2713 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
2714 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2715 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2723 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2724 lpszStructType
, pbEncoded
, cbEncoded
,
2725 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2728 *pcbStructInfo
= bytesNeeded
;
2729 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2730 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2732 CRYPT_INTEGER_BLOB
*blob
;
2734 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2735 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2736 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2737 blob
->pbData
= (BYTE
*)pvStructInfo
+
2738 sizeof(CRYPT_INTEGER_BLOB
);
2739 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2740 lpszStructType
, pbEncoded
, cbEncoded
,
2741 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2748 SetLastError(STATUS_ACCESS_VIOLATION
);
2755 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
2756 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2757 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2763 *pcbStructInfo
= sizeof(int);
2768 if (pbEncoded
[0] == ASN_ENUMERATED
)
2770 unsigned int val
= 0, i
;
2774 SetLastError(CRYPT_E_ASN1_EOD
);
2777 else if (pbEncoded
[1] == 0)
2779 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2784 /* A little strange looking, but we have to accept a sign byte:
2785 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
2786 * assuming a small length is okay here, it has to be in short
2789 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
2791 SetLastError(CRYPT_E_ASN1_LARGE
);
2794 for (i
= 0; i
< pbEncoded
[1]; i
++)
2797 val
|= pbEncoded
[2 + i
];
2799 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2800 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
2802 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2803 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2804 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
2810 SetLastError(CRYPT_E_ASN1_BADTAG
);
2816 SetLastError(STATUS_ACCESS_VIOLATION
);
2823 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
2826 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
2831 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
2833 if (!isdigit(*(pbEncoded))) \
2835 SetLastError(CRYPT_E_ASN1_CORRUPT); \
2841 (word) += *(pbEncoded)++ - '0'; \
2846 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
2847 SYSTEMTIME
*sysTime
)
2854 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
2856 WORD hours
, minutes
= 0;
2857 BYTE sign
= *pbEncoded
++;
2860 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
2861 if (ret
&& hours
>= 24)
2863 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2868 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
2869 if (ret
&& minutes
>= 60)
2871 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2879 sysTime
->wHour
+= hours
;
2880 sysTime
->wMinute
+= minutes
;
2884 if (hours
> sysTime
->wHour
)
2887 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
2890 sysTime
->wHour
-= hours
;
2891 if (minutes
> sysTime
->wMinute
)
2894 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
2897 sysTime
->wMinute
-= minutes
;
2904 SetLastError(STATUS_ACCESS_VIOLATION
);
2911 #define MIN_ENCODED_TIME_LENGTH 10
2913 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
2914 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2915 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2921 *pcbStructInfo
= sizeof(FILETIME
);
2927 if (pbEncoded
[0] == ASN_UTCTIME
)
2931 SetLastError(CRYPT_E_ASN1_EOD
);
2934 else if (pbEncoded
[1] > 0x7f)
2936 /* long-form date strings really can't be valid */
2937 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2942 SYSTEMTIME sysTime
= { 0 };
2943 BYTE len
= pbEncoded
[1];
2945 if (len
< MIN_ENCODED_TIME_LENGTH
)
2947 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2953 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
2954 if (sysTime
.wYear
>= 50)
2955 sysTime
.wYear
+= 1900;
2957 sysTime
.wYear
+= 2000;
2958 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
2959 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
2960 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
2961 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
2964 if (len
>= 2 && isdigit(*pbEncoded
) &&
2965 isdigit(*(pbEncoded
+ 1)))
2966 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
2968 else if (isdigit(*pbEncoded
))
2969 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
2972 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
2975 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
2976 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2979 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2980 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2981 ret
= SystemTimeToFileTime(&sysTime
,
2982 (FILETIME
*)pvStructInfo
);
2989 SetLastError(CRYPT_E_ASN1_BADTAG
);
2995 SetLastError(STATUS_ACCESS_VIOLATION
);
3002 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
3003 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3004 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3010 *pcbStructInfo
= sizeof(FILETIME
);
3016 if (pbEncoded
[0] == ASN_GENERALTIME
)
3020 SetLastError(CRYPT_E_ASN1_EOD
);
3023 else if (pbEncoded
[1] > 0x7f)
3025 /* long-form date strings really can't be valid */
3026 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3031 BYTE len
= pbEncoded
[1];
3033 if (len
< MIN_ENCODED_TIME_LENGTH
)
3035 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3040 SYSTEMTIME sysTime
= { 0 };
3043 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3044 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3045 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3046 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3049 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3052 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3054 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3061 /* workaround macro weirdness */
3062 digits
= min(len
, 3);
3063 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3064 sysTime
.wMilliseconds
);
3067 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3070 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3071 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3074 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3075 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3076 ret
= SystemTimeToFileTime(&sysTime
,
3077 (FILETIME
*)pvStructInfo
);
3084 SetLastError(CRYPT_E_ASN1_BADTAG
);
3090 SetLastError(STATUS_ACCESS_VIOLATION
);
3097 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3098 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3099 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3105 if (pbEncoded
[0] == ASN_UTCTIME
)
3106 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
3107 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3109 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3110 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
3111 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
3112 pvStructInfo
, pcbStructInfo
);
3115 SetLastError(CRYPT_E_ASN1_BADTAG
);
3121 SetLastError(STATUS_ACCESS_VIOLATION
);
3128 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3129 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3130 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3136 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3138 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3140 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3145 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3146 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3148 ptr
= pbEncoded
+ 1 + lenBytes
;
3149 remainingLen
= dataLen
;
3150 while (ret
&& remainingLen
)
3154 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3157 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3159 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3160 ptr
+= 1 + nextLenBytes
+ nextLen
;
3161 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3162 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3163 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3169 CRYPT_SEQUENCE_OF_ANY
*seq
;
3173 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3174 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3176 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3177 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3178 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3179 seq
->cValue
= cValue
;
3180 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3182 nextPtr
= (BYTE
*)seq
->rgValue
+
3183 cValue
* sizeof(CRYPT_DER_BLOB
);
3184 ptr
= pbEncoded
+ 1 + lenBytes
;
3185 remainingLen
= dataLen
;
3187 while (ret
&& remainingLen
)
3191 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3194 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3196 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3198 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3199 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3202 seq
->rgValue
[i
].pbData
= nextPtr
;
3203 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3205 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3207 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3208 ptr
+= 1 + nextLenBytes
+ nextLen
;
3218 SetLastError(CRYPT_E_ASN1_BADTAG
);
3224 SetLastError(STATUS_ACCESS_VIOLATION
);
3231 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3232 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3233 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3237 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3239 DWORD bytesNeeded
, dataLen
;
3241 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3243 struct AsnArrayDescriptor arrayDesc
= {
3244 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3245 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3246 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3247 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3253 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3254 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3255 0, NULL
, NULL
, &nameLen
, NULL
);
3256 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3259 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3261 *pcbStructInfo
= bytesNeeded
;
3262 else if (*pcbStructInfo
< bytesNeeded
)
3264 *pcbStructInfo
= bytesNeeded
;
3265 SetLastError(ERROR_MORE_DATA
);
3270 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3274 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3275 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3276 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3277 0, NULL
, &name
->u
.FullName
, pcbStructInfo
,
3278 name
->u
.FullName
.rgAltEntry
);
3281 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3287 SetLastError(CRYPT_E_ASN1_BADTAG
);
3293 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
3294 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3295 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3297 struct AsnDecodeSequenceItem items
[] = {
3298 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3299 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3300 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3301 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3302 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3303 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3304 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3305 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3306 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3307 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3311 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3312 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3313 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3317 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3318 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3319 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3323 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3324 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3328 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3329 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3330 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3332 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3333 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3337 SetLastError(STATUS_ACCESS_VIOLATION
);
3344 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3345 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3346 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3350 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3351 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3355 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3356 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3358 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3359 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3363 SetLastError(STATUS_ACCESS_VIOLATION
);
3370 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3371 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3372 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3376 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3377 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3381 struct AsnDecodeSequenceItem items
[] = {
3382 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3383 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3384 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3385 offsetof(CRL_ISSUING_DIST_POINT
,
3386 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3387 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3388 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3390 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
3391 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3393 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
3394 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
3395 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
3396 OnlySomeReasonFlags
.pbData
), 0 },
3397 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
3398 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
3401 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3402 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3403 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3407 SetLastError(STATUS_ACCESS_VIOLATION
);
3414 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
3415 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3416 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3418 static HCRYPTOIDFUNCSET set
= NULL
;
3420 CryptDecodeObjectExFunc decodeFunc
= NULL
;
3421 HCRYPTOIDFUNCADDR hFunc
= NULL
;
3423 TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n",
3424 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
3425 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3427 if (!pvStructInfo
&& !pcbStructInfo
)
3429 SetLastError(ERROR_INVALID_PARAMETER
);
3432 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
3433 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
3435 SetLastError(ERROR_FILE_NOT_FOUND
);
3440 SetLastError(CRYPT_E_ASN1_EOD
);
3443 if (cbEncoded
> MAX_ENCODED_LEN
)
3445 SetLastError(CRYPT_E_ASN1_LARGE
);
3449 SetLastError(NOERROR
);
3450 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
3451 *(BYTE
**)pvStructInfo
= NULL
;
3452 if (!HIWORD(lpszStructType
))
3454 switch (LOWORD(lpszStructType
))
3456 case (WORD
)X509_CERT
:
3457 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
3459 case (WORD
)X509_CERT_TO_BE_SIGNED
:
3460 decodeFunc
= CRYPT_AsnDecodeCert
;
3462 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
3463 decodeFunc
= CRYPT_AsnDecodeCRL
;
3465 case (WORD
)X509_EXTENSIONS
:
3466 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3468 case (WORD
)X509_NAME_VALUE
:
3469 decodeFunc
= CRYPT_AsnDecodeNameValue
;
3471 case (WORD
)X509_NAME
:
3472 decodeFunc
= CRYPT_AsnDecodeName
;
3474 case (WORD
)X509_PUBLIC_KEY_INFO
:
3475 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
3477 case (WORD
)X509_ALTERNATE_NAME
:
3478 decodeFunc
= CRYPT_AsnDecodeAltName
;
3480 case (WORD
)X509_BASIC_CONSTRAINTS
:
3481 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3483 case (WORD
)X509_BASIC_CONSTRAINTS2
:
3484 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3486 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
3487 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
3489 case (WORD
)X509_UNICODE_NAME
:
3490 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
3492 case (WORD
)X509_UNICODE_NAME_VALUE
:
3493 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
3495 case (WORD
)X509_OCTET_STRING
:
3496 decodeFunc
= CRYPT_AsnDecodeOctets
;
3498 case (WORD
)X509_BITS
:
3499 case (WORD
)X509_KEY_USAGE
:
3500 decodeFunc
= CRYPT_AsnDecodeBits
;
3502 case (WORD
)X509_INTEGER
:
3503 decodeFunc
= CRYPT_AsnDecodeInt
;
3505 case (WORD
)X509_MULTI_BYTE_INTEGER
:
3506 decodeFunc
= CRYPT_AsnDecodeInteger
;
3508 case (WORD
)X509_MULTI_BYTE_UINT
:
3509 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
3511 case (WORD
)X509_ENUMERATED
:
3512 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3514 case (WORD
)X509_CHOICE_OF_TIME
:
3515 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
3517 case (WORD
)X509_SEQUENCE_OF_ANY
:
3518 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
3520 case (WORD
)PKCS_UTC_TIME
:
3521 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3523 case (WORD
)X509_CRL_DIST_POINTS
:
3524 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3526 case (WORD
)X509_ENHANCED_KEY_USAGE
:
3527 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3529 case (WORD
)X509_ISSUING_DIST_POINT
:
3530 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3533 FIXME("%d: unimplemented\n", LOWORD(lpszStructType
));
3536 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
3537 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3538 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
3539 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3540 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
3541 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3542 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
3543 decodeFunc
= CRYPT_AsnDecodeBits
;
3544 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
3545 decodeFunc
= CRYPT_AsnDecodeOctets
;
3546 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
3547 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3548 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
3549 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3550 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
3551 decodeFunc
= CRYPT_AsnDecodeAltName
;
3552 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
3553 decodeFunc
= CRYPT_AsnDecodeAltName
;
3554 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
3555 decodeFunc
= CRYPT_AsnDecodeAltName
;
3556 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
3557 decodeFunc
= CRYPT_AsnDecodeAltName
;
3558 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
3559 decodeFunc
= CRYPT_AsnDecodeAltName
;
3560 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
3561 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3562 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
3563 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3564 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
3565 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3567 TRACE("OID %s not found or unimplemented, looking for DLL\n",
3568 debugstr_a(lpszStructType
));
3572 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
3573 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
3574 (void **)&decodeFunc
, &hFunc
);
3577 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
3578 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3580 SetLastError(ERROR_FILE_NOT_FOUND
);
3582 CryptFreeOIDFunctionAddress(hFunc
, 0);