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
46 #include "wine/debug.h"
47 #include "wine/exception.h"
48 #include "crypt32_private.h"
50 /* This is a bit arbitrary, but to set some limit: */
51 #define MAX_ENCODED_LEN 0x02000000
53 #define ASN_FLAGS_MASK 0xe0
54 #define ASN_TYPE_MASK 0x1f
56 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
64 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
65 DWORD
, DWORD
, void *, DWORD
*);
66 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
67 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
69 /* Prototypes for built-in decoders. They follow the Ex style prototypes.
70 * The dwCertEncodingType and lpszStructType are ignored by the built-in
71 * functions, but the parameters are retained to simplify CryptDecodeObjectEx,
72 * since it must call functions in external DLLs that follow these signatures.
74 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
75 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
76 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
77 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
78 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
79 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
80 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
81 * time, doesn't do memory allocation, and doesn't do exception handling.
82 * (This isn't intended to be the externally-called one.)
84 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
85 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
86 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
87 /* Assumes algo->Parameters.pbData is set ahead of time. Internal func. */
88 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
89 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
90 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
91 /* Internal function */
92 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
93 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
94 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
97 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
98 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
99 /* Like CRYPT_AsnDecodeBits, but assumes the CRYPT_INTEGER_BLOB's pbData
100 * member has been initialized, doesn't do exception handling, and doesn't do
103 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
104 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
105 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
106 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
107 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
108 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
109 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
110 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
111 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
112 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
113 * member has been initialized, doesn't do exception handling, and doesn't do
114 * memory allocation. Also doesn't check tag, assumes the caller has checked
117 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
118 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
119 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
120 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
121 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
122 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
123 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
124 void *pvStructInfo
, DWORD
*pcbStructInfo
);
126 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
127 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
128 DWORD
*pcbStructInfo
)
130 static HCRYPTOIDFUNCSET set
= NULL
;
132 CryptDecodeObjectFunc pCryptDecodeObject
;
133 HCRYPTOIDFUNCADDR hFunc
;
135 TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
136 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
137 pvStructInfo
, pcbStructInfo
);
139 if (!pvStructInfo
&& !pcbStructInfo
)
141 SetLastError(ERROR_INVALID_PARAMETER
);
145 /* Try registered DLL first.. */
147 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
148 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
149 (void **)&pCryptDecodeObject
, &hFunc
);
150 if (pCryptDecodeObject
)
152 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
153 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
154 CryptFreeOIDFunctionAddress(hFunc
, 0);
158 /* If not, use CryptDecodeObjectEx */
159 ret
= CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
, pbEncoded
,
160 cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
165 /* Gets the number of length bytes from the given (leading) length byte */
166 #define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
168 /* Helper function to get the encoded length of the data starting at pbEncoded,
169 * where pbEncoded[0] is the tag. If the data are too short to contain a
170 * length or if the length is too large for cbEncoded, sets an appropriate
171 * error code and returns FALSE.
173 static BOOL WINAPI
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
180 SetLastError(CRYPT_E_ASN1_CORRUPT
);
183 else if (pbEncoded
[1] <= 0x7f)
185 if (pbEncoded
[1] + 1 > cbEncoded
)
187 SetLastError(CRYPT_E_ASN1_EOD
);
198 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
200 if (lenLen
> sizeof(DWORD
) + 1)
202 SetLastError(CRYPT_E_ASN1_LARGE
);
205 else if (lenLen
+ 2 > cbEncoded
)
207 SetLastError(CRYPT_E_ASN1_CORRUPT
);
220 if (out
+ lenLen
+ 1 > cbEncoded
)
222 SetLastError(CRYPT_E_ASN1_EOD
);
235 /* Helper function to check *pcbStructInfo, set it to the required size, and
236 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
237 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
238 * pointer to the newly allocated memory.
240 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
241 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
246 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
248 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
249 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
251 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
252 if (!*(BYTE
**)pvStructInfo
)
255 *pcbStructInfo
= bytesNeeded
;
257 else if (*pcbStructInfo
< bytesNeeded
)
259 *pcbStructInfo
= bytesNeeded
;
260 SetLastError(ERROR_MORE_DATA
);
267 * The expected tag of the item. If tag is 0, decodeFunc is called
268 * regardless of the tag value seen.
270 * A sequence is decoded into a struct. The offset member is the
271 * offset of this item within that struct.
273 * The decoder function to use. If this is NULL, then the member isn't
274 * decoded, but minSize space is reserved for it.
276 * The minimum amount of space occupied after decoding. You must set this.
278 * If true, and the tag doesn't match the expected tag for this item,
279 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
280 * filled with 0 for this member.
281 * hasPointer, pointerOffset:
282 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
283 * the offset within the struct of the data pointer (or to the
284 * first data pointer, if more than one exist).
286 * Used by CRYPT_AsnDecodeSequence, not for your use.
288 struct AsnDecodeSequenceItem
292 CryptDecodeObjectExFunc decodeFunc
;
300 /* Decodes the items in a sequence, where the items are described in items,
301 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
302 * pvStructInfo. nextData is a pointer to the memory location at which the
303 * first decoded item with a dynamic pointer should point.
304 * Upon decoding, *cbDecoded is the total number of bytes decoded.
306 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
307 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
308 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
,
312 DWORD i
, decoded
= 0;
313 const BYTE
*ptr
= pbEncoded
;
315 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
317 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
321 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
324 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
326 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
328 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
330 TRACE("Setting next pointer to %p\n",
332 *(BYTE
**)((BYTE
*)pvStructInfo
+
333 items
[i
].pointerOffset
) = nextData
;
335 if (items
[i
].decodeFunc
)
338 TRACE("decoding item %d\n", i
);
340 TRACE("sizing item %d\n", i
);
341 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
342 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
343 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
344 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
345 : NULL
, &items
[i
].size
);
348 if (nextData
&& items
[i
].hasPointer
&&
349 items
[i
].size
> items
[i
].minSize
)
351 nextData
+= items
[i
].size
- items
[i
].minSize
;
352 /* align nextData to DWORD boundaries */
353 if (items
[i
].size
% sizeof(DWORD
))
354 nextData
+= sizeof(DWORD
) - items
[i
].size
%
357 /* Account for alignment padding */
358 if (items
[i
].size
% sizeof(DWORD
))
359 items
[i
].size
+= sizeof(DWORD
) -
360 items
[i
].size
% sizeof(DWORD
);
361 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
362 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
364 else if (items
[i
].optional
&&
365 GetLastError() == CRYPT_E_ASN1_BADTAG
)
367 TRACE("skipping optional item %d\n", i
);
368 items
[i
].size
= items
[i
].minSize
;
369 SetLastError(NOERROR
);
373 TRACE("item %d failed: %08x\n", i
,
378 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
379 items
[i
].size
= items
[i
].minSize
;
382 else if (items
[i
].optional
)
384 TRACE("skipping optional item %d\n", i
);
385 items
[i
].size
= items
[i
].minSize
;
389 TRACE("tag %02x doesn't match expected %02x\n",
390 ptr
[0], items
[i
].tag
);
391 SetLastError(CRYPT_E_ASN1_BADTAG
);
396 else if (items
[i
].optional
)
398 TRACE("missing optional item %d, skipping\n", i
);
399 items
[i
].size
= items
[i
].minSize
;
403 TRACE("not enough bytes for item %d, failing\n", i
);
404 SetLastError(CRYPT_E_ASN1_CORRUPT
);
409 *cbDecoded
= decoded
;
413 /* This decodes an arbitrary sequence into a contiguous block of memory
414 * (basically, a struct.) Each element being decoded is described by a struct
415 * AsnDecodeSequenceItem, see above.
416 * startingPointer is an optional pointer to the first place where dynamic
417 * data will be stored. If you know the starting offset, you may pass it
418 * here. Otherwise, pass NULL, and one will be inferred from the items.
419 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
421 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
422 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
423 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
424 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
428 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
429 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
432 if (pbEncoded
[0] == ASN_SEQUENCE
)
436 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
438 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
439 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
441 cbEncoded
-= 1 + lenBytes
;
442 if (cbEncoded
< dataLen
)
444 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
446 SetLastError(CRYPT_E_ASN1_CORRUPT
);
450 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, ptr
,
451 cbEncoded
, dwFlags
, NULL
, NULL
, &cbDecoded
);
452 if (ret
&& cbDecoded
!= dataLen
)
454 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
456 SetLastError(CRYPT_E_ASN1_CORRUPT
);
461 DWORD i
, bytesNeeded
= 0, structSize
= 0;
463 for (i
= 0; i
< cItem
; i
++)
465 bytesNeeded
+= items
[i
].size
;
466 structSize
+= items
[i
].minSize
;
469 *pcbStructInfo
= bytesNeeded
;
470 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
471 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
475 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
476 pvStructInfo
= *(BYTE
**)pvStructInfo
;
478 nextData
= (BYTE
*)startingPointer
;
480 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
481 memset(pvStructInfo
, 0, structSize
);
482 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
483 ptr
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
,
491 SetLastError(CRYPT_E_ASN1_BADTAG
);
494 TRACE("returning %d (%08x)\n", ret
, GetLastError());
499 * The expected tag of the entire encoded array (usually a variant
500 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
501 * regardless of the tag seen.
503 * used to decode each item in the array
505 * is the minimum size of each decoded item
507 * indicates whether each item has a dynamic pointer
509 * indicates the offset within itemSize at which the pointer exists
511 struct AsnArrayDescriptor
514 CryptDecodeObjectExFunc decodeFunc
;
520 struct AsnArrayItemSize
526 /* Decodes an array of like types into a struct GenericArray.
527 * The layout and decoding of the array are described by a struct
528 * AsnArrayDescriptor.
530 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
531 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
532 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
533 void *startingPointer
)
537 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
538 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
541 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
545 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
547 DWORD bytesNeeded
, cItems
= 0;
548 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
549 /* There can be arbitrarily many items, but there is often only one.
551 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
553 bytesNeeded
= sizeof(struct GenericArray
);
558 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
559 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
561 DWORD itemLenBytes
, itemDataLen
, size
= 0;
563 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
564 /* Each item decoded may not tolerate extraneous bytes, so
565 * get the length of the next element and pass it directly.
567 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
570 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
571 1 + itemLenBytes
+ itemDataLen
,
572 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
579 if (itemSizes
!= &itemSize
)
580 itemSizes
= CryptMemRealloc(itemSizes
,
581 cItems
* sizeof(struct AsnArrayItemSize
));
586 cItems
* sizeof(struct AsnArrayItemSize
));
588 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
592 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
594 itemSizes
[cItems
- 1].size
= size
;
596 ret
= CRYPT_GetLen(ptr
,
597 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
599 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
609 *pcbStructInfo
= bytesNeeded
;
610 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
611 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
616 struct GenericArray
*array
;
618 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
619 pvStructInfo
= *(BYTE
**)pvStructInfo
;
620 array
= (struct GenericArray
*)pvStructInfo
;
621 array
->cItems
= cItems
;
623 array
->rgItems
= startingPointer
;
625 array
->rgItems
= (BYTE
*)array
+
626 sizeof(struct GenericArray
);
627 nextData
= (BYTE
*)array
->rgItems
+
628 array
->cItems
* arrayDesc
->itemSize
;
629 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
630 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
633 if (arrayDesc
->hasPointer
)
634 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
635 + arrayDesc
->pointerOffset
) = nextData
;
636 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
637 itemSizes
[i
].encodedLen
,
638 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
639 array
->rgItems
+ i
* arrayDesc
->itemSize
,
645 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
646 ret
= CRYPT_GetLen(ptr
,
647 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
649 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
654 if (itemSizes
!= &itemSize
)
655 CryptMemFree(itemSizes
);
660 SetLastError(CRYPT_E_ASN1_BADTAG
);
666 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
667 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
668 * to CRYPT_E_ASN1_CORRUPT.
669 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
672 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
673 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
674 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
679 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
681 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
682 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
684 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
685 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
688 *pcbStructInfo
= bytesNeeded
;
689 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
690 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
692 CRYPT_DER_BLOB
*blob
;
694 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
695 pvStructInfo
= *(BYTE
**)pvStructInfo
;
696 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
697 blob
->cbData
= 1 + lenBytes
+ dataLen
;
700 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
701 blob
->pbData
= (BYTE
*)pbEncoded
;
704 assert(blob
->pbData
);
705 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
710 SetLastError(CRYPT_E_ASN1_CORRUPT
);
718 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
719 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
720 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
721 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
725 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
726 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
728 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
731 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
732 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
733 pvStructInfo
, pcbStructInfo
);
734 if (ret
&& pvStructInfo
)
736 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
743 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
745 temp
= blob
->pbData
[i
];
746 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
747 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
751 TRACE("returning %d (%08x)\n", ret
, GetLastError());
755 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
756 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
757 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
761 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
762 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
766 struct AsnDecodeSequenceItem items
[] = {
767 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
768 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
769 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
770 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
771 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
772 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
773 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
774 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
775 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
776 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
779 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
780 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
781 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
782 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
783 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
787 SetLastError(STATUS_ACCESS_VIOLATION
);
792 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
796 /* Internal function */
797 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
798 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
799 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
804 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
806 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
808 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
809 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
810 pvStructInfo
, pcbStructInfo
);
815 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
816 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
817 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
821 struct AsnDecodeSequenceItem items
[] = {
822 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
823 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
824 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
825 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
828 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
829 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
830 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
834 /* Internal function */
835 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
836 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
837 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
842 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
844 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
846 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
847 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
848 pDecodePara
, pvStructInfo
, pcbStructInfo
);
853 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
854 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
855 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
858 struct AsnDecodeSequenceItem items
[] = {
859 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
860 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
861 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
862 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
863 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
864 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
865 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
866 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
867 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
868 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
870 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
871 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
873 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
874 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
876 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
877 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
878 FALSE
, TRUE
, offsetof(CERT_INFO
,
879 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
880 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
881 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
882 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
883 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
884 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
885 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
886 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
887 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
888 offsetof(CERT_INFO
, rgExtension
), 0 },
891 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
892 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
894 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
895 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
896 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
897 if (ret
&& pvStructInfo
)
901 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
902 info
= *(CERT_INFO
**)pvStructInfo
;
904 info
= (CERT_INFO
*)pvStructInfo
;
905 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
906 !info
->Subject
.cbData
)
908 SetLastError(CRYPT_E_ASN1_CORRUPT
);
909 /* Don't need to deallocate, because it should have failed on the
910 * first pass (and no memory was allocated.)
916 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
920 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
921 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
922 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
926 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
927 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
931 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
934 /* First try to decode it as a signed cert. */
935 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
936 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
937 (BYTE
*)&signedCert
, &size
);
941 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
942 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
943 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
, pvStructInfo
,
945 LocalFree(signedCert
);
947 /* Failing that, try it as an unsigned cert */
951 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
952 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
953 pDecodePara
, pvStructInfo
, pcbStructInfo
);
958 SetLastError(STATUS_ACCESS_VIOLATION
);
963 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
967 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
968 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
969 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
972 struct AsnDecodeSequenceItem items
[] = {
973 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
974 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
975 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
976 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
977 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
978 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
979 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
980 offsetof(CRL_ENTRY
, rgExtension
), 0 },
982 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
984 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
987 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
988 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
989 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
993 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
994 * been set prior to calling.
996 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
997 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
998 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1001 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1002 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1003 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1004 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1006 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1007 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1009 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1010 pDecodePara
, pvStructInfo
, pcbStructInfo
,
1011 entries
? entries
->rgItems
: NULL
);
1012 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1016 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1017 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1018 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1020 struct AsnDecodeSequenceItem items
[] = {
1021 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1022 CRYPT_AsnDecodeInt
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1023 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1024 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1025 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1026 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1027 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1029 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1030 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1031 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1032 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1033 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1034 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1035 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1036 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1037 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1038 offsetof(CRL_INFO
, rgExtension
), 0 },
1042 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1043 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1045 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1046 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1047 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1049 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1053 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1054 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1055 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1059 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1060 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1064 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1067 /* First try to decode it as a signed crl. */
1068 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
1069 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1070 (BYTE
*)&signedCrl
, &size
);
1074 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1075 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1076 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1077 pvStructInfo
, pcbStructInfo
);
1078 LocalFree(signedCrl
);
1080 /* Failing that, try it as an unsigned crl */
1084 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1085 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1086 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1091 SetLastError(STATUS_ACCESS_VIOLATION
);
1096 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1100 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
1101 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1102 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1106 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1107 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1109 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1113 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1115 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1116 DWORD bytesNeeded
= sizeof(LPSTR
);
1120 /* The largest possible string for the first two components
1121 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1126 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1127 pbEncoded
[1 + lenBytes
] / 40,
1128 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1130 bytesNeeded
+= strlen(firstTwo
) + 1;
1131 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1132 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1134 /* large enough for ".4000000" */
1138 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1145 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1148 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1155 snprintf(str
, sizeof(str
), ".%d", val
);
1156 bytesNeeded
+= strlen(str
);
1161 *pcbStructInfo
= bytesNeeded
;
1162 else if (*pcbStructInfo
< bytesNeeded
)
1164 *pcbStructInfo
= bytesNeeded
;
1165 SetLastError(ERROR_MORE_DATA
);
1173 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1176 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1177 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1179 pszObjId
+= strlen(pszObjId
);
1180 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1181 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1185 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1194 sprintf(pszObjId
, ".%d", val
);
1195 pszObjId
+= strlen(pszObjId
);
1199 *(LPSTR
*)pvStructInfo
= NULL
;
1200 *pcbStructInfo
= bytesNeeded
;
1207 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1210 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1211 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1212 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1214 struct AsnDecodeSequenceItem items
[] = {
1215 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1216 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1217 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1218 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1219 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1220 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1221 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1222 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1225 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1227 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1231 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1232 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1233 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1234 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1236 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1237 debugstr_a(ext
->pszObjId
));
1238 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1242 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1243 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1244 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1247 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1248 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1249 offsetof(CERT_EXTENSION
, pszObjId
) };
1250 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1253 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1255 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1256 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1260 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1261 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1262 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1268 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1269 lpszStructType
, pbEncoded
, cbEncoded
,
1270 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1271 if (ret
&& pvStructInfo
)
1273 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1274 pcbStructInfo
, *pcbStructInfo
);
1277 CERT_EXTENSIONS
*exts
;
1279 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1280 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1281 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1282 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1283 sizeof(CERT_EXTENSIONS
));
1284 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1285 lpszStructType
, pbEncoded
, cbEncoded
,
1286 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1293 SetLastError(STATUS_ACCESS_VIOLATION
);
1300 /* Warning: this assumes the address of value->Value.pbData is already set, in
1301 * order to avoid overwriting memory. (In some cases, it may change it, if it
1302 * doesn't copy anything to memory.) Be sure to set it correctly!
1304 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1305 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1306 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1310 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1312 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1314 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1315 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1317 switch (pbEncoded
[0])
1319 case ASN_OCTETSTRING
:
1320 valueType
= CERT_RDN_OCTET_STRING
;
1321 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1322 bytesNeeded
+= dataLen
;
1324 case ASN_NUMERICSTRING
:
1325 valueType
= CERT_RDN_NUMERIC_STRING
;
1326 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1327 bytesNeeded
+= dataLen
;
1329 case ASN_PRINTABLESTRING
:
1330 valueType
= CERT_RDN_PRINTABLE_STRING
;
1331 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1332 bytesNeeded
+= dataLen
;
1335 valueType
= CERT_RDN_IA5_STRING
;
1336 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1337 bytesNeeded
+= dataLen
;
1340 valueType
= CERT_RDN_T61_STRING
;
1341 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1342 bytesNeeded
+= dataLen
;
1344 case ASN_VIDEOTEXSTRING
:
1345 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1346 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1347 bytesNeeded
+= dataLen
;
1349 case ASN_GRAPHICSTRING
:
1350 valueType
= CERT_RDN_GRAPHIC_STRING
;
1351 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1352 bytesNeeded
+= dataLen
;
1354 case ASN_VISIBLESTRING
:
1355 valueType
= CERT_RDN_VISIBLE_STRING
;
1356 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1357 bytesNeeded
+= dataLen
;
1359 case ASN_GENERALSTRING
:
1360 valueType
= CERT_RDN_GENERAL_STRING
;
1361 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1362 bytesNeeded
+= dataLen
;
1364 case ASN_UNIVERSALSTRING
:
1365 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1366 SetLastError(CRYPT_E_ASN1_BADTAG
);
1369 valueType
= CERT_RDN_BMP_STRING
;
1370 bytesNeeded
+= dataLen
;
1372 case ASN_UTF8STRING
:
1373 valueType
= CERT_RDN_UTF8_STRING
;
1374 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1375 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1378 SetLastError(CRYPT_E_ASN1_BADTAG
);
1383 *pcbStructInfo
= bytesNeeded
;
1384 else if (*pcbStructInfo
< bytesNeeded
)
1386 *pcbStructInfo
= bytesNeeded
;
1387 SetLastError(ERROR_MORE_DATA
);
1392 *pcbStructInfo
= bytesNeeded
;
1393 value
->dwValueType
= valueType
;
1398 assert(value
->Value
.pbData
);
1399 switch (pbEncoded
[0])
1401 case ASN_OCTETSTRING
:
1402 case ASN_NUMERICSTRING
:
1403 case ASN_PRINTABLESTRING
:
1406 case ASN_VIDEOTEXSTRING
:
1407 case ASN_GRAPHICSTRING
:
1408 case ASN_VISIBLESTRING
:
1409 case ASN_GENERALSTRING
:
1410 value
->Value
.cbData
= dataLen
;
1413 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1414 memcpy(value
->Value
.pbData
,
1415 pbEncoded
+ 1 + lenBytes
, dataLen
);
1417 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1423 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1425 value
->Value
.cbData
= dataLen
;
1426 for (i
= 0; i
< dataLen
/ 2; i
++)
1427 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1428 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1431 case ASN_UTF8STRING
:
1433 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1435 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1436 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1437 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1444 value
->Value
.cbData
= 0;
1445 value
->Value
.pbData
= NULL
;
1452 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1453 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1454 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1460 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1461 lpszStructType
, pbEncoded
, cbEncoded
,
1462 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1463 if (ret
&& pvStructInfo
)
1465 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1466 pcbStructInfo
, *pcbStructInfo
);
1469 CERT_NAME_VALUE
*value
;
1471 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1472 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1473 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1474 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1475 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1476 lpszStructType
, pbEncoded
, cbEncoded
,
1477 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1484 SetLastError(STATUS_ACCESS_VIOLATION
);
1491 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1492 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1493 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1494 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1498 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1500 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1502 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1503 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1505 switch (pbEncoded
[0])
1507 case ASN_NUMERICSTRING
:
1508 valueType
= CERT_RDN_NUMERIC_STRING
;
1509 bytesNeeded
+= dataLen
* 2;
1511 case ASN_PRINTABLESTRING
:
1512 valueType
= CERT_RDN_PRINTABLE_STRING
;
1513 bytesNeeded
+= dataLen
* 2;
1516 valueType
= CERT_RDN_IA5_STRING
;
1517 bytesNeeded
+= dataLen
* 2;
1520 valueType
= CERT_RDN_T61_STRING
;
1521 bytesNeeded
+= dataLen
* 2;
1523 case ASN_VIDEOTEXSTRING
:
1524 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1525 bytesNeeded
+= dataLen
* 2;
1527 case ASN_GRAPHICSTRING
:
1528 valueType
= CERT_RDN_GRAPHIC_STRING
;
1529 bytesNeeded
+= dataLen
* 2;
1531 case ASN_VISIBLESTRING
:
1532 valueType
= CERT_RDN_VISIBLE_STRING
;
1533 bytesNeeded
+= dataLen
* 2;
1535 case ASN_GENERALSTRING
:
1536 valueType
= CERT_RDN_GENERAL_STRING
;
1537 bytesNeeded
+= dataLen
* 2;
1539 case ASN_UNIVERSALSTRING
:
1540 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1541 bytesNeeded
+= dataLen
/ 2;
1544 valueType
= CERT_RDN_BMP_STRING
;
1545 bytesNeeded
+= dataLen
;
1547 case ASN_UTF8STRING
:
1548 valueType
= CERT_RDN_UTF8_STRING
;
1549 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1550 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1553 SetLastError(CRYPT_E_ASN1_BADTAG
);
1558 *pcbStructInfo
= bytesNeeded
;
1559 else if (*pcbStructInfo
< bytesNeeded
)
1561 *pcbStructInfo
= bytesNeeded
;
1562 SetLastError(ERROR_MORE_DATA
);
1567 *pcbStructInfo
= bytesNeeded
;
1568 value
->dwValueType
= valueType
;
1572 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1574 assert(value
->Value
.pbData
);
1575 switch (pbEncoded
[0])
1577 case ASN_NUMERICSTRING
:
1578 case ASN_PRINTABLESTRING
:
1581 case ASN_VIDEOTEXSTRING
:
1582 case ASN_GRAPHICSTRING
:
1583 case ASN_VISIBLESTRING
:
1584 case ASN_GENERALSTRING
:
1585 value
->Value
.cbData
= dataLen
* 2;
1586 for (i
= 0; i
< dataLen
; i
++)
1587 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1589 case ASN_UNIVERSALSTRING
:
1590 value
->Value
.cbData
= dataLen
/ 2;
1591 for (i
= 0; i
< dataLen
/ 4; i
++)
1592 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1593 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1596 value
->Value
.cbData
= dataLen
;
1597 for (i
= 0; i
< dataLen
/ 2; i
++)
1598 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1599 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1601 case ASN_UTF8STRING
:
1602 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1603 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1604 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1610 value
->Value
.cbData
= 0;
1611 value
->Value
.pbData
= NULL
;
1618 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1619 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1620 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1626 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1627 lpszStructType
, pbEncoded
, cbEncoded
,
1628 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1629 if (ret
&& pvStructInfo
)
1631 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1632 pcbStructInfo
, *pcbStructInfo
);
1635 CERT_NAME_VALUE
*value
;
1637 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1638 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1639 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1640 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1641 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1642 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1643 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1650 SetLastError(STATUS_ACCESS_VIOLATION
);
1657 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1658 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1659 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1662 struct AsnDecodeSequenceItem items
[] = {
1663 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1664 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1665 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1666 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1667 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1668 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1670 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1672 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1673 pvStructInfo
, *pcbStructInfo
);
1676 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1677 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1678 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1679 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1682 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1683 debugstr_a(attr
->pszObjId
));
1684 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1686 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1690 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1691 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1692 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1695 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1696 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1697 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1698 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1700 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1701 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1705 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1706 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1707 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1713 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1714 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1715 offsetof(CERT_RDN
, rgRDNAttr
) };
1717 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1718 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1722 SetLastError(STATUS_ACCESS_VIOLATION
);
1729 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType
,
1730 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1731 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1734 struct AsnDecodeSequenceItem items
[] = {
1735 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1736 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1737 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1738 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1739 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1740 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1742 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1744 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1745 pvStructInfo
, *pcbStructInfo
);
1748 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1749 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1750 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1751 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1754 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1755 debugstr_a(attr
->pszObjId
));
1756 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1758 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1762 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType
,
1763 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1764 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1767 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1768 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1769 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1770 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1772 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1773 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1777 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1778 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1779 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1785 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1786 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1787 offsetof(CERT_RDN
, rgRDNAttr
) };
1789 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1790 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1794 SetLastError(STATUS_ACCESS_VIOLATION
);
1801 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1802 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1803 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1806 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1808 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1809 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1811 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1812 bytesNeeded
+= cbEncoded
;
1814 *pcbStructInfo
= bytesNeeded
;
1815 else if (*pcbStructInfo
< bytesNeeded
)
1817 SetLastError(ERROR_MORE_DATA
);
1818 *pcbStructInfo
= bytesNeeded
;
1823 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1825 *pcbStructInfo
= bytesNeeded
;
1826 blob
->cbData
= cbEncoded
;
1827 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1828 blob
->pbData
= (LPBYTE
)pbEncoded
;
1831 assert(blob
->pbData
);
1832 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1838 static BOOL WINAPI
CRYPT_DecodeDERArray(DWORD dwCertEncodingType
,
1839 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1840 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1843 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1844 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
), TRUE
,
1845 offsetof(CRYPT_DER_BLOB
, pbData
) };
1846 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
1848 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1849 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1851 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1852 pDecodePara
, pvStructInfo
, pcbStructInfo
, array
? array
->rgItems
: NULL
);
1856 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
1857 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1858 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1864 struct AsnDecodeSequenceItem items
[] = {
1865 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
1866 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1867 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
1868 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
1869 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
1870 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
1872 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
1874 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1875 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1876 pDecodePara
, pvStructInfo
, pcbStructInfo
, attr
? attr
->pszObjId
:
1881 SetLastError(STATUS_ACCESS_VIOLATION
);
1884 TRACE("returning %d\n", ret
);
1888 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributesInternal(
1889 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1890 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1891 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1893 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1894 CRYPT_AsnDecodePKCSAttribute
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
1895 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
1896 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1899 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1900 pDecodePara
, pvStructInfo
, pcbStructInfo
, attrs
? attrs
->rgAttr
:
1905 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
1906 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1907 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1911 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1912 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1918 if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1919 lpszStructType
, pbEncoded
, cbEncoded
,
1920 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1923 *pcbStructInfo
= bytesNeeded
;
1924 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1925 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1927 PCRYPT_ATTRIBUTES attrs
;
1929 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1930 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1931 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1932 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
1933 sizeof(CRYPT_ATTRIBUTES
));
1934 ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1935 lpszStructType
, pbEncoded
, cbEncoded
,
1936 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1943 SetLastError(STATUS_ACCESS_VIOLATION
);
1946 TRACE("returning %d\n", ret
);
1950 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1951 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1952 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1954 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1955 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1957 struct AsnDecodeSequenceItem items
[] = {
1958 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1959 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1960 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1961 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1962 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1963 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1966 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1967 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1969 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1970 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1971 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1972 if (ret
&& pvStructInfo
)
1974 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1975 debugstr_a(algo
->pszObjId
));
1980 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1981 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1982 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1985 struct AsnDecodeSequenceItem items
[] = {
1986 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1987 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1988 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
1989 Algorithm
.pszObjId
) },
1990 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
1991 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1992 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
1994 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1996 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1997 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1998 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
1999 info
->Algorithm
.Parameters
.pbData
: NULL
);
2003 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2004 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2005 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2013 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2014 lpszStructType
, pbEncoded
, cbEncoded
,
2015 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2018 *pcbStructInfo
= bytesNeeded
;
2019 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2020 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2022 PCERT_PUBLIC_KEY_INFO info
;
2024 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2025 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2026 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2027 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2028 sizeof(CERT_PUBLIC_KEY_INFO
);
2029 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2030 lpszStructType
, pbEncoded
, cbEncoded
,
2031 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2038 SetLastError(STATUS_ACCESS_VIOLATION
);
2045 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
2046 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2047 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2053 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2056 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2058 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2061 if (pbEncoded
[1] > 1)
2063 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2068 *pcbStructInfo
= sizeof(BOOL
);
2071 else if (*pcbStructInfo
< sizeof(BOOL
))
2073 *pcbStructInfo
= sizeof(BOOL
);
2074 SetLastError(ERROR_MORE_DATA
);
2079 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2082 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2086 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
2087 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2088 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2090 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2091 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2094 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2095 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2099 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2102 if ((pbEncoded
[0] & ASN_FLAGS_MASK
) != ASN_CONTEXT
)
2104 SetLastError(CRYPT_E_ASN1_BADTAG
);
2107 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2108 if (1 + lenBytes
> cbEncoded
)
2110 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2113 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2115 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2117 case 1: /* rfc822Name */
2118 case 2: /* dNSName */
2119 case 6: /* uniformResourceIdentifier */
2120 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2122 case 7: /* iPAddress */
2123 bytesNeeded
+= dataLen
;
2125 case 8: /* registeredID */
2126 /* FIXME: decode as OID */
2127 case 0: /* otherName */
2128 case 4: /* directoryName */
2130 SetLastError(CRYPT_E_ASN1_BADTAG
);
2133 case 3: /* x400Address, unimplemented */
2134 case 5: /* ediPartyName, unimplemented */
2135 SetLastError(CRYPT_E_ASN1_BADTAG
);
2139 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2145 *pcbStructInfo
= bytesNeeded
;
2146 else if (*pcbStructInfo
< bytesNeeded
)
2148 *pcbStructInfo
= bytesNeeded
;
2149 SetLastError(ERROR_MORE_DATA
);
2154 *pcbStructInfo
= bytesNeeded
;
2155 /* MS used values one greater than the asn1 ones.. sigh */
2156 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2157 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2159 case 1: /* rfc822Name */
2160 case 2: /* dNSName */
2161 case 6: /* uniformResourceIdentifier */
2165 for (i
= 0; i
< dataLen
; i
++)
2166 entry
->u
.pwszURL
[i
] =
2167 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2168 entry
->u
.pwszURL
[i
] = 0;
2169 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2170 debugstr_w(entry
->u
.pwszURL
));
2173 case 7: /* iPAddress */
2174 /* The next data pointer is in the pwszURL spot, that is,
2175 * the first 4 bytes. Need to move it to the next spot.
2177 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2178 entry
->u
.IPAddress
.cbData
= dataLen
;
2179 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2189 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2190 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2191 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2194 struct AsnArrayDescriptor arrayDesc
= { 0,
2195 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2196 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2197 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2199 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2200 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2203 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2204 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2205 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
2209 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2210 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2211 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2217 struct AsnDecodeSequenceItem items
[] = {
2218 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2219 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2220 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2221 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2222 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2223 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2224 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2225 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2226 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2227 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2228 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2231 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2232 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2233 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2237 SetLastError(STATUS_ACCESS_VIOLATION
);
2244 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2245 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2246 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2252 struct AsnDecodeSequenceItem items
[] = {
2253 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2254 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2255 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2256 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2257 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2258 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2259 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2260 AuthorityCertIssuer
.rgAltEntry
), 0 },
2261 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2262 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2263 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2264 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2265 AuthorityCertSerialNumber
.pbData
), 0 },
2268 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2269 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2270 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2274 SetLastError(STATUS_ACCESS_VIOLATION
);
2281 static BOOL WINAPI
CRYPT_AsnDecodePKCSContent(DWORD dwCertEncodingType
,
2282 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2283 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2288 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2289 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2291 /* The caller has already checked the tag, no need to check it again.
2292 * Check the outer length is valid by calling CRYPT_GetLen:
2294 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2296 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2299 pbEncoded
+= 1 + lenBytes
;
2300 /* Check the inner length is valid by calling CRYPT_GetLen again: */
2301 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &innerLen
)))
2303 ret
= CRYPT_AsnDecodeCopyBytes(dwCertEncodingType
, NULL
,
2304 pbEncoded
, dataLen
, dwFlags
, pDecodePara
, pvStructInfo
,
2311 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfoInternal(
2312 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2313 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2314 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2316 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2317 struct AsnDecodeSequenceItem items
[] = {
2318 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2319 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
2320 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2321 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2322 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2323 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2324 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2327 return CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2328 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2329 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->pszObjId
: NULL
);
2332 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2333 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2334 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2339 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2343 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2344 lpszStructType
, pbEncoded
, cbEncoded
,
2345 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
2346 if (ret
&& pvStructInfo
)
2348 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2349 pcbStructInfo
, *pcbStructInfo
);
2352 CRYPT_CONTENT_INFO
*info
;
2354 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2355 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2356 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2357 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2358 sizeof(CRYPT_CONTENT_INFO
));
2359 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2360 lpszStructType
, pbEncoded
, cbEncoded
,
2361 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2368 SetLastError(STATUS_ACCESS_VIOLATION
);
2374 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2375 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2376 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2379 struct AsnDecodeSequenceItem items
[] = {
2380 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
), CRYPT_AsnDecodeInt
,
2381 sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2382 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2383 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2384 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2386 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2387 CRYPT_AsnDecodePKCSContentInfoInternal
,
2388 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2389 ContentInfo
.pszObjId
), 0 },
2390 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2391 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2392 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2395 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
2396 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2397 pDecodePara
, digestedData
, pcbDigestedData
, NULL
);
2401 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2402 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2403 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2407 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2408 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2412 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2413 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2414 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2416 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2417 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2421 SetLastError(STATUS_ACCESS_VIOLATION
);
2428 struct PATH_LEN_CONSTRAINT
2430 BOOL fPathLenConstraint
;
2431 DWORD dwPathLenConstraint
;
2434 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2435 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2436 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2440 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2441 pvStructInfo
, *pcbStructInfo
);
2445 if (pbEncoded
[0] == ASN_INTEGER
)
2447 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2450 *pcbStructInfo
= bytesNeeded
;
2451 else if (*pcbStructInfo
< bytesNeeded
)
2453 SetLastError(ERROR_MORE_DATA
);
2454 *pcbStructInfo
= bytesNeeded
;
2459 struct PATH_LEN_CONSTRAINT
*constraint
=
2460 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2461 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2463 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
2464 pbEncoded
, cbEncoded
, 0, NULL
,
2465 &constraint
->dwPathLenConstraint
, &size
);
2467 constraint
->fPathLenConstraint
= TRUE
;
2468 TRACE("got an int, dwPathLenConstraint is %d\n",
2469 constraint
->dwPathLenConstraint
);
2474 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2478 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2482 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2483 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2484 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2487 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2488 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2489 offsetof(CERT_NAME_BLOB
, pbData
) };
2490 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2492 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2493 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2495 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2496 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2497 entries
? entries
->rgItems
: NULL
);
2498 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2502 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2503 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2504 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2510 struct AsnDecodeSequenceItem items
[] = {
2511 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2512 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2513 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2514 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2515 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2516 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2517 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2518 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2519 sizeof(struct GenericArray
), TRUE
, TRUE
,
2520 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2523 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2524 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2525 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2529 SetLastError(STATUS_ACCESS_VIOLATION
);
2536 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2537 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2538 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2544 struct AsnDecodeSequenceItem items
[] = {
2545 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2546 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2547 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2548 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2549 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2552 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2553 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2554 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2558 SetLastError(STATUS_ACCESS_VIOLATION
);
2565 #define RSA1_MAGIC 0x31415352
2567 struct DECODED_RSA_PUB_KEY
2570 CRYPT_INTEGER_BLOB modulus
;
2573 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2574 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2575 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2581 struct AsnDecodeSequenceItem items
[] = {
2582 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2583 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2584 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2586 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2587 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2589 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2592 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2593 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2594 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
2597 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2598 decodedKey
->modulus
.cbData
;
2602 *pcbStructInfo
= bytesNeeded
;
2605 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2606 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2609 RSAPUBKEY
*rsaPubKey
;
2611 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2612 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2613 hdr
= (BLOBHEADER
*)pvStructInfo
;
2614 hdr
->bType
= PUBLICKEYBLOB
;
2615 hdr
->bVersion
= CUR_BLOB_VERSION
;
2617 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2618 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2619 sizeof(BLOBHEADER
));
2620 rsaPubKey
->magic
= RSA1_MAGIC
;
2621 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2622 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2623 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2624 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2625 decodedKey
->modulus
.cbData
);
2627 LocalFree(decodedKey
);
2632 SetLastError(STATUS_ACCESS_VIOLATION
);
2639 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2640 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2641 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2644 DWORD bytesNeeded
, dataLen
;
2646 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2647 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2649 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2651 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2652 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2654 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2656 *pcbStructInfo
= bytesNeeded
;
2657 else if (*pcbStructInfo
< bytesNeeded
)
2659 SetLastError(ERROR_MORE_DATA
);
2660 *pcbStructInfo
= bytesNeeded
;
2665 CRYPT_DATA_BLOB
*blob
;
2666 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2668 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2669 blob
->cbData
= dataLen
;
2670 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2671 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2674 assert(blob
->pbData
);
2676 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2684 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2685 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2686 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2690 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2691 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2699 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2702 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2704 SetLastError(CRYPT_E_ASN1_BADTAG
);
2707 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2708 lpszStructType
, pbEncoded
, cbEncoded
,
2709 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2712 *pcbStructInfo
= bytesNeeded
;
2713 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2714 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2716 CRYPT_DATA_BLOB
*blob
;
2718 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2719 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2720 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2721 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2722 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2723 lpszStructType
, pbEncoded
, cbEncoded
,
2724 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2731 SetLastError(STATUS_ACCESS_VIOLATION
);
2738 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2739 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2740 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2744 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2745 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2747 if (pbEncoded
[0] == ASN_BITSTRING
)
2749 DWORD bytesNeeded
, dataLen
;
2751 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2753 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2754 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2756 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2758 *pcbStructInfo
= bytesNeeded
;
2759 else if (*pcbStructInfo
< bytesNeeded
)
2761 *pcbStructInfo
= bytesNeeded
;
2762 SetLastError(ERROR_MORE_DATA
);
2767 CRYPT_BIT_BLOB
*blob
;
2769 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2770 blob
->cbData
= dataLen
- 1;
2771 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2772 GET_LEN_BYTES(pbEncoded
[1]));
2773 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2775 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2776 GET_LEN_BYTES(pbEncoded
[1]);
2780 assert(blob
->pbData
);
2783 BYTE mask
= 0xff << blob
->cUnusedBits
;
2785 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2786 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2787 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2795 SetLastError(CRYPT_E_ASN1_BADTAG
);
2798 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2802 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2803 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2804 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2808 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2809 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2815 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2816 lpszStructType
, pbEncoded
, cbEncoded
,
2817 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2820 *pcbStructInfo
= bytesNeeded
;
2821 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2822 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2824 CRYPT_BIT_BLOB
*blob
;
2826 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2827 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2828 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2829 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2830 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2831 lpszStructType
, pbEncoded
, cbEncoded
,
2832 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2839 SetLastError(STATUS_ACCESS_VIOLATION
);
2843 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2847 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2848 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2849 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2855 *pcbStructInfo
= sizeof(int);
2860 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2861 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2862 DWORD size
= sizeof(buf
);
2864 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2865 if (pbEncoded
[0] != ASN_INTEGER
)
2867 SetLastError(CRYPT_E_ASN1_BADTAG
);
2871 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2872 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
,
2876 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2877 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2881 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2882 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2883 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2885 /* initialize to a negative value to sign-extend */
2890 for (i
= 0; i
< blob
->cbData
; i
++)
2893 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2895 memcpy(pvStructInfo
, &val
, sizeof(int));
2898 else if (GetLastError() == ERROR_MORE_DATA
)
2899 SetLastError(CRYPT_E_ASN1_LARGE
);
2903 SetLastError(STATUS_ACCESS_VIOLATION
);
2910 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2911 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2912 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2915 DWORD bytesNeeded
, dataLen
;
2917 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2919 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2921 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2923 *pcbStructInfo
= bytesNeeded
;
2924 else if (*pcbStructInfo
< bytesNeeded
)
2926 *pcbStructInfo
= bytesNeeded
;
2927 SetLastError(ERROR_MORE_DATA
);
2932 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2934 blob
->cbData
= dataLen
;
2935 assert(blob
->pbData
);
2940 for (i
= 0; i
< blob
->cbData
; i
++)
2942 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2951 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
2952 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2953 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2961 if (pbEncoded
[0] != ASN_INTEGER
)
2963 SetLastError(CRYPT_E_ASN1_BADTAG
);
2967 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2968 lpszStructType
, pbEncoded
, cbEncoded
,
2969 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
);
2973 *pcbStructInfo
= bytesNeeded
;
2974 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2975 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2977 CRYPT_INTEGER_BLOB
*blob
;
2979 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2980 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2981 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2982 blob
->pbData
= (BYTE
*)pvStructInfo
+
2983 sizeof(CRYPT_INTEGER_BLOB
);
2984 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2985 lpszStructType
, pbEncoded
, cbEncoded
,
2986 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2993 SetLastError(STATUS_ACCESS_VIOLATION
);
3000 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
3001 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3002 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3003 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3007 if (pbEncoded
[0] == ASN_INTEGER
)
3009 DWORD bytesNeeded
, dataLen
;
3011 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3013 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3015 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3017 *pcbStructInfo
= bytesNeeded
;
3018 else if (*pcbStructInfo
< bytesNeeded
)
3020 *pcbStructInfo
= bytesNeeded
;
3021 SetLastError(ERROR_MORE_DATA
);
3026 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3028 blob
->cbData
= dataLen
;
3029 assert(blob
->pbData
);
3030 /* remove leading zero byte if it exists */
3031 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3040 for (i
= 0; i
< blob
->cbData
; i
++)
3042 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3051 SetLastError(CRYPT_E_ASN1_BADTAG
);
3057 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3058 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3059 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3067 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3068 lpszStructType
, pbEncoded
, cbEncoded
,
3069 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
3072 *pcbStructInfo
= bytesNeeded
;
3073 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3074 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3076 CRYPT_INTEGER_BLOB
*blob
;
3078 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3079 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3080 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3081 blob
->pbData
= (BYTE
*)pvStructInfo
+
3082 sizeof(CRYPT_INTEGER_BLOB
);
3083 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3084 lpszStructType
, pbEncoded
, cbEncoded
,
3085 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3092 SetLastError(STATUS_ACCESS_VIOLATION
);
3099 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3100 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3101 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3107 *pcbStructInfo
= sizeof(int);
3112 if (pbEncoded
[0] == ASN_ENUMERATED
)
3114 unsigned int val
= 0, i
;
3118 SetLastError(CRYPT_E_ASN1_EOD
);
3121 else if (pbEncoded
[1] == 0)
3123 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3128 /* A little strange looking, but we have to accept a sign byte:
3129 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3130 * assuming a small length is okay here, it has to be in short
3133 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3135 SetLastError(CRYPT_E_ASN1_LARGE
);
3138 for (i
= 0; i
< pbEncoded
[1]; i
++)
3141 val
|= pbEncoded
[2 + i
];
3143 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3144 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3146 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3147 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3148 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3154 SetLastError(CRYPT_E_ASN1_BADTAG
);
3160 SetLastError(STATUS_ACCESS_VIOLATION
);
3167 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3170 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3175 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3177 if (!isdigit(*(pbEncoded))) \
3179 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3185 (word) += *(pbEncoded)++ - '0'; \
3190 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3191 SYSTEMTIME
*sysTime
)
3198 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3200 WORD hours
, minutes
= 0;
3201 BYTE sign
= *pbEncoded
++;
3204 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3205 if (ret
&& hours
>= 24)
3207 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3212 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3213 if (ret
&& minutes
>= 60)
3215 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3223 sysTime
->wHour
+= hours
;
3224 sysTime
->wMinute
+= minutes
;
3228 if (hours
> sysTime
->wHour
)
3231 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3234 sysTime
->wHour
-= hours
;
3235 if (minutes
> sysTime
->wMinute
)
3238 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3241 sysTime
->wMinute
-= minutes
;
3248 SetLastError(STATUS_ACCESS_VIOLATION
);
3255 #define MIN_ENCODED_TIME_LENGTH 10
3257 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3258 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3259 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3265 *pcbStructInfo
= sizeof(FILETIME
);
3271 if (pbEncoded
[0] == ASN_UTCTIME
)
3275 SetLastError(CRYPT_E_ASN1_EOD
);
3278 else if (pbEncoded
[1] > 0x7f)
3280 /* long-form date strings really can't be valid */
3281 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3286 SYSTEMTIME sysTime
= { 0 };
3287 BYTE len
= pbEncoded
[1];
3289 if (len
< MIN_ENCODED_TIME_LENGTH
)
3291 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3297 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3298 if (sysTime
.wYear
>= 50)
3299 sysTime
.wYear
+= 1900;
3301 sysTime
.wYear
+= 2000;
3302 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3303 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3304 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3305 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3308 if (len
>= 2 && isdigit(*pbEncoded
) &&
3309 isdigit(*(pbEncoded
+ 1)))
3310 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3312 else if (isdigit(*pbEncoded
))
3313 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3316 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3319 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3320 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3323 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3324 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3325 ret
= SystemTimeToFileTime(&sysTime
,
3326 (FILETIME
*)pvStructInfo
);
3333 SetLastError(CRYPT_E_ASN1_BADTAG
);
3339 SetLastError(STATUS_ACCESS_VIOLATION
);
3346 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
3347 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3348 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3354 *pcbStructInfo
= sizeof(FILETIME
);
3360 if (pbEncoded
[0] == ASN_GENERALTIME
)
3364 SetLastError(CRYPT_E_ASN1_EOD
);
3367 else if (pbEncoded
[1] > 0x7f)
3369 /* long-form date strings really can't be valid */
3370 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3375 BYTE len
= pbEncoded
[1];
3377 if (len
< MIN_ENCODED_TIME_LENGTH
)
3379 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3384 SYSTEMTIME sysTime
= { 0 };
3387 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3388 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3389 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3390 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3393 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3396 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3398 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3405 /* workaround macro weirdness */
3406 digits
= min(len
, 3);
3407 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3408 sysTime
.wMilliseconds
);
3411 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3414 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3415 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3418 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3419 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3420 ret
= SystemTimeToFileTime(&sysTime
,
3421 (FILETIME
*)pvStructInfo
);
3428 SetLastError(CRYPT_E_ASN1_BADTAG
);
3434 SetLastError(STATUS_ACCESS_VIOLATION
);
3441 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3442 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3443 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3449 if (pbEncoded
[0] == ASN_UTCTIME
)
3450 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
3451 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3453 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3454 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
3455 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
3456 pvStructInfo
, pcbStructInfo
);
3459 SetLastError(CRYPT_E_ASN1_BADTAG
);
3465 SetLastError(STATUS_ACCESS_VIOLATION
);
3472 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3473 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3474 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3480 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3482 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3484 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3489 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3490 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3492 ptr
= pbEncoded
+ 1 + lenBytes
;
3493 remainingLen
= dataLen
;
3494 while (ret
&& remainingLen
)
3498 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3501 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3503 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3504 ptr
+= 1 + nextLenBytes
+ nextLen
;
3505 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3506 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3507 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3513 CRYPT_SEQUENCE_OF_ANY
*seq
;
3517 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3518 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3520 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3521 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3522 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3523 seq
->cValue
= cValue
;
3524 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3526 nextPtr
= (BYTE
*)seq
->rgValue
+
3527 cValue
* sizeof(CRYPT_DER_BLOB
);
3528 ptr
= pbEncoded
+ 1 + lenBytes
;
3529 remainingLen
= dataLen
;
3531 while (ret
&& remainingLen
)
3535 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3538 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3540 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3542 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3543 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3546 seq
->rgValue
[i
].pbData
= nextPtr
;
3547 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3549 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3551 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3552 ptr
+= 1 + nextLenBytes
+ nextLen
;
3562 SetLastError(CRYPT_E_ASN1_BADTAG
);
3568 SetLastError(STATUS_ACCESS_VIOLATION
);
3575 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3576 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3577 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3581 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3583 DWORD bytesNeeded
, dataLen
;
3585 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3587 struct AsnArrayDescriptor arrayDesc
= {
3588 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3589 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3590 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3591 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3597 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3598 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3599 0, NULL
, NULL
, &nameLen
, NULL
);
3600 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3603 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3605 *pcbStructInfo
= bytesNeeded
;
3606 else if (*pcbStructInfo
< bytesNeeded
)
3608 *pcbStructInfo
= bytesNeeded
;
3609 SetLastError(ERROR_MORE_DATA
);
3614 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3618 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3619 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3620 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3621 0, NULL
, &name
->u
.FullName
, pcbStructInfo
,
3622 name
->u
.FullName
.rgAltEntry
);
3625 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3631 SetLastError(CRYPT_E_ASN1_BADTAG
);
3637 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
3638 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3639 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3641 struct AsnDecodeSequenceItem items
[] = {
3642 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3643 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3644 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3645 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3646 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3647 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3648 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3649 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3650 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3651 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3655 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3656 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3657 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3661 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3662 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3663 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3667 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3668 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3672 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3673 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3674 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3676 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3677 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3681 SetLastError(STATUS_ACCESS_VIOLATION
);
3688 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3689 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3690 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3694 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3695 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3699 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3700 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3702 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3703 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3707 SetLastError(STATUS_ACCESS_VIOLATION
);
3714 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3715 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3716 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3720 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3721 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3725 struct AsnDecodeSequenceItem items
[] = {
3726 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3727 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3728 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3729 offsetof(CRL_ISSUING_DIST_POINT
,
3730 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3731 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3732 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3734 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
3735 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3737 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
3738 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
3739 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
3740 OnlySomeReasonFlags
.pbData
), 0 },
3741 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
3742 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
3745 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3746 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3747 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3751 SetLastError(STATUS_ACCESS_VIOLATION
);
3758 static BOOL WINAPI
CRYPT_AsnDecodeIssuerSerialNumber(DWORD dwCertEncodingType
,
3759 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3760 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3763 struct AsnDecodeSequenceItem items
[] = {
3764 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
3765 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
3767 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
3768 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
3769 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
3771 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
3772 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
3774 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3775 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3777 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3778 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3779 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
3780 issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
3781 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
3783 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3786 TRACE("returning %d\n", ret
);
3790 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
3791 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3792 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3796 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3797 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3801 struct AsnDecodeSequenceItem items
[] = {
3802 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
3803 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3804 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
3805 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
3806 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
3807 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
3808 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3809 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
3810 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
3811 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3812 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
3813 HashEncryptionAlgorithm
.pszObjId
), 0 },
3814 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
3815 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3816 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
3817 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
3818 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3819 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
3820 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
3821 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
3822 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
3825 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3826 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3827 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3831 SetLastError(STATUS_ACCESS_VIOLATION
);
3834 TRACE("returning %d\n", ret
);
3838 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
3839 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3840 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3842 static HCRYPTOIDFUNCSET set
= NULL
;
3844 CryptDecodeObjectExFunc decodeFunc
= NULL
;
3845 HCRYPTOIDFUNCADDR hFunc
= NULL
;
3847 TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
3848 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
3849 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3851 if (!pvStructInfo
&& !pcbStructInfo
)
3853 SetLastError(ERROR_INVALID_PARAMETER
);
3856 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
3857 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
3859 SetLastError(ERROR_FILE_NOT_FOUND
);
3864 SetLastError(CRYPT_E_ASN1_EOD
);
3867 if (cbEncoded
> MAX_ENCODED_LEN
)
3869 SetLastError(CRYPT_E_ASN1_LARGE
);
3873 SetLastError(NOERROR
);
3874 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
3875 *(BYTE
**)pvStructInfo
= NULL
;
3876 if (!HIWORD(lpszStructType
))
3878 switch (LOWORD(lpszStructType
))
3880 case (WORD
)X509_CERT
:
3881 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
3883 case (WORD
)X509_CERT_TO_BE_SIGNED
:
3884 decodeFunc
= CRYPT_AsnDecodeCert
;
3886 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
3887 decodeFunc
= CRYPT_AsnDecodeCRL
;
3889 case (WORD
)X509_EXTENSIONS
:
3890 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3892 case (WORD
)X509_NAME_VALUE
:
3893 decodeFunc
= CRYPT_AsnDecodeNameValue
;
3895 case (WORD
)X509_NAME
:
3896 decodeFunc
= CRYPT_AsnDecodeName
;
3898 case (WORD
)X509_PUBLIC_KEY_INFO
:
3899 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
3901 case (WORD
)X509_AUTHORITY_KEY_ID
:
3902 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3904 case (WORD
)X509_ALTERNATE_NAME
:
3905 decodeFunc
= CRYPT_AsnDecodeAltName
;
3907 case (WORD
)X509_BASIC_CONSTRAINTS
:
3908 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3910 case (WORD
)X509_BASIC_CONSTRAINTS2
:
3911 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3913 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
3914 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
3916 case (WORD
)X509_UNICODE_NAME
:
3917 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
3919 case (WORD
)PKCS_ATTRIBUTE
:
3920 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
3922 case (WORD
)X509_UNICODE_NAME_VALUE
:
3923 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
3925 case (WORD
)X509_OCTET_STRING
:
3926 decodeFunc
= CRYPT_AsnDecodeOctets
;
3928 case (WORD
)X509_BITS
:
3929 case (WORD
)X509_KEY_USAGE
:
3930 decodeFunc
= CRYPT_AsnDecodeBits
;
3932 case (WORD
)X509_INTEGER
:
3933 decodeFunc
= CRYPT_AsnDecodeInt
;
3935 case (WORD
)X509_MULTI_BYTE_INTEGER
:
3936 decodeFunc
= CRYPT_AsnDecodeInteger
;
3938 case (WORD
)X509_MULTI_BYTE_UINT
:
3939 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
3941 case (WORD
)X509_ENUMERATED
:
3942 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3944 case (WORD
)X509_CHOICE_OF_TIME
:
3945 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
3947 case (WORD
)X509_AUTHORITY_KEY_ID2
:
3948 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
3950 case (WORD
)PKCS_CONTENT_INFO
:
3951 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
3953 case (WORD
)X509_SEQUENCE_OF_ANY
:
3954 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
3956 case (WORD
)PKCS_UTC_TIME
:
3957 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3959 case (WORD
)X509_CRL_DIST_POINTS
:
3960 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3962 case (WORD
)X509_ENHANCED_KEY_USAGE
:
3963 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3965 case (WORD
)PKCS_ATTRIBUTES
:
3966 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
3968 case (WORD
)X509_ISSUING_DIST_POINT
:
3969 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3971 case (WORD
)PKCS7_SIGNER_INFO
:
3972 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
3975 FIXME("%d: unimplemented\n", LOWORD(lpszStructType
));
3978 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
3979 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3980 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
3981 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3982 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
3983 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3984 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
3985 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
3986 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
3987 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3988 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
3989 decodeFunc
= CRYPT_AsnDecodeBits
;
3990 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
3991 decodeFunc
= CRYPT_AsnDecodeOctets
;
3992 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
3993 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3994 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
3995 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3996 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
3997 decodeFunc
= CRYPT_AsnDecodeAltName
;
3998 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
3999 decodeFunc
= CRYPT_AsnDecodeAltName
;
4000 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4001 decodeFunc
= CRYPT_AsnDecodeAltName
;
4002 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4003 decodeFunc
= CRYPT_AsnDecodeAltName
;
4004 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4005 decodeFunc
= CRYPT_AsnDecodeAltName
;
4006 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4007 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4008 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4009 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4010 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4011 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4013 TRACE("OID %s not found or unimplemented, looking for DLL\n",
4014 debugstr_a(lpszStructType
));
4018 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4019 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4020 (void **)&decodeFunc
, &hFunc
);
4023 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
4024 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4026 SetLastError(ERROR_FILE_NOT_FOUND
);
4028 CryptFreeOIDFunctionAddress(hFunc
, 0);