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, minSize:
282 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
283 * the offset within the (outer) 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 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
301 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
302 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
)
308 ptr
= pbEncoded
+ 1 + GET_LEN_BYTES(pbEncoded
[1]);
309 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
311 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
315 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
318 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
320 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
322 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
324 TRACE("Setting next pointer to %p\n",
326 *(BYTE
**)((BYTE
*)pvStructInfo
+
327 items
[i
].pointerOffset
) = nextData
;
329 if (items
[i
].decodeFunc
)
332 TRACE("decoding item %d\n", i
);
334 TRACE("sizing item %d\n", i
);
335 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
336 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
337 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
338 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
339 : NULL
, &items
[i
].size
);
342 if (nextData
&& items
[i
].hasPointer
&&
343 items
[i
].size
> items
[i
].minSize
)
345 nextData
+= items
[i
].size
- items
[i
].minSize
;
346 /* align nextData to DWORD boundaries */
347 if (items
[i
].size
% sizeof(DWORD
))
348 nextData
+= sizeof(DWORD
) - items
[i
].size
%
351 /* Account for alignment padding */
352 if (items
[i
].size
% sizeof(DWORD
))
353 items
[i
].size
+= sizeof(DWORD
) -
354 items
[i
].size
% sizeof(DWORD
);
355 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
357 else if (items
[i
].optional
&&
358 GetLastError() == CRYPT_E_ASN1_BADTAG
)
360 TRACE("skipping optional item %d\n", i
);
361 items
[i
].size
= items
[i
].minSize
;
362 SetLastError(NOERROR
);
366 TRACE("item %d failed: %08x\n", i
,
370 items
[i
].size
= items
[i
].minSize
;
372 else if (items
[i
].optional
)
374 TRACE("skipping optional item %d\n", i
);
375 items
[i
].size
= items
[i
].minSize
;
379 TRACE("tag %02x doesn't match expected %02x\n",
380 ptr
[0], items
[i
].tag
);
381 SetLastError(CRYPT_E_ASN1_BADTAG
);
386 else if (items
[i
].optional
)
388 TRACE("missing optional item %d, skipping\n", i
);
389 items
[i
].size
= items
[i
].minSize
;
393 TRACE("not enough bytes for item %d, failing\n", i
);
394 SetLastError(CRYPT_E_ASN1_CORRUPT
);
398 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
400 TRACE("%d remaining bytes, failing\n", cbEncoded
-
402 SetLastError(CRYPT_E_ASN1_CORRUPT
);
408 /* This decodes an arbitrary sequence into a contiguous block of memory
409 * (basically, a struct.) Each element being decoded is described by a struct
410 * AsnDecodeSequenceItem, see above.
411 * startingPointer is an optional pointer to the first place where dynamic
412 * data will be stored. If you know the starting offset, you may pass it
413 * here. Otherwise, pass NULL, and one will be inferred from the items.
414 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
415 * If any undecoded data are left over, fails with CRYPT_E_ASN1_CORRUPT.
417 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
418 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
419 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
420 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
424 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
425 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
428 if (pbEncoded
[0] == ASN_SEQUENCE
)
432 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
436 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, pbEncoded
,
437 cbEncoded
, dwFlags
, NULL
, NULL
);
440 DWORD bytesNeeded
= 0, structSize
= 0;
442 for (i
= 0; i
< cItem
; i
++)
444 bytesNeeded
+= items
[i
].size
;
445 structSize
+= items
[i
].minSize
;
448 *pcbStructInfo
= bytesNeeded
;
449 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
450 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
454 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
455 pvStructInfo
= *(BYTE
**)pvStructInfo
;
457 nextData
= (BYTE
*)startingPointer
;
459 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
460 memset(pvStructInfo
, 0, structSize
);
461 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
462 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
);
469 SetLastError(CRYPT_E_ASN1_BADTAG
);
472 TRACE("returning %d (%08x)\n", ret
, GetLastError());
477 * The expected tag of the entire encoded array (usually a variant
478 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
479 * regardless of the tag seen.
481 * used to decode each item in the array
483 * is the minimum size of each decoded item
485 * indicates whether each item has a dynamic pointer
487 * indicates the offset within itemSize at which the pointer exists
489 struct AsnArrayDescriptor
492 CryptDecodeObjectExFunc decodeFunc
;
498 struct AsnArrayItemSize
504 /* Decodes an array of like types into a struct GenericArray.
505 * The layout and decoding of the array are described by a struct
506 * AsnArrayDescriptor.
508 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
509 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
510 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
511 void *startingPointer
)
515 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
516 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
519 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
523 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
525 DWORD bytesNeeded
, cItems
= 0;
526 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
527 /* There can be arbitrarily many items, but there is often only one.
529 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
531 bytesNeeded
= sizeof(struct GenericArray
);
536 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
537 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
539 DWORD itemLenBytes
, itemDataLen
, size
= 0;
541 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
542 /* Each item decoded may not tolerate extraneous bytes, so
543 * get the length of the next element and pass it directly.
545 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
548 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
549 1 + itemLenBytes
+ itemDataLen
,
550 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
557 if (itemSizes
!= &itemSize
)
558 itemSizes
= CryptMemRealloc(itemSizes
,
559 cItems
* sizeof(struct AsnArrayItemSize
));
564 cItems
* sizeof(struct AsnArrayItemSize
));
566 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
570 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
572 itemSizes
[cItems
- 1].size
= size
;
574 ret
= CRYPT_GetLen(ptr
,
575 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
577 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
587 *pcbStructInfo
= bytesNeeded
;
588 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
589 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
594 struct GenericArray
*array
;
596 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
597 pvStructInfo
= *(BYTE
**)pvStructInfo
;
598 array
= (struct GenericArray
*)pvStructInfo
;
599 array
->cItems
= cItems
;
601 array
->rgItems
= startingPointer
;
603 array
->rgItems
= (BYTE
*)array
+
604 sizeof(struct GenericArray
);
605 nextData
= (BYTE
*)array
->rgItems
+
606 array
->cItems
* arrayDesc
->itemSize
;
607 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
608 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
611 if (arrayDesc
->hasPointer
)
612 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
613 + arrayDesc
->pointerOffset
) = nextData
;
614 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
615 itemSizes
[i
].encodedLen
,
616 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
617 array
->rgItems
+ i
* arrayDesc
->itemSize
,
623 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
624 ret
= CRYPT_GetLen(ptr
,
625 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
627 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
632 if (itemSizes
!= &itemSize
)
633 CryptMemFree(itemSizes
);
638 SetLastError(CRYPT_E_ASN1_BADTAG
);
644 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
645 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
646 * to CRYPT_E_ASN1_CORRUPT.
647 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
650 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
651 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
652 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
657 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
659 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
660 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
662 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
663 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
666 *pcbStructInfo
= bytesNeeded
;
667 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
668 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
670 CRYPT_DER_BLOB
*blob
;
672 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
673 pvStructInfo
= *(BYTE
**)pvStructInfo
;
674 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
675 blob
->cbData
= 1 + lenBytes
+ dataLen
;
678 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
679 blob
->pbData
= (BYTE
*)pbEncoded
;
682 assert(blob
->pbData
);
683 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
688 SetLastError(CRYPT_E_ASN1_CORRUPT
);
696 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
697 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
698 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
699 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
703 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
704 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
706 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
709 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
710 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
711 pvStructInfo
, pcbStructInfo
);
712 if (ret
&& pvStructInfo
)
714 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
721 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
723 temp
= blob
->pbData
[i
];
724 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
725 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
729 TRACE("returning %d (%08x)\n", ret
, GetLastError());
733 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
734 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
735 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
739 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
740 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
744 struct AsnDecodeSequenceItem items
[] = {
745 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
746 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
747 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
748 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
749 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
750 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
751 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
752 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
753 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
754 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
757 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
758 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
759 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
760 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
761 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
765 SetLastError(STATUS_ACCESS_VIOLATION
);
770 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
774 /* Internal function */
775 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
776 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
777 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
782 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
784 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
786 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
787 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
788 pvStructInfo
, pcbStructInfo
);
793 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
794 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
795 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
799 struct AsnDecodeSequenceItem items
[] = {
800 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
801 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
802 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
803 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
806 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
807 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
808 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
812 /* Internal function */
813 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
814 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
815 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
820 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
822 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
824 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
825 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
826 pDecodePara
, pvStructInfo
, pcbStructInfo
);
831 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
832 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
833 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
836 struct AsnDecodeSequenceItem items
[] = {
837 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
838 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
839 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
840 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
841 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
842 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
843 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
844 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
845 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
846 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
848 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
849 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
851 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
852 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
854 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
855 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
856 FALSE
, TRUE
, offsetof(CERT_INFO
,
857 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
858 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
859 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
860 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
861 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
862 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
863 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
864 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
865 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
866 offsetof(CERT_INFO
, rgExtension
), 0 },
869 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
870 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
872 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
873 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
874 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
876 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
880 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
881 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
882 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
886 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
887 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
891 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
894 /* First try to decode it as a signed cert. */
895 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
896 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
897 (BYTE
*)&signedCert
, &size
);
901 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
902 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
903 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
, pvStructInfo
,
905 LocalFree(signedCert
);
907 /* Failing that, try it as an unsigned cert */
911 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
912 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
913 pDecodePara
, pvStructInfo
, pcbStructInfo
);
918 SetLastError(STATUS_ACCESS_VIOLATION
);
923 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
927 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
928 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
929 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
932 struct AsnDecodeSequenceItem items
[] = {
933 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
934 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
935 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
936 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
937 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
938 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
939 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
940 offsetof(CRL_ENTRY
, rgExtension
), 0 },
942 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
944 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
947 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
948 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
949 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
953 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
954 * been set prior to calling.
956 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
957 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
958 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
961 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
962 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
963 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
964 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
966 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
967 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
969 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
970 pDecodePara
, pvStructInfo
, pcbStructInfo
,
971 entries
? entries
->rgItems
: NULL
);
972 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
976 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
977 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
978 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
980 struct AsnDecodeSequenceItem items
[] = {
981 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
982 CRYPT_AsnDecodeInt
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
983 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
984 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
985 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
986 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
987 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
989 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
990 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
991 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
992 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
993 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
994 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
995 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
996 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
997 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
998 offsetof(CRL_INFO
, rgExtension
), 0 },
1002 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1003 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1005 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1006 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1007 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1009 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1013 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1014 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1015 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1019 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1020 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1024 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1027 /* First try to decode it as a signed crl. */
1028 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
1029 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1030 (BYTE
*)&signedCrl
, &size
);
1034 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1035 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1036 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1037 pvStructInfo
, pcbStructInfo
);
1038 LocalFree(signedCrl
);
1040 /* Failing that, try it as an unsigned crl */
1044 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1045 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1046 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1051 SetLastError(STATUS_ACCESS_VIOLATION
);
1056 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1060 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
1061 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1062 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1066 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1067 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1069 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1073 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1075 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1076 DWORD bytesNeeded
= sizeof(LPSTR
);
1080 /* The largest possible string for the first two components
1081 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1086 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1087 pbEncoded
[1 + lenBytes
] / 40,
1088 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1090 bytesNeeded
+= strlen(firstTwo
) + 1;
1091 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1092 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1094 /* large enough for ".4000000" */
1098 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1105 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1108 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1115 snprintf(str
, sizeof(str
), ".%d", val
);
1116 bytesNeeded
+= strlen(str
);
1121 *pcbStructInfo
= bytesNeeded
;
1122 else if (*pcbStructInfo
< bytesNeeded
)
1124 *pcbStructInfo
= bytesNeeded
;
1125 SetLastError(ERROR_MORE_DATA
);
1133 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1136 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1137 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1139 pszObjId
+= strlen(pszObjId
);
1140 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1141 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1145 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1154 sprintf(pszObjId
, ".%d", val
);
1155 pszObjId
+= strlen(pszObjId
);
1159 *(LPSTR
*)pvStructInfo
= NULL
;
1160 *pcbStructInfo
= bytesNeeded
;
1167 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1170 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1171 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1172 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1174 struct AsnDecodeSequenceItem items
[] = {
1175 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1176 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1177 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1178 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1179 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1180 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1181 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1182 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1185 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1187 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1191 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1192 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1193 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1194 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1196 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1197 debugstr_a(ext
->pszObjId
));
1198 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1202 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1203 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1204 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1207 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1208 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1209 offsetof(CERT_EXTENSION
, pszObjId
) };
1210 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1212 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1213 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1215 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1216 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1220 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1221 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1222 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1228 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1229 lpszStructType
, pbEncoded
, cbEncoded
,
1230 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1231 if (ret
&& pvStructInfo
)
1233 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1234 pcbStructInfo
, *pcbStructInfo
);
1237 CERT_EXTENSIONS
*exts
;
1239 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1240 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1241 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1242 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1243 sizeof(CERT_EXTENSIONS
));
1244 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1245 lpszStructType
, pbEncoded
, cbEncoded
,
1246 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1253 SetLastError(STATUS_ACCESS_VIOLATION
);
1260 /* Warning: this assumes the address of value->Value.pbData is already set, in
1261 * order to avoid overwriting memory. (In some cases, it may change it, if it
1262 * doesn't copy anything to memory.) Be sure to set it correctly!
1264 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1265 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1266 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1270 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1272 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1274 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1275 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1277 switch (pbEncoded
[0])
1279 case ASN_OCTETSTRING
:
1280 valueType
= CERT_RDN_OCTET_STRING
;
1281 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1282 bytesNeeded
+= dataLen
;
1284 case ASN_NUMERICSTRING
:
1285 valueType
= CERT_RDN_NUMERIC_STRING
;
1286 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1287 bytesNeeded
+= dataLen
;
1289 case ASN_PRINTABLESTRING
:
1290 valueType
= CERT_RDN_PRINTABLE_STRING
;
1291 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1292 bytesNeeded
+= dataLen
;
1295 valueType
= CERT_RDN_IA5_STRING
;
1296 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1297 bytesNeeded
+= dataLen
;
1300 valueType
= CERT_RDN_T61_STRING
;
1301 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1302 bytesNeeded
+= dataLen
;
1304 case ASN_VIDEOTEXSTRING
:
1305 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1306 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1307 bytesNeeded
+= dataLen
;
1309 case ASN_GRAPHICSTRING
:
1310 valueType
= CERT_RDN_GRAPHIC_STRING
;
1311 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1312 bytesNeeded
+= dataLen
;
1314 case ASN_VISIBLESTRING
:
1315 valueType
= CERT_RDN_VISIBLE_STRING
;
1316 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1317 bytesNeeded
+= dataLen
;
1319 case ASN_GENERALSTRING
:
1320 valueType
= CERT_RDN_GENERAL_STRING
;
1321 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1322 bytesNeeded
+= dataLen
;
1324 case ASN_UNIVERSALSTRING
:
1325 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1326 SetLastError(CRYPT_E_ASN1_BADTAG
);
1329 valueType
= CERT_RDN_BMP_STRING
;
1330 bytesNeeded
+= dataLen
;
1332 case ASN_UTF8STRING
:
1333 valueType
= CERT_RDN_UTF8_STRING
;
1334 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1335 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1338 SetLastError(CRYPT_E_ASN1_BADTAG
);
1343 *pcbStructInfo
= bytesNeeded
;
1344 else if (*pcbStructInfo
< bytesNeeded
)
1346 *pcbStructInfo
= bytesNeeded
;
1347 SetLastError(ERROR_MORE_DATA
);
1352 *pcbStructInfo
= bytesNeeded
;
1353 value
->dwValueType
= valueType
;
1358 assert(value
->Value
.pbData
);
1359 switch (pbEncoded
[0])
1361 case ASN_OCTETSTRING
:
1362 case ASN_NUMERICSTRING
:
1363 case ASN_PRINTABLESTRING
:
1366 case ASN_VIDEOTEXSTRING
:
1367 case ASN_GRAPHICSTRING
:
1368 case ASN_VISIBLESTRING
:
1369 case ASN_GENERALSTRING
:
1370 value
->Value
.cbData
= dataLen
;
1373 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1374 memcpy(value
->Value
.pbData
,
1375 pbEncoded
+ 1 + lenBytes
, dataLen
);
1377 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1383 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1385 value
->Value
.cbData
= dataLen
;
1386 for (i
= 0; i
< dataLen
/ 2; i
++)
1387 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1388 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1391 case ASN_UTF8STRING
:
1393 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1395 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1396 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1397 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1404 value
->Value
.cbData
= 0;
1405 value
->Value
.pbData
= NULL
;
1412 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1413 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1414 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1420 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1421 lpszStructType
, pbEncoded
, cbEncoded
,
1422 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1423 if (ret
&& pvStructInfo
)
1425 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1426 pcbStructInfo
, *pcbStructInfo
);
1429 CERT_NAME_VALUE
*value
;
1431 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1432 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1433 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1434 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1435 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1436 lpszStructType
, pbEncoded
, cbEncoded
,
1437 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1444 SetLastError(STATUS_ACCESS_VIOLATION
);
1451 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1452 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1453 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1454 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1458 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1460 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1462 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1463 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1465 switch (pbEncoded
[0])
1467 case ASN_NUMERICSTRING
:
1468 valueType
= CERT_RDN_NUMERIC_STRING
;
1469 bytesNeeded
+= dataLen
* 2;
1471 case ASN_PRINTABLESTRING
:
1472 valueType
= CERT_RDN_PRINTABLE_STRING
;
1473 bytesNeeded
+= dataLen
* 2;
1476 valueType
= CERT_RDN_IA5_STRING
;
1477 bytesNeeded
+= dataLen
* 2;
1480 valueType
= CERT_RDN_T61_STRING
;
1481 bytesNeeded
+= dataLen
* 2;
1483 case ASN_VIDEOTEXSTRING
:
1484 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1485 bytesNeeded
+= dataLen
* 2;
1487 case ASN_GRAPHICSTRING
:
1488 valueType
= CERT_RDN_GRAPHIC_STRING
;
1489 bytesNeeded
+= dataLen
* 2;
1491 case ASN_VISIBLESTRING
:
1492 valueType
= CERT_RDN_VISIBLE_STRING
;
1493 bytesNeeded
+= dataLen
* 2;
1495 case ASN_GENERALSTRING
:
1496 valueType
= CERT_RDN_GENERAL_STRING
;
1497 bytesNeeded
+= dataLen
* 2;
1499 case ASN_UNIVERSALSTRING
:
1500 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1501 bytesNeeded
+= dataLen
/ 2;
1504 valueType
= CERT_RDN_BMP_STRING
;
1505 bytesNeeded
+= dataLen
;
1507 case ASN_UTF8STRING
:
1508 valueType
= CERT_RDN_UTF8_STRING
;
1509 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1510 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1513 SetLastError(CRYPT_E_ASN1_BADTAG
);
1518 *pcbStructInfo
= bytesNeeded
;
1519 else if (*pcbStructInfo
< bytesNeeded
)
1521 *pcbStructInfo
= bytesNeeded
;
1522 SetLastError(ERROR_MORE_DATA
);
1527 *pcbStructInfo
= bytesNeeded
;
1528 value
->dwValueType
= valueType
;
1532 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1534 assert(value
->Value
.pbData
);
1535 switch (pbEncoded
[0])
1537 case ASN_NUMERICSTRING
:
1538 case ASN_PRINTABLESTRING
:
1541 case ASN_VIDEOTEXSTRING
:
1542 case ASN_GRAPHICSTRING
:
1543 case ASN_VISIBLESTRING
:
1544 case ASN_GENERALSTRING
:
1545 value
->Value
.cbData
= dataLen
* 2;
1546 for (i
= 0; i
< dataLen
; i
++)
1547 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1549 case ASN_UNIVERSALSTRING
:
1550 value
->Value
.cbData
= dataLen
/ 2;
1551 for (i
= 0; i
< dataLen
/ 4; i
++)
1552 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1553 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1556 value
->Value
.cbData
= dataLen
;
1557 for (i
= 0; i
< dataLen
/ 2; i
++)
1558 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1559 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1561 case ASN_UTF8STRING
:
1562 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1563 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1564 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1570 value
->Value
.cbData
= 0;
1571 value
->Value
.pbData
= NULL
;
1578 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1579 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1580 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1586 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1587 lpszStructType
, pbEncoded
, cbEncoded
,
1588 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1589 if (ret
&& pvStructInfo
)
1591 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1592 pcbStructInfo
, *pcbStructInfo
);
1595 CERT_NAME_VALUE
*value
;
1597 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1598 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1599 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1600 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1601 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1602 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1603 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1610 SetLastError(STATUS_ACCESS_VIOLATION
);
1617 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1618 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1619 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1622 struct AsnDecodeSequenceItem items
[] = {
1623 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1624 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1625 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1626 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1627 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1628 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1630 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1632 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1633 pvStructInfo
, *pcbStructInfo
);
1636 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1637 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1638 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1639 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1642 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1643 debugstr_a(attr
->pszObjId
));
1644 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1646 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1650 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1651 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1652 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1655 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1656 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1657 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1658 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1660 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1661 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1665 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1666 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1667 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1673 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1674 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1675 offsetof(CERT_RDN
, rgRDNAttr
) };
1677 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1678 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1682 SetLastError(STATUS_ACCESS_VIOLATION
);
1689 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType
,
1690 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1691 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1694 struct AsnDecodeSequenceItem items
[] = {
1695 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1696 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1697 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1698 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1699 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1700 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1702 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1704 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1705 pvStructInfo
, *pcbStructInfo
);
1708 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1709 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1710 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1711 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1714 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1715 debugstr_a(attr
->pszObjId
));
1716 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1718 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1722 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType
,
1723 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1724 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1727 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1728 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1729 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1730 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1732 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1733 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1737 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1738 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1739 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1745 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1746 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1747 offsetof(CERT_RDN
, rgRDNAttr
) };
1749 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1750 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1754 SetLastError(STATUS_ACCESS_VIOLATION
);
1761 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1762 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1763 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1766 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1768 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1769 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1771 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1772 bytesNeeded
+= cbEncoded
;
1774 *pcbStructInfo
= bytesNeeded
;
1775 else if (*pcbStructInfo
< bytesNeeded
)
1777 SetLastError(ERROR_MORE_DATA
);
1778 *pcbStructInfo
= bytesNeeded
;
1783 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1785 *pcbStructInfo
= bytesNeeded
;
1786 blob
->cbData
= cbEncoded
;
1787 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1788 blob
->pbData
= (LPBYTE
)pbEncoded
;
1791 assert(blob
->pbData
);
1792 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1798 static BOOL WINAPI
CRYPT_DecodeDERArray(DWORD dwCertEncodingType
,
1799 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1800 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1803 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1804 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
), TRUE
,
1805 offsetof(CRYPT_DER_BLOB
, pbData
) };
1806 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
1808 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1809 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1811 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1812 pDecodePara
, pvStructInfo
, pcbStructInfo
, array
? array
->rgItems
: NULL
);
1816 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
1817 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1818 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1824 struct AsnDecodeSequenceItem items
[] = {
1825 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
1826 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1827 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
1828 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
1829 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
1830 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
1832 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
1834 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1835 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1836 pDecodePara
, pvStructInfo
, pcbStructInfo
, attr
? attr
->pszObjId
:
1841 SetLastError(STATUS_ACCESS_VIOLATION
);
1844 TRACE("returning %d\n", ret
);
1848 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributesInternal(
1849 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1850 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1851 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1853 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1854 CRYPT_AsnDecodePKCSAttribute
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
1855 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
1856 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1859 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1860 pDecodePara
, pvStructInfo
, pcbStructInfo
, attrs
? attrs
->rgAttr
:
1865 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
1866 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1867 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1871 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1872 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1878 if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1879 lpszStructType
, pbEncoded
, cbEncoded
,
1880 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1883 *pcbStructInfo
= bytesNeeded
;
1884 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1885 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1887 PCRYPT_ATTRIBUTES attrs
;
1889 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1890 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1891 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1892 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
1893 sizeof(CRYPT_ATTRIBUTES
));
1894 ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1895 lpszStructType
, pbEncoded
, cbEncoded
,
1896 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1903 SetLastError(STATUS_ACCESS_VIOLATION
);
1906 TRACE("returning %d\n", ret
);
1910 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1911 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1912 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1914 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1915 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1917 struct AsnDecodeSequenceItem items
[] = {
1918 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1919 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1920 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1921 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1922 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1923 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1926 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1927 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1929 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1930 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1931 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1932 if (ret
&& pvStructInfo
)
1934 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1935 debugstr_a(algo
->pszObjId
));
1940 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1941 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1942 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1945 struct AsnDecodeSequenceItem items
[] = {
1946 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1947 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1948 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
1949 Algorithm
.pszObjId
) },
1950 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
1951 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1952 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
1954 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1956 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1957 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1958 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
1959 info
->Algorithm
.Parameters
.pbData
: NULL
);
1963 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
1964 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1965 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1973 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1974 lpszStructType
, pbEncoded
, cbEncoded
,
1975 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1978 *pcbStructInfo
= bytesNeeded
;
1979 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1980 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1982 PCERT_PUBLIC_KEY_INFO info
;
1984 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1985 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1986 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1987 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
1988 sizeof(CERT_PUBLIC_KEY_INFO
);
1989 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1990 lpszStructType
, pbEncoded
, cbEncoded
,
1991 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1998 SetLastError(STATUS_ACCESS_VIOLATION
);
2005 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
2006 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2007 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2013 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2016 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2018 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2021 if (pbEncoded
[1] > 1)
2023 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2028 *pcbStructInfo
= sizeof(BOOL
);
2031 else if (*pcbStructInfo
< sizeof(BOOL
))
2033 *pcbStructInfo
= sizeof(BOOL
);
2034 SetLastError(ERROR_MORE_DATA
);
2039 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2042 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2046 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
2047 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2048 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2050 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2051 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2054 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2055 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2059 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2062 if ((pbEncoded
[0] & ASN_FLAGS_MASK
) != ASN_CONTEXT
)
2064 SetLastError(CRYPT_E_ASN1_BADTAG
);
2067 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2068 if (1 + lenBytes
> cbEncoded
)
2070 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2073 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2075 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2077 case 1: /* rfc822Name */
2078 case 2: /* dNSName */
2079 case 6: /* uniformResourceIdentifier */
2080 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2082 case 7: /* iPAddress */
2083 bytesNeeded
+= dataLen
;
2085 case 8: /* registeredID */
2086 /* FIXME: decode as OID */
2087 case 0: /* otherName */
2088 case 4: /* directoryName */
2090 SetLastError(CRYPT_E_ASN1_BADTAG
);
2093 case 3: /* x400Address, unimplemented */
2094 case 5: /* ediPartyName, unimplemented */
2095 SetLastError(CRYPT_E_ASN1_BADTAG
);
2099 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2105 *pcbStructInfo
= bytesNeeded
;
2106 else if (*pcbStructInfo
< bytesNeeded
)
2108 *pcbStructInfo
= bytesNeeded
;
2109 SetLastError(ERROR_MORE_DATA
);
2114 *pcbStructInfo
= bytesNeeded
;
2115 /* MS used values one greater than the asn1 ones.. sigh */
2116 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2117 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2119 case 1: /* rfc822Name */
2120 case 2: /* dNSName */
2121 case 6: /* uniformResourceIdentifier */
2125 for (i
= 0; i
< dataLen
; i
++)
2126 entry
->u
.pwszURL
[i
] =
2127 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2128 entry
->u
.pwszURL
[i
] = 0;
2129 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2130 debugstr_w(entry
->u
.pwszURL
));
2133 case 7: /* iPAddress */
2134 /* The next data pointer is in the pwszURL spot, that is,
2135 * the first 4 bytes. Need to move it to the next spot.
2137 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2138 entry
->u
.IPAddress
.cbData
= dataLen
;
2139 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2149 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2150 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2151 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2154 struct AsnArrayDescriptor arrayDesc
= { 0,
2155 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2156 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2157 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2159 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2160 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2163 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2164 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2165 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
2169 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2170 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2171 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2177 struct AsnDecodeSequenceItem items
[] = {
2178 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2179 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2180 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2181 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2182 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2183 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2184 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2185 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2186 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2187 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2188 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2191 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2192 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2193 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2197 SetLastError(STATUS_ACCESS_VIOLATION
);
2204 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2205 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2206 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2212 struct AsnDecodeSequenceItem items
[] = {
2213 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2214 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2215 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2216 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2217 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2218 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2219 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2220 AuthorityCertIssuer
.rgAltEntry
), 0 },
2221 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2222 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2223 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2224 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2225 AuthorityCertSerialNumber
.pbData
), 0 },
2228 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2229 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2230 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2234 SetLastError(STATUS_ACCESS_VIOLATION
);
2241 static BOOL WINAPI
CRYPT_AsnDecodePKCSContent(DWORD dwCertEncodingType
,
2242 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2243 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2248 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2249 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2251 /* The caller has already checked the tag, no need to check it again.
2252 * Check the outer length is valid by calling CRYPT_GetLen:
2254 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2256 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2259 pbEncoded
+= 1 + lenBytes
;
2260 /* Check the inner length is valid by calling CRYPT_GetLen again: */
2261 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &innerLen
)))
2263 ret
= CRYPT_AsnDecodeCopyBytes(dwCertEncodingType
, NULL
,
2264 pbEncoded
, dataLen
, dwFlags
, pDecodePara
, pvStructInfo
,
2271 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2272 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2273 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2277 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2278 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2282 struct AsnDecodeSequenceItem items
[] = {
2283 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2284 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
2285 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2286 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2287 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2288 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2289 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2292 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2293 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2294 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2298 SetLastError(STATUS_ACCESS_VIOLATION
);
2305 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2306 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2307 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2311 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2312 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2316 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2317 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2318 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2320 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2321 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2325 SetLastError(STATUS_ACCESS_VIOLATION
);
2332 struct PATH_LEN_CONSTRAINT
2334 BOOL fPathLenConstraint
;
2335 DWORD dwPathLenConstraint
;
2338 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2339 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2340 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2344 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2345 pvStructInfo
, *pcbStructInfo
);
2349 if (pbEncoded
[0] == ASN_INTEGER
)
2351 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2354 *pcbStructInfo
= bytesNeeded
;
2355 else if (*pcbStructInfo
< bytesNeeded
)
2357 SetLastError(ERROR_MORE_DATA
);
2358 *pcbStructInfo
= bytesNeeded
;
2363 struct PATH_LEN_CONSTRAINT
*constraint
=
2364 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2365 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2367 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
2368 pbEncoded
, cbEncoded
, 0, NULL
,
2369 &constraint
->dwPathLenConstraint
, &size
);
2371 constraint
->fPathLenConstraint
= TRUE
;
2372 TRACE("got an int, dwPathLenConstraint is %d\n",
2373 constraint
->dwPathLenConstraint
);
2378 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2382 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2386 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2387 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2388 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2391 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2392 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2393 offsetof(CERT_NAME_BLOB
, pbData
) };
2394 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2396 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2397 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2399 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2400 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2401 entries
? entries
->rgItems
: NULL
);
2402 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2406 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2407 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2408 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2414 struct AsnDecodeSequenceItem items
[] = {
2415 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2416 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2417 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2418 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2419 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2420 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2421 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2422 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2423 sizeof(struct GenericArray
), TRUE
, TRUE
,
2424 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2427 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2428 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2429 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2433 SetLastError(STATUS_ACCESS_VIOLATION
);
2440 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2441 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2442 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2448 struct AsnDecodeSequenceItem items
[] = {
2449 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2450 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2451 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2452 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2453 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2456 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2457 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2458 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2462 SetLastError(STATUS_ACCESS_VIOLATION
);
2469 #define RSA1_MAGIC 0x31415352
2471 struct DECODED_RSA_PUB_KEY
2474 CRYPT_INTEGER_BLOB modulus
;
2477 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2478 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2479 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2485 struct AsnDecodeSequenceItem items
[] = {
2486 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2487 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2488 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2490 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2491 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2493 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2496 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2497 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2498 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
2501 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2502 decodedKey
->modulus
.cbData
;
2506 *pcbStructInfo
= bytesNeeded
;
2509 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2510 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2513 RSAPUBKEY
*rsaPubKey
;
2515 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2516 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2517 hdr
= (BLOBHEADER
*)pvStructInfo
;
2518 hdr
->bType
= PUBLICKEYBLOB
;
2519 hdr
->bVersion
= CUR_BLOB_VERSION
;
2521 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2522 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2523 sizeof(BLOBHEADER
));
2524 rsaPubKey
->magic
= RSA1_MAGIC
;
2525 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2526 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2527 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2528 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2529 decodedKey
->modulus
.cbData
);
2531 LocalFree(decodedKey
);
2536 SetLastError(STATUS_ACCESS_VIOLATION
);
2543 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2544 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2545 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2548 DWORD bytesNeeded
, dataLen
;
2550 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2551 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2553 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2555 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2556 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2558 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2560 *pcbStructInfo
= bytesNeeded
;
2561 else if (*pcbStructInfo
< bytesNeeded
)
2563 SetLastError(ERROR_MORE_DATA
);
2564 *pcbStructInfo
= bytesNeeded
;
2569 CRYPT_DATA_BLOB
*blob
;
2570 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2572 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2573 blob
->cbData
= dataLen
;
2574 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2575 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2578 assert(blob
->pbData
);
2580 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2588 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2589 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2590 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2594 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2595 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2603 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2606 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2608 SetLastError(CRYPT_E_ASN1_BADTAG
);
2611 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2612 lpszStructType
, pbEncoded
, cbEncoded
,
2613 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2616 *pcbStructInfo
= bytesNeeded
;
2617 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2618 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2620 CRYPT_DATA_BLOB
*blob
;
2622 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2623 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2624 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2625 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2626 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2627 lpszStructType
, pbEncoded
, cbEncoded
,
2628 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2635 SetLastError(STATUS_ACCESS_VIOLATION
);
2642 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2643 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2644 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2648 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2649 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2651 if (pbEncoded
[0] == ASN_BITSTRING
)
2653 DWORD bytesNeeded
, dataLen
;
2655 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2657 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2658 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2660 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2662 *pcbStructInfo
= bytesNeeded
;
2663 else if (*pcbStructInfo
< bytesNeeded
)
2665 *pcbStructInfo
= bytesNeeded
;
2666 SetLastError(ERROR_MORE_DATA
);
2671 CRYPT_BIT_BLOB
*blob
;
2673 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2674 blob
->cbData
= dataLen
- 1;
2675 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2676 GET_LEN_BYTES(pbEncoded
[1]));
2677 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2679 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2680 GET_LEN_BYTES(pbEncoded
[1]);
2684 assert(blob
->pbData
);
2687 BYTE mask
= 0xff << blob
->cUnusedBits
;
2689 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2690 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2691 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2699 SetLastError(CRYPT_E_ASN1_BADTAG
);
2702 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2706 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2707 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2708 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2712 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2713 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2719 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2720 lpszStructType
, pbEncoded
, cbEncoded
,
2721 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2724 *pcbStructInfo
= bytesNeeded
;
2725 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2726 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2728 CRYPT_BIT_BLOB
*blob
;
2730 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2731 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2732 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2733 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2734 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2735 lpszStructType
, pbEncoded
, cbEncoded
,
2736 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2743 SetLastError(STATUS_ACCESS_VIOLATION
);
2747 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2751 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2752 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2753 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2759 *pcbStructInfo
= sizeof(int);
2764 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2765 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2766 DWORD size
= sizeof(buf
);
2768 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2769 if (pbEncoded
[0] != ASN_INTEGER
)
2771 SetLastError(CRYPT_E_ASN1_BADTAG
);
2775 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2776 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
,
2780 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2781 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2785 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2786 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2787 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2789 /* initialize to a negative value to sign-extend */
2794 for (i
= 0; i
< blob
->cbData
; i
++)
2797 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2799 memcpy(pvStructInfo
, &val
, sizeof(int));
2802 else if (GetLastError() == ERROR_MORE_DATA
)
2803 SetLastError(CRYPT_E_ASN1_LARGE
);
2807 SetLastError(STATUS_ACCESS_VIOLATION
);
2814 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2815 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2816 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2819 DWORD bytesNeeded
, dataLen
;
2821 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2823 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2825 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2827 *pcbStructInfo
= bytesNeeded
;
2828 else if (*pcbStructInfo
< bytesNeeded
)
2830 *pcbStructInfo
= bytesNeeded
;
2831 SetLastError(ERROR_MORE_DATA
);
2836 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2838 blob
->cbData
= dataLen
;
2839 assert(blob
->pbData
);
2844 for (i
= 0; i
< blob
->cbData
; i
++)
2846 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2855 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
2856 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2857 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2865 if (pbEncoded
[0] != ASN_INTEGER
)
2867 SetLastError(CRYPT_E_ASN1_BADTAG
);
2871 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2872 lpszStructType
, pbEncoded
, cbEncoded
,
2873 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
);
2877 *pcbStructInfo
= bytesNeeded
;
2878 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2879 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2881 CRYPT_INTEGER_BLOB
*blob
;
2883 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2884 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2885 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2886 blob
->pbData
= (BYTE
*)pvStructInfo
+
2887 sizeof(CRYPT_INTEGER_BLOB
);
2888 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2889 lpszStructType
, pbEncoded
, cbEncoded
,
2890 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2897 SetLastError(STATUS_ACCESS_VIOLATION
);
2904 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
2905 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2906 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2907 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2911 if (pbEncoded
[0] == ASN_INTEGER
)
2913 DWORD bytesNeeded
, dataLen
;
2915 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2917 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2919 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2921 *pcbStructInfo
= bytesNeeded
;
2922 else if (*pcbStructInfo
< bytesNeeded
)
2924 *pcbStructInfo
= bytesNeeded
;
2925 SetLastError(ERROR_MORE_DATA
);
2930 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2932 blob
->cbData
= dataLen
;
2933 assert(blob
->pbData
);
2934 /* remove leading zero byte if it exists */
2935 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
2944 for (i
= 0; i
< blob
->cbData
; i
++)
2946 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2955 SetLastError(CRYPT_E_ASN1_BADTAG
);
2961 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
2962 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2963 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2971 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2972 lpszStructType
, pbEncoded
, cbEncoded
,
2973 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2976 *pcbStructInfo
= bytesNeeded
;
2977 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2978 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2980 CRYPT_INTEGER_BLOB
*blob
;
2982 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2983 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2984 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2985 blob
->pbData
= (BYTE
*)pvStructInfo
+
2986 sizeof(CRYPT_INTEGER_BLOB
);
2987 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2988 lpszStructType
, pbEncoded
, cbEncoded
,
2989 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2996 SetLastError(STATUS_ACCESS_VIOLATION
);
3003 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3004 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3005 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3011 *pcbStructInfo
= sizeof(int);
3016 if (pbEncoded
[0] == ASN_ENUMERATED
)
3018 unsigned int val
= 0, i
;
3022 SetLastError(CRYPT_E_ASN1_EOD
);
3025 else if (pbEncoded
[1] == 0)
3027 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3032 /* A little strange looking, but we have to accept a sign byte:
3033 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3034 * assuming a small length is okay here, it has to be in short
3037 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3039 SetLastError(CRYPT_E_ASN1_LARGE
);
3042 for (i
= 0; i
< pbEncoded
[1]; i
++)
3045 val
|= pbEncoded
[2 + i
];
3047 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3048 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3050 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3051 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3052 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3058 SetLastError(CRYPT_E_ASN1_BADTAG
);
3064 SetLastError(STATUS_ACCESS_VIOLATION
);
3071 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3074 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3079 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3081 if (!isdigit(*(pbEncoded))) \
3083 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3089 (word) += *(pbEncoded)++ - '0'; \
3094 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3095 SYSTEMTIME
*sysTime
)
3102 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3104 WORD hours
, minutes
= 0;
3105 BYTE sign
= *pbEncoded
++;
3108 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3109 if (ret
&& hours
>= 24)
3111 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3116 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3117 if (ret
&& minutes
>= 60)
3119 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3127 sysTime
->wHour
+= hours
;
3128 sysTime
->wMinute
+= minutes
;
3132 if (hours
> sysTime
->wHour
)
3135 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3138 sysTime
->wHour
-= hours
;
3139 if (minutes
> sysTime
->wMinute
)
3142 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3145 sysTime
->wMinute
-= minutes
;
3152 SetLastError(STATUS_ACCESS_VIOLATION
);
3159 #define MIN_ENCODED_TIME_LENGTH 10
3161 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3162 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3163 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3169 *pcbStructInfo
= sizeof(FILETIME
);
3175 if (pbEncoded
[0] == ASN_UTCTIME
)
3179 SetLastError(CRYPT_E_ASN1_EOD
);
3182 else if (pbEncoded
[1] > 0x7f)
3184 /* long-form date strings really can't be valid */
3185 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3190 SYSTEMTIME sysTime
= { 0 };
3191 BYTE len
= pbEncoded
[1];
3193 if (len
< MIN_ENCODED_TIME_LENGTH
)
3195 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3201 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3202 if (sysTime
.wYear
>= 50)
3203 sysTime
.wYear
+= 1900;
3205 sysTime
.wYear
+= 2000;
3206 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3207 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3208 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3209 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3212 if (len
>= 2 && isdigit(*pbEncoded
) &&
3213 isdigit(*(pbEncoded
+ 1)))
3214 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3216 else if (isdigit(*pbEncoded
))
3217 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3220 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3223 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3224 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3227 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3228 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3229 ret
= SystemTimeToFileTime(&sysTime
,
3230 (FILETIME
*)pvStructInfo
);
3237 SetLastError(CRYPT_E_ASN1_BADTAG
);
3243 SetLastError(STATUS_ACCESS_VIOLATION
);
3250 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
3251 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3252 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3258 *pcbStructInfo
= sizeof(FILETIME
);
3264 if (pbEncoded
[0] == ASN_GENERALTIME
)
3268 SetLastError(CRYPT_E_ASN1_EOD
);
3271 else if (pbEncoded
[1] > 0x7f)
3273 /* long-form date strings really can't be valid */
3274 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3279 BYTE len
= pbEncoded
[1];
3281 if (len
< MIN_ENCODED_TIME_LENGTH
)
3283 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3288 SYSTEMTIME sysTime
= { 0 };
3291 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3292 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3293 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3294 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3297 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3300 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3302 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3309 /* workaround macro weirdness */
3310 digits
= min(len
, 3);
3311 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3312 sysTime
.wMilliseconds
);
3315 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3318 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3319 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3322 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3323 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3324 ret
= SystemTimeToFileTime(&sysTime
,
3325 (FILETIME
*)pvStructInfo
);
3332 SetLastError(CRYPT_E_ASN1_BADTAG
);
3338 SetLastError(STATUS_ACCESS_VIOLATION
);
3345 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3346 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3347 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3353 if (pbEncoded
[0] == ASN_UTCTIME
)
3354 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
3355 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3357 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3358 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
3359 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
3360 pvStructInfo
, pcbStructInfo
);
3363 SetLastError(CRYPT_E_ASN1_BADTAG
);
3369 SetLastError(STATUS_ACCESS_VIOLATION
);
3376 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3377 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3378 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3384 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3386 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3388 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3393 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3394 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3396 ptr
= pbEncoded
+ 1 + lenBytes
;
3397 remainingLen
= dataLen
;
3398 while (ret
&& remainingLen
)
3402 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3405 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3407 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3408 ptr
+= 1 + nextLenBytes
+ nextLen
;
3409 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3410 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3411 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3417 CRYPT_SEQUENCE_OF_ANY
*seq
;
3421 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3422 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3424 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3425 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3426 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3427 seq
->cValue
= cValue
;
3428 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3430 nextPtr
= (BYTE
*)seq
->rgValue
+
3431 cValue
* sizeof(CRYPT_DER_BLOB
);
3432 ptr
= pbEncoded
+ 1 + lenBytes
;
3433 remainingLen
= dataLen
;
3435 while (ret
&& remainingLen
)
3439 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3442 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3444 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3446 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3447 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3450 seq
->rgValue
[i
].pbData
= nextPtr
;
3451 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3453 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3455 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3456 ptr
+= 1 + nextLenBytes
+ nextLen
;
3466 SetLastError(CRYPT_E_ASN1_BADTAG
);
3472 SetLastError(STATUS_ACCESS_VIOLATION
);
3479 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3480 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3481 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3485 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3487 DWORD bytesNeeded
, dataLen
;
3489 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3491 struct AsnArrayDescriptor arrayDesc
= {
3492 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3493 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3494 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3495 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3501 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3502 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3503 0, NULL
, NULL
, &nameLen
, NULL
);
3504 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3507 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3509 *pcbStructInfo
= bytesNeeded
;
3510 else if (*pcbStructInfo
< bytesNeeded
)
3512 *pcbStructInfo
= bytesNeeded
;
3513 SetLastError(ERROR_MORE_DATA
);
3518 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3522 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3523 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3524 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3525 0, NULL
, &name
->u
.FullName
, pcbStructInfo
,
3526 name
->u
.FullName
.rgAltEntry
);
3529 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3535 SetLastError(CRYPT_E_ASN1_BADTAG
);
3541 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
3542 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3543 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3545 struct AsnDecodeSequenceItem items
[] = {
3546 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3547 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3548 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3549 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3550 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3551 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3552 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3553 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3554 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3555 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3559 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3560 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3561 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3565 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3566 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3567 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3571 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3572 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3576 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3577 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3578 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3580 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3581 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3585 SetLastError(STATUS_ACCESS_VIOLATION
);
3592 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3593 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3594 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3598 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3599 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3603 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3604 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3606 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3607 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3611 SetLastError(STATUS_ACCESS_VIOLATION
);
3618 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3619 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3620 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3624 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3625 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3629 struct AsnDecodeSequenceItem items
[] = {
3630 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3631 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3632 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3633 offsetof(CRL_ISSUING_DIST_POINT
,
3634 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3635 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3636 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3638 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
3639 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3641 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
3642 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
3643 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
3644 OnlySomeReasonFlags
.pbData
), 0 },
3645 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
3646 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
3649 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3650 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3651 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3655 SetLastError(STATUS_ACCESS_VIOLATION
);
3662 static BOOL WINAPI
CRYPT_AsnDecodeIssuerSerialNumber(DWORD dwCertEncodingType
,
3663 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3664 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3667 struct AsnDecodeSequenceItem items
[] = {
3668 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
3669 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
3671 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
3672 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
3673 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
3675 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
3676 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
3678 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3679 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3681 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3682 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3683 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
3684 issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
3685 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
3687 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3690 TRACE("returning %d\n", ret
);
3694 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
3695 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3696 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3700 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3701 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3705 struct AsnDecodeSequenceItem items
[] = {
3706 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
3707 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3708 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
3709 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
3710 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
3711 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
3712 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3713 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
3714 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
3715 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3716 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
3717 HashEncryptionAlgorithm
.pszObjId
), 0 },
3718 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
3719 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3720 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
3721 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
3722 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3723 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
3724 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
3725 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
3726 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
3729 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3730 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3731 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3735 SetLastError(STATUS_ACCESS_VIOLATION
);
3738 TRACE("returning %d\n", ret
);
3742 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
3743 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3744 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3746 static HCRYPTOIDFUNCSET set
= NULL
;
3748 CryptDecodeObjectExFunc decodeFunc
= NULL
;
3749 HCRYPTOIDFUNCADDR hFunc
= NULL
;
3751 TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
3752 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
3753 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3755 if (!pvStructInfo
&& !pcbStructInfo
)
3757 SetLastError(ERROR_INVALID_PARAMETER
);
3760 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
3761 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
3763 SetLastError(ERROR_FILE_NOT_FOUND
);
3768 SetLastError(CRYPT_E_ASN1_EOD
);
3771 if (cbEncoded
> MAX_ENCODED_LEN
)
3773 SetLastError(CRYPT_E_ASN1_LARGE
);
3777 SetLastError(NOERROR
);
3778 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
3779 *(BYTE
**)pvStructInfo
= NULL
;
3780 if (!HIWORD(lpszStructType
))
3782 switch (LOWORD(lpszStructType
))
3784 case (WORD
)X509_CERT
:
3785 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
3787 case (WORD
)X509_CERT_TO_BE_SIGNED
:
3788 decodeFunc
= CRYPT_AsnDecodeCert
;
3790 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
3791 decodeFunc
= CRYPT_AsnDecodeCRL
;
3793 case (WORD
)X509_EXTENSIONS
:
3794 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3796 case (WORD
)X509_NAME_VALUE
:
3797 decodeFunc
= CRYPT_AsnDecodeNameValue
;
3799 case (WORD
)X509_NAME
:
3800 decodeFunc
= CRYPT_AsnDecodeName
;
3802 case (WORD
)X509_PUBLIC_KEY_INFO
:
3803 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
3805 case (WORD
)X509_AUTHORITY_KEY_ID
:
3806 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3808 case (WORD
)X509_ALTERNATE_NAME
:
3809 decodeFunc
= CRYPT_AsnDecodeAltName
;
3811 case (WORD
)X509_BASIC_CONSTRAINTS
:
3812 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3814 case (WORD
)X509_BASIC_CONSTRAINTS2
:
3815 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3817 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
3818 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
3820 case (WORD
)X509_UNICODE_NAME
:
3821 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
3823 case (WORD
)PKCS_ATTRIBUTE
:
3824 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
3826 case (WORD
)X509_UNICODE_NAME_VALUE
:
3827 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
3829 case (WORD
)X509_OCTET_STRING
:
3830 decodeFunc
= CRYPT_AsnDecodeOctets
;
3832 case (WORD
)X509_BITS
:
3833 case (WORD
)X509_KEY_USAGE
:
3834 decodeFunc
= CRYPT_AsnDecodeBits
;
3836 case (WORD
)X509_INTEGER
:
3837 decodeFunc
= CRYPT_AsnDecodeInt
;
3839 case (WORD
)X509_MULTI_BYTE_INTEGER
:
3840 decodeFunc
= CRYPT_AsnDecodeInteger
;
3842 case (WORD
)X509_MULTI_BYTE_UINT
:
3843 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
3845 case (WORD
)X509_ENUMERATED
:
3846 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3848 case (WORD
)X509_CHOICE_OF_TIME
:
3849 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
3851 case (WORD
)X509_AUTHORITY_KEY_ID2
:
3852 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
3854 case (WORD
)PKCS_CONTENT_INFO
:
3855 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
3857 case (WORD
)X509_SEQUENCE_OF_ANY
:
3858 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
3860 case (WORD
)PKCS_UTC_TIME
:
3861 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3863 case (WORD
)X509_CRL_DIST_POINTS
:
3864 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3866 case (WORD
)X509_ENHANCED_KEY_USAGE
:
3867 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3869 case (WORD
)PKCS_ATTRIBUTES
:
3870 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
3872 case (WORD
)X509_ISSUING_DIST_POINT
:
3873 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3875 case (WORD
)PKCS7_SIGNER_INFO
:
3876 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
3879 FIXME("%d: unimplemented\n", LOWORD(lpszStructType
));
3882 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
3883 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3884 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
3885 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3886 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
3887 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3888 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
3889 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
3890 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
3891 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3892 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
3893 decodeFunc
= CRYPT_AsnDecodeBits
;
3894 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
3895 decodeFunc
= CRYPT_AsnDecodeOctets
;
3896 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
3897 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3898 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
3899 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3900 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
3901 decodeFunc
= CRYPT_AsnDecodeAltName
;
3902 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
3903 decodeFunc
= CRYPT_AsnDecodeAltName
;
3904 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
3905 decodeFunc
= CRYPT_AsnDecodeAltName
;
3906 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
3907 decodeFunc
= CRYPT_AsnDecodeAltName
;
3908 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
3909 decodeFunc
= CRYPT_AsnDecodeAltName
;
3910 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
3911 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3912 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
3913 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3914 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
3915 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3917 TRACE("OID %s not found or unimplemented, looking for DLL\n",
3918 debugstr_a(lpszStructType
));
3922 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
3923 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
3924 (void **)&decodeFunc
, &hFunc
);
3927 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
3928 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3930 SetLastError(ERROR_FILE_NOT_FOUND
);
3932 CryptFreeOIDFunctionAddress(hFunc
, 0);