2 * Copyright 2005-2007 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
38 #define NONAMELESSUNION
45 #include "wine/debug.h"
46 #include "wine/exception.h"
47 #include "crypt32_private.h"
49 /* This is a bit arbitrary, but to set some limit: */
50 #define MAX_ENCODED_LEN 0x02000000
52 #define ASN_FLAGS_MASK 0xe0
53 #define ASN_TYPE_MASK 0x1f
55 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
56 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
64 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
65 DWORD
, DWORD
, void *, DWORD
*);
66 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
67 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
69 /* 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 /* Gets the number of length bytes from the given (leading) length byte */
127 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
129 /* Helper function to get the encoded length of the data starting at pbEncoded,
130 * where pbEncoded[0] is the tag. If the data are too short to contain a
131 * length or if the length is too large for cbEncoded, sets an appropriate
132 * error code and returns FALSE.
134 static BOOL WINAPI
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
141 SetLastError(CRYPT_E_ASN1_CORRUPT
);
144 else if (pbEncoded
[1] <= 0x7f)
146 if (pbEncoded
[1] + 1 > cbEncoded
)
148 SetLastError(CRYPT_E_ASN1_EOD
);
157 else if (pbEncoded
[1] == 0x80)
159 FIXME("unimplemented for indefinite-length encoding\n");
160 SetLastError(CRYPT_E_ASN1_CORRUPT
);
165 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
167 if (lenLen
> sizeof(DWORD
) + 1)
169 SetLastError(CRYPT_E_ASN1_LARGE
);
172 else if (lenLen
+ 2 > cbEncoded
)
174 SetLastError(CRYPT_E_ASN1_CORRUPT
);
187 if (out
+ lenLen
+ 1 > cbEncoded
)
189 SetLastError(CRYPT_E_ASN1_EOD
);
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
207 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
208 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
213 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
215 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
216 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
218 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
219 if (!*(BYTE
**)pvStructInfo
)
222 *pcbStructInfo
= bytesNeeded
;
224 else if (*pcbStructInfo
< bytesNeeded
)
226 *pcbStructInfo
= bytesNeeded
;
227 SetLastError(ERROR_MORE_DATA
);
234 * The expected tag of the item. If tag is 0, decodeFunc is called
235 * regardless of the tag value seen.
237 * A sequence is decoded into a struct. The offset member is the
238 * offset of this item within that struct.
240 * The decoder function to use. If this is NULL, then the member isn't
241 * decoded, but minSize space is reserved for it.
243 * The minimum amount of space occupied after decoding. You must set this.
245 * If true, and the tag doesn't match the expected tag for this item,
246 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
247 * filled with 0 for this member.
248 * hasPointer, pointerOffset:
249 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
250 * the offset within the struct of the data pointer (or to the
251 * first data pointer, if more than one exist).
253 * Used by CRYPT_AsnDecodeSequence, not for your use.
255 struct AsnDecodeSequenceItem
259 CryptDecodeObjectExFunc decodeFunc
;
267 /* Decodes the items in a sequence, where the items are described in items,
268 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
269 * pvStructInfo. nextData is a pointer to the memory location at which the
270 * first decoded item with a dynamic pointer should point.
271 * Upon decoding, *cbDecoded is the total number of bytes decoded.
273 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
274 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
275 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
,
279 DWORD i
, decoded
= 0;
280 const BYTE
*ptr
= pbEncoded
;
282 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
283 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
285 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
287 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
291 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
294 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
296 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
298 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
300 TRACE("Setting next pointer to %p\n",
302 *(BYTE
**)((BYTE
*)pvStructInfo
+
303 items
[i
].pointerOffset
) = nextData
;
305 if (items
[i
].decodeFunc
)
308 TRACE("decoding item %d\n", i
);
310 TRACE("sizing item %d\n", i
);
311 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
312 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
313 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
314 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
315 : NULL
, &items
[i
].size
);
318 /* Account for alignment padding */
319 if (items
[i
].size
% sizeof(DWORD
))
320 items
[i
].size
+= sizeof(DWORD
) -
321 items
[i
].size
% sizeof(DWORD
);
322 TRACE("item %d size: %d\n", i
, items
[i
].size
);
323 if (nextData
&& items
[i
].hasPointer
&&
324 items
[i
].size
> items
[i
].minSize
)
325 nextData
+= items
[i
].size
- items
[i
].minSize
;
326 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
327 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
328 TRACE("item %d: decoded %d bytes\n", i
,
329 1 + nextItemLenBytes
+ nextItemLen
);
331 else if (items
[i
].optional
&&
332 GetLastError() == CRYPT_E_ASN1_BADTAG
)
334 TRACE("skipping optional item %d\n", i
);
335 items
[i
].size
= items
[i
].minSize
;
336 SetLastError(NOERROR
);
340 TRACE("item %d failed: %08x\n", i
,
345 TRACE("item %d: decoded %d bytes\n", i
,
346 1 + nextItemLenBytes
+ nextItemLen
);
347 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
348 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
349 items
[i
].size
= items
[i
].minSize
;
352 else if (items
[i
].optional
)
354 TRACE("skipping optional item %d\n", i
);
355 items
[i
].size
= items
[i
].minSize
;
359 TRACE("item %d: tag %02x doesn't match expected %02x\n",
360 i
, ptr
[0], items
[i
].tag
);
361 SetLastError(CRYPT_E_ASN1_BADTAG
);
366 else if (items
[i
].optional
)
368 TRACE("missing optional item %d, skipping\n", i
);
369 items
[i
].size
= items
[i
].minSize
;
373 TRACE("not enough bytes for item %d, failing\n", i
);
374 SetLastError(CRYPT_E_ASN1_CORRUPT
);
379 *cbDecoded
= decoded
;
380 TRACE("returning %d\n", ret
);
384 /* This decodes an arbitrary sequence into a contiguous block of memory
385 * (basically, a struct.) Each element being decoded is described by a struct
386 * AsnDecodeSequenceItem, see above.
387 * startingPointer is an optional pointer to the first place where dynamic
388 * data will be stored. If you know the starting offset, you may pass it
389 * here. Otherwise, pass NULL, and one will be inferred from the items.
390 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
392 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
393 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
394 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
395 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
399 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
400 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
403 if (pbEncoded
[0] == ASN_SEQUENCE
)
407 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
409 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
410 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
412 cbEncoded
-= 1 + lenBytes
;
413 if (cbEncoded
< dataLen
)
415 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
417 SetLastError(CRYPT_E_ASN1_CORRUPT
);
421 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, ptr
,
422 cbEncoded
, dwFlags
, NULL
, NULL
, &cbDecoded
);
423 if (ret
&& cbDecoded
!= dataLen
)
425 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
427 SetLastError(CRYPT_E_ASN1_CORRUPT
);
432 DWORD i
, bytesNeeded
= 0, structSize
= 0;
434 for (i
= 0; i
< cItem
; i
++)
436 bytesNeeded
+= items
[i
].size
;
437 structSize
+= items
[i
].minSize
;
440 *pcbStructInfo
= bytesNeeded
;
441 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
442 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
446 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
447 pvStructInfo
= *(BYTE
**)pvStructInfo
;
449 nextData
= (BYTE
*)startingPointer
;
451 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
452 memset(pvStructInfo
, 0, structSize
);
453 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
454 ptr
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
,
462 SetLastError(CRYPT_E_ASN1_BADTAG
);
465 TRACE("returning %d (%08x)\n", ret
, GetLastError());
470 * The expected tag of the entire encoded array (usually a variant
471 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
472 * regardless of the tag seen.
474 * used to decode each item in the array
476 * is the minimum size of each decoded item
478 * indicates whether each item has a dynamic pointer
480 * indicates the offset within itemSize at which the pointer exists
482 struct AsnArrayDescriptor
485 CryptDecodeObjectExFunc decodeFunc
;
491 struct AsnArrayItemSize
497 /* Decodes an array of like types into a struct GenericArray.
498 * The layout and decoding of the array are described by a struct
499 * AsnArrayDescriptor.
501 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
502 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
503 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
504 void *startingPointer
)
508 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
509 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
512 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
516 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
518 DWORD bytesNeeded
, cItems
= 0;
519 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
520 /* There can be arbitrarily many items, but there is often only one.
522 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
524 bytesNeeded
= sizeof(struct GenericArray
);
529 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
530 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
532 DWORD itemLenBytes
, itemDataLen
, size
= 0;
534 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
535 /* Each item decoded may not tolerate extraneous bytes, so
536 * get the length of the next element and pass it directly.
538 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
541 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
542 1 + itemLenBytes
+ itemDataLen
,
543 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
550 if (itemSizes
!= &itemSize
)
551 itemSizes
= CryptMemRealloc(itemSizes
,
552 cItems
* sizeof(struct AsnArrayItemSize
));
557 cItems
* sizeof(struct AsnArrayItemSize
));
559 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
563 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
565 itemSizes
[cItems
- 1].size
= size
;
567 ret
= CRYPT_GetLen(ptr
,
568 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
570 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
580 *pcbStructInfo
= bytesNeeded
;
581 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
582 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
587 struct GenericArray
*array
;
589 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
590 pvStructInfo
= *(BYTE
**)pvStructInfo
;
591 array
= (struct GenericArray
*)pvStructInfo
;
592 array
->cItems
= cItems
;
594 array
->rgItems
= startingPointer
;
596 array
->rgItems
= (BYTE
*)array
+
597 sizeof(struct GenericArray
);
598 nextData
= (BYTE
*)array
->rgItems
+
599 array
->cItems
* arrayDesc
->itemSize
;
600 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
601 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
604 if (arrayDesc
->hasPointer
)
605 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
606 + arrayDesc
->pointerOffset
) = nextData
;
607 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
608 itemSizes
[i
].encodedLen
,
609 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
610 array
->rgItems
+ i
* arrayDesc
->itemSize
,
616 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
617 ret
= CRYPT_GetLen(ptr
,
618 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
620 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
625 if (itemSizes
!= &itemSize
)
626 CryptMemFree(itemSizes
);
631 SetLastError(CRYPT_E_ASN1_BADTAG
);
637 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
638 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
639 * to CRYPT_E_ASN1_CORRUPT.
640 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
643 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
644 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
645 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
650 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
652 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
653 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
655 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
656 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
659 *pcbStructInfo
= bytesNeeded
;
660 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
661 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
663 CRYPT_DER_BLOB
*blob
;
665 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
666 pvStructInfo
= *(BYTE
**)pvStructInfo
;
667 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
668 blob
->cbData
= 1 + lenBytes
+ dataLen
;
671 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
672 blob
->pbData
= (BYTE
*)pbEncoded
;
675 assert(blob
->pbData
);
676 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
681 SetLastError(CRYPT_E_ASN1_CORRUPT
);
689 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
690 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
691 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
692 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
696 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
697 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
699 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
702 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
703 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
704 pvStructInfo
, pcbStructInfo
);
705 if (ret
&& pvStructInfo
)
707 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
714 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
716 temp
= blob
->pbData
[i
];
717 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
718 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
722 TRACE("returning %d (%08x)\n", ret
, GetLastError());
726 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
727 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
728 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
732 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
733 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
737 struct AsnDecodeSequenceItem items
[] = {
738 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
739 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
740 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
741 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
742 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
743 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
744 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
745 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
746 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
747 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
750 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
751 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
752 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
753 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
754 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
758 SetLastError(STATUS_ACCESS_VIOLATION
);
763 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
767 /* Internal function */
768 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
769 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
770 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
775 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
777 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
779 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
780 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
781 pvStructInfo
, pcbStructInfo
);
786 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
787 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
788 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
792 struct AsnDecodeSequenceItem items
[] = {
793 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
794 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
795 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
796 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
799 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
800 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
801 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
805 /* Internal function */
806 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
807 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
808 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
813 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
815 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
817 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
818 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
819 pDecodePara
, pvStructInfo
, pcbStructInfo
);
824 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
825 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
826 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
829 struct AsnDecodeSequenceItem items
[] = {
830 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
831 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
832 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
833 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
834 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
835 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
836 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
837 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
838 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
839 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
841 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
842 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
844 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
845 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
847 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
848 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
849 FALSE
, TRUE
, offsetof(CERT_INFO
,
850 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
851 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
852 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
853 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
854 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
855 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
856 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
857 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
858 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
859 offsetof(CERT_INFO
, rgExtension
), 0 },
862 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
863 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
865 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
866 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
867 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
868 if (ret
&& pvStructInfo
)
872 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
873 info
= *(CERT_INFO
**)pvStructInfo
;
875 info
= (CERT_INFO
*)pvStructInfo
;
876 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
877 !info
->Subject
.cbData
)
879 SetLastError(CRYPT_E_ASN1_CORRUPT
);
880 /* Don't need to deallocate, because it should have failed on the
881 * first pass (and no memory was allocated.)
887 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
891 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
892 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
893 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
897 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
898 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
904 /* Unless told not to, first try to decode it as a signed cert. */
905 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
907 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
909 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
910 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
911 (BYTE
*)&signedCert
, &size
);
915 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
916 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
917 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
918 pvStructInfo
, pcbStructInfo
);
919 LocalFree(signedCert
);
922 /* Failing that, try it as an unsigned cert */
926 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
927 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
928 pDecodePara
, pvStructInfo
, pcbStructInfo
);
933 SetLastError(STATUS_ACCESS_VIOLATION
);
937 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
941 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
942 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
943 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
946 struct AsnDecodeSequenceItem items
[] = {
947 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
948 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
949 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
950 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
951 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
952 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
953 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
954 offsetof(CRL_ENTRY
, rgExtension
), 0 },
956 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
958 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
961 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
962 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
963 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
967 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
968 * been set prior to calling.
970 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
971 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
972 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
975 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
976 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
977 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
978 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
980 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
981 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
983 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
984 pDecodePara
, pvStructInfo
, pcbStructInfo
,
985 entries
? entries
->rgItems
: NULL
);
986 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
990 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
991 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
992 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
994 struct AsnDecodeSequenceItem items
[] = {
995 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
996 CRYPT_AsnDecodeInt
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
997 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
998 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
999 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1000 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1001 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1003 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1004 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1005 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1006 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1007 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1008 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1009 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1010 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1011 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1012 offsetof(CRL_INFO
, rgExtension
), 0 },
1016 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1017 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1019 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1020 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1021 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1023 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1027 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1028 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1029 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1033 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1034 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1040 /* Unless told not to, first try to decode it as a signed crl. */
1041 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1043 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1045 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1046 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1047 (BYTE
*)&signedCrl
, &size
);
1051 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1052 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1053 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1054 pvStructInfo
, pcbStructInfo
);
1055 LocalFree(signedCrl
);
1058 /* Failing that, try it as an unsigned crl */
1062 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1063 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1064 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1069 SetLastError(STATUS_ACCESS_VIOLATION
);
1073 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1077 static BOOL WINAPI
CRYPT_AsnDecodeOidIgnoreTag(DWORD dwCertEncodingType
,
1078 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1079 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1084 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1085 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1087 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1089 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1090 DWORD bytesNeeded
= sizeof(LPSTR
);
1094 /* The largest possible string for the first two components
1095 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1100 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1101 pbEncoded
[1 + lenBytes
] / 40,
1102 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1104 bytesNeeded
+= strlen(firstTwo
) + 1;
1105 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1106 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1108 /* large enough for ".4000000" */
1112 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1119 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1122 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1129 snprintf(str
, sizeof(str
), ".%d", val
);
1130 bytesNeeded
+= strlen(str
);
1135 *pcbStructInfo
= bytesNeeded
;
1136 else if (*pcbStructInfo
< bytesNeeded
)
1138 *pcbStructInfo
= bytesNeeded
;
1139 SetLastError(ERROR_MORE_DATA
);
1147 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1150 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1151 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1153 pszObjId
+= strlen(pszObjId
);
1154 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1155 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1159 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1168 sprintf(pszObjId
, ".%d", val
);
1169 pszObjId
+= strlen(pszObjId
);
1173 *(LPSTR
*)pvStructInfo
= NULL
;
1174 *pcbStructInfo
= bytesNeeded
;
1180 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
1181 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1182 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1186 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1187 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1189 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1190 ret
= CRYPT_AsnDecodeOidIgnoreTag(dwCertEncodingType
, lpszStructType
,
1191 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
1195 SetLastError(CRYPT_E_ASN1_BADTAG
);
1201 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1204 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1205 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1206 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1208 struct AsnDecodeSequenceItem items
[] = {
1209 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1210 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1211 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1212 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1213 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1214 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1215 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1216 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1219 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1221 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1225 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1226 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1227 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1228 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1230 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1231 debugstr_a(ext
->pszObjId
));
1232 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1236 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1237 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1238 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1241 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1242 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1243 offsetof(CERT_EXTENSION
, pszObjId
) };
1244 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1246 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1247 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1249 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1250 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1254 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1255 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1256 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1262 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1263 lpszStructType
, pbEncoded
, cbEncoded
,
1264 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1265 if (ret
&& pvStructInfo
)
1267 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1268 pcbStructInfo
, *pcbStructInfo
);
1271 CERT_EXTENSIONS
*exts
;
1273 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1274 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1275 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1276 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1277 sizeof(CERT_EXTENSIONS
));
1278 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1279 lpszStructType
, pbEncoded
, cbEncoded
,
1280 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1287 SetLastError(STATUS_ACCESS_VIOLATION
);
1294 /* Warning: this assumes the address of value->Value.pbData is already set, in
1295 * order to avoid overwriting memory. (In some cases, it may change it, if it
1296 * doesn't copy anything to memory.) Be sure to set it correctly!
1298 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1299 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1300 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1304 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1306 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1308 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1309 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1311 switch (pbEncoded
[0])
1313 case ASN_OCTETSTRING
:
1314 valueType
= CERT_RDN_OCTET_STRING
;
1315 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1316 bytesNeeded
+= dataLen
;
1318 case ASN_NUMERICSTRING
:
1319 valueType
= CERT_RDN_NUMERIC_STRING
;
1320 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1321 bytesNeeded
+= dataLen
;
1323 case ASN_PRINTABLESTRING
:
1324 valueType
= CERT_RDN_PRINTABLE_STRING
;
1325 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1326 bytesNeeded
+= dataLen
;
1329 valueType
= CERT_RDN_IA5_STRING
;
1330 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1331 bytesNeeded
+= dataLen
;
1334 valueType
= CERT_RDN_T61_STRING
;
1335 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1336 bytesNeeded
+= dataLen
;
1338 case ASN_VIDEOTEXSTRING
:
1339 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1340 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1341 bytesNeeded
+= dataLen
;
1343 case ASN_GRAPHICSTRING
:
1344 valueType
= CERT_RDN_GRAPHIC_STRING
;
1345 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1346 bytesNeeded
+= dataLen
;
1348 case ASN_VISIBLESTRING
:
1349 valueType
= CERT_RDN_VISIBLE_STRING
;
1350 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1351 bytesNeeded
+= dataLen
;
1353 case ASN_GENERALSTRING
:
1354 valueType
= CERT_RDN_GENERAL_STRING
;
1355 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1356 bytesNeeded
+= dataLen
;
1358 case ASN_UNIVERSALSTRING
:
1359 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1360 SetLastError(CRYPT_E_ASN1_BADTAG
);
1363 valueType
= CERT_RDN_BMP_STRING
;
1364 bytesNeeded
+= dataLen
;
1366 case ASN_UTF8STRING
:
1367 valueType
= CERT_RDN_UTF8_STRING
;
1368 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1369 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1372 SetLastError(CRYPT_E_ASN1_BADTAG
);
1377 *pcbStructInfo
= bytesNeeded
;
1378 else if (*pcbStructInfo
< bytesNeeded
)
1380 *pcbStructInfo
= bytesNeeded
;
1381 SetLastError(ERROR_MORE_DATA
);
1386 *pcbStructInfo
= bytesNeeded
;
1387 value
->dwValueType
= valueType
;
1392 assert(value
->Value
.pbData
);
1393 switch (pbEncoded
[0])
1395 case ASN_OCTETSTRING
:
1396 case ASN_NUMERICSTRING
:
1397 case ASN_PRINTABLESTRING
:
1400 case ASN_VIDEOTEXSTRING
:
1401 case ASN_GRAPHICSTRING
:
1402 case ASN_VISIBLESTRING
:
1403 case ASN_GENERALSTRING
:
1404 value
->Value
.cbData
= dataLen
;
1407 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1408 memcpy(value
->Value
.pbData
,
1409 pbEncoded
+ 1 + lenBytes
, dataLen
);
1411 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1417 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1419 value
->Value
.cbData
= dataLen
;
1420 for (i
= 0; i
< dataLen
/ 2; i
++)
1421 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1422 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1425 case ASN_UTF8STRING
:
1427 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1429 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1430 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1431 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1438 value
->Value
.cbData
= 0;
1439 value
->Value
.pbData
= NULL
;
1446 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1447 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1448 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1454 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1455 lpszStructType
, pbEncoded
, cbEncoded
,
1456 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1457 if (ret
&& pvStructInfo
)
1459 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1460 pcbStructInfo
, *pcbStructInfo
);
1463 CERT_NAME_VALUE
*value
;
1465 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1466 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1467 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1468 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1469 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1470 lpszStructType
, pbEncoded
, cbEncoded
,
1471 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1478 SetLastError(STATUS_ACCESS_VIOLATION
);
1485 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1486 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1487 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1488 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1492 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1494 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1496 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1497 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1499 switch (pbEncoded
[0])
1501 case ASN_NUMERICSTRING
:
1502 valueType
= CERT_RDN_NUMERIC_STRING
;
1503 bytesNeeded
+= dataLen
* 2;
1505 case ASN_PRINTABLESTRING
:
1506 valueType
= CERT_RDN_PRINTABLE_STRING
;
1507 bytesNeeded
+= dataLen
* 2;
1510 valueType
= CERT_RDN_IA5_STRING
;
1511 bytesNeeded
+= dataLen
* 2;
1514 valueType
= CERT_RDN_T61_STRING
;
1515 bytesNeeded
+= dataLen
* 2;
1517 case ASN_VIDEOTEXSTRING
:
1518 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1519 bytesNeeded
+= dataLen
* 2;
1521 case ASN_GRAPHICSTRING
:
1522 valueType
= CERT_RDN_GRAPHIC_STRING
;
1523 bytesNeeded
+= dataLen
* 2;
1525 case ASN_VISIBLESTRING
:
1526 valueType
= CERT_RDN_VISIBLE_STRING
;
1527 bytesNeeded
+= dataLen
* 2;
1529 case ASN_GENERALSTRING
:
1530 valueType
= CERT_RDN_GENERAL_STRING
;
1531 bytesNeeded
+= dataLen
* 2;
1533 case ASN_UNIVERSALSTRING
:
1534 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1535 bytesNeeded
+= dataLen
/ 2;
1538 valueType
= CERT_RDN_BMP_STRING
;
1539 bytesNeeded
+= dataLen
;
1541 case ASN_UTF8STRING
:
1542 valueType
= CERT_RDN_UTF8_STRING
;
1543 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1544 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1547 SetLastError(CRYPT_E_ASN1_BADTAG
);
1552 *pcbStructInfo
= bytesNeeded
;
1553 else if (*pcbStructInfo
< bytesNeeded
)
1555 *pcbStructInfo
= bytesNeeded
;
1556 SetLastError(ERROR_MORE_DATA
);
1561 *pcbStructInfo
= bytesNeeded
;
1562 value
->dwValueType
= valueType
;
1566 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1568 assert(value
->Value
.pbData
);
1569 switch (pbEncoded
[0])
1571 case ASN_NUMERICSTRING
:
1572 case ASN_PRINTABLESTRING
:
1575 case ASN_VIDEOTEXSTRING
:
1576 case ASN_GRAPHICSTRING
:
1577 case ASN_VISIBLESTRING
:
1578 case ASN_GENERALSTRING
:
1579 value
->Value
.cbData
= dataLen
* 2;
1580 for (i
= 0; i
< dataLen
; i
++)
1581 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1583 case ASN_UNIVERSALSTRING
:
1584 value
->Value
.cbData
= dataLen
/ 2;
1585 for (i
= 0; i
< dataLen
/ 4; i
++)
1586 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1587 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1590 value
->Value
.cbData
= dataLen
;
1591 for (i
= 0; i
< dataLen
/ 2; i
++)
1592 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1593 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1595 case ASN_UTF8STRING
:
1596 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1597 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1598 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1604 value
->Value
.cbData
= 0;
1605 value
->Value
.pbData
= NULL
;
1612 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1613 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1614 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1620 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1621 lpszStructType
, pbEncoded
, cbEncoded
,
1622 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1623 if (ret
&& pvStructInfo
)
1625 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1626 pcbStructInfo
, *pcbStructInfo
);
1629 CERT_NAME_VALUE
*value
;
1631 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1632 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1633 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1634 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1635 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1636 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1637 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1644 SetLastError(STATUS_ACCESS_VIOLATION
);
1651 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1652 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1653 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1656 struct AsnDecodeSequenceItem items
[] = {
1657 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1658 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1659 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1660 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1661 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1662 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1664 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1666 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1667 pvStructInfo
, *pcbStructInfo
);
1670 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1671 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1672 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1673 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1676 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1677 debugstr_a(attr
->pszObjId
));
1678 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1680 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1684 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1685 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1686 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1689 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1690 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1691 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1692 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1694 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1695 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1699 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1700 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1701 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1707 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1708 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1709 offsetof(CERT_RDN
, rgRDNAttr
) };
1711 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1712 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1716 SetLastError(STATUS_ACCESS_VIOLATION
);
1723 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType
,
1724 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1725 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1728 struct AsnDecodeSequenceItem items
[] = {
1729 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1730 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1731 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1732 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1733 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1734 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1736 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1738 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1739 pvStructInfo
, *pcbStructInfo
);
1742 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1743 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1744 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1745 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1748 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1749 debugstr_a(attr
->pszObjId
));
1750 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1752 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1756 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType
,
1757 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1758 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1761 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1762 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1763 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1764 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1766 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1767 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1771 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1772 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1773 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1779 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1780 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1781 offsetof(CERT_RDN
, rgRDNAttr
) };
1783 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1784 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1788 SetLastError(STATUS_ACCESS_VIOLATION
);
1795 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1796 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1797 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1800 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1802 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1803 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1805 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1806 bytesNeeded
+= cbEncoded
;
1808 *pcbStructInfo
= bytesNeeded
;
1809 else if (*pcbStructInfo
< bytesNeeded
)
1811 SetLastError(ERROR_MORE_DATA
);
1812 *pcbStructInfo
= bytesNeeded
;
1817 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1819 *pcbStructInfo
= bytesNeeded
;
1820 blob
->cbData
= cbEncoded
;
1821 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1822 blob
->pbData
= (LPBYTE
)pbEncoded
;
1825 assert(blob
->pbData
);
1826 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1832 static BOOL WINAPI
CRYPT_DecodeDERArray(DWORD dwCertEncodingType
,
1833 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1834 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1837 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
1838 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
1839 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
1841 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1842 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1844 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1845 pDecodePara
, pvStructInfo
, pcbStructInfo
, array
? array
->rgItems
: NULL
);
1849 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
1850 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1851 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1857 struct AsnDecodeSequenceItem items
[] = {
1858 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
1859 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1860 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
1861 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
1862 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
1863 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
1865 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
1867 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1868 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1869 pDecodePara
, pvStructInfo
, pcbStructInfo
, attr
? attr
->pszObjId
:
1874 SetLastError(STATUS_ACCESS_VIOLATION
);
1877 TRACE("returning %d\n", ret
);
1881 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributesInternal(
1882 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1883 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1884 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1886 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodePKCSAttribute
,
1887 sizeof(CRYPT_ATTRIBUTE
), TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
1888 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1891 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1892 pDecodePara
, pvStructInfo
, pcbStructInfo
, attrs
? attrs
->rgAttr
:
1897 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
1898 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1899 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1903 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1904 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1911 SetLastError(CRYPT_E_ASN1_EOD
);
1912 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
1913 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1914 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(
1915 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1916 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1919 *pcbStructInfo
= bytesNeeded
;
1920 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1921 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1923 PCRYPT_ATTRIBUTES attrs
;
1925 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1926 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1927 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1928 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
1929 sizeof(CRYPT_ATTRIBUTES
));
1930 ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1931 lpszStructType
, pbEncoded
, cbEncoded
,
1932 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1939 SetLastError(STATUS_ACCESS_VIOLATION
);
1942 TRACE("returning %d\n", ret
);
1946 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1947 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1948 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1950 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1951 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1953 struct AsnDecodeSequenceItem items
[] = {
1954 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1955 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1956 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1957 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1958 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1959 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1962 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1963 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1965 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1966 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1967 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1968 if (ret
&& pvStructInfo
)
1970 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1971 debugstr_a(algo
->pszObjId
));
1976 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1977 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1978 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1981 struct AsnDecodeSequenceItem items
[] = {
1982 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1983 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1984 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
1985 Algorithm
.pszObjId
) },
1986 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
1987 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1988 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
1990 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1992 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1993 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1994 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
1995 info
->Algorithm
.Parameters
.pbData
: NULL
);
1999 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2000 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2001 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2009 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2010 lpszStructType
, pbEncoded
, cbEncoded
,
2011 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2014 *pcbStructInfo
= bytesNeeded
;
2015 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2016 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2018 PCERT_PUBLIC_KEY_INFO info
;
2020 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2021 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2022 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2023 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2024 sizeof(CERT_PUBLIC_KEY_INFO
);
2025 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2026 lpszStructType
, pbEncoded
, cbEncoded
,
2027 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2034 SetLastError(STATUS_ACCESS_VIOLATION
);
2041 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
2042 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2043 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2049 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2052 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2054 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2057 if (pbEncoded
[1] > 1)
2059 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2064 *pcbStructInfo
= sizeof(BOOL
);
2067 else if (*pcbStructInfo
< sizeof(BOOL
))
2069 *pcbStructInfo
= sizeof(BOOL
);
2070 SetLastError(ERROR_MORE_DATA
);
2075 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2078 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2082 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
2083 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2084 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2086 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2087 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2090 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2091 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2095 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2098 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2099 if (1 + lenBytes
> cbEncoded
)
2101 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2104 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2106 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2108 case 1: /* rfc822Name */
2109 case 2: /* dNSName */
2110 case 6: /* uniformResourceIdentifier */
2111 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2113 case 4: /* directoryName */
2114 case 7: /* iPAddress */
2115 bytesNeeded
+= dataLen
;
2117 case 8: /* registeredID */
2118 ret
= CRYPT_AsnDecodeOidIgnoreTag(dwCertEncodingType
, NULL
,
2119 pbEncoded
, cbEncoded
, 0, NULL
, NULL
, &dataLen
);
2122 /* FIXME: ugly, shouldn't need to know internals of OID decode
2123 * function to use it.
2125 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2128 case 0: /* otherName */
2129 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2130 SetLastError(CRYPT_E_ASN1_BADTAG
);
2133 case 3: /* x400Address, unimplemented */
2134 case 5: /* ediPartyName, unimplemented */
2135 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2136 SetLastError(CRYPT_E_ASN1_BADTAG
);
2140 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2141 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2147 *pcbStructInfo
= bytesNeeded
;
2148 else if (*pcbStructInfo
< bytesNeeded
)
2150 *pcbStructInfo
= bytesNeeded
;
2151 SetLastError(ERROR_MORE_DATA
);
2156 *pcbStructInfo
= bytesNeeded
;
2157 /* MS used values one greater than the asn1 ones.. sigh */
2158 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2159 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2161 case 1: /* rfc822Name */
2162 case 2: /* dNSName */
2163 case 6: /* uniformResourceIdentifier */
2167 for (i
= 0; i
< dataLen
; i
++)
2168 entry
->u
.pwszURL
[i
] =
2169 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2170 entry
->u
.pwszURL
[i
] = 0;
2171 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2172 debugstr_w(entry
->u
.pwszURL
));
2175 case 4: /* directoryName */
2176 entry
->dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
2177 /* The data are memory-equivalent with the IPAddress case,
2180 case 7: /* iPAddress */
2181 /* The next data pointer is in the pwszURL spot, that is,
2182 * the first 4 bytes. Need to move it to the next spot.
2184 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2185 entry
->u
.IPAddress
.cbData
= dataLen
;
2186 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2189 case 8: /* registeredID */
2190 ret
= CRYPT_AsnDecodeOidIgnoreTag(dwCertEncodingType
, NULL
,
2191 pbEncoded
, cbEncoded
, 0, NULL
, &entry
->u
.pszRegisteredID
,
2201 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2202 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2203 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2206 struct AsnArrayDescriptor arrayDesc
= { 0,
2207 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2208 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2209 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2211 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2212 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2215 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2216 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2217 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
2221 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2222 static BOOL WINAPI
CRYPT_AsnDecodeIntegerSwapBytes(DWORD dwCertEncodingType
,
2223 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2224 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2228 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2229 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2231 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2234 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
, lpszStructType
,
2235 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
2236 pvStructInfo
, pcbStructInfo
);
2237 if (ret
&& pvStructInfo
)
2239 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2246 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
2248 temp
= blob
->pbData
[i
];
2249 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
2250 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
2254 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2258 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2259 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2260 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2266 struct AsnDecodeSequenceItem items
[] = {
2267 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2268 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2269 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2270 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2271 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2272 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2273 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2274 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2275 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2276 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2277 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2280 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2281 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2282 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2286 SetLastError(STATUS_ACCESS_VIOLATION
);
2293 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2294 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2295 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2301 struct AsnDecodeSequenceItem items
[] = {
2302 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2303 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2304 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2305 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2306 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2307 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2308 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2309 AuthorityCertIssuer
.rgAltEntry
), 0 },
2310 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2311 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2312 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2313 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2314 AuthorityCertSerialNumber
.pbData
), 0 },
2317 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2318 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2319 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2323 SetLastError(STATUS_ACCESS_VIOLATION
);
2330 static BOOL WINAPI
CRYPT_AsnDecodePKCSContent(DWORD dwCertEncodingType
,
2331 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2332 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2337 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2338 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2340 /* The caller has already checked the tag, no need to check it again.
2341 * Check the outer length is valid by calling CRYPT_GetLen:
2343 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2345 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2348 pbEncoded
+= 1 + lenBytes
;
2349 /* Check the inner length is valid by calling CRYPT_GetLen again: */
2350 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &innerLen
)))
2352 ret
= CRYPT_AsnDecodeCopyBytes(dwCertEncodingType
, NULL
,
2353 pbEncoded
, dataLen
, dwFlags
, pDecodePara
, pvStructInfo
,
2360 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfoInternal(
2361 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2362 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2363 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2365 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2366 struct AsnDecodeSequenceItem items
[] = {
2367 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2368 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2369 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2370 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2371 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2372 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2373 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2377 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2378 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2380 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2381 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2382 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->pszObjId
: NULL
);
2386 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2387 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2388 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2392 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2393 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2397 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2398 lpszStructType
, pbEncoded
, cbEncoded
,
2399 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
2400 if (ret
&& pvStructInfo
)
2402 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2403 pcbStructInfo
, *pcbStructInfo
);
2406 CRYPT_CONTENT_INFO
*info
;
2408 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2409 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2410 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2411 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2412 sizeof(CRYPT_CONTENT_INFO
));
2413 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2414 lpszStructType
, pbEncoded
, cbEncoded
,
2415 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2422 SetLastError(STATUS_ACCESS_VIOLATION
);
2428 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2429 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2430 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2433 struct AsnDecodeSequenceItem items
[] = {
2434 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
), CRYPT_AsnDecodeInt
,
2435 sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2436 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2437 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2438 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2440 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2441 CRYPT_AsnDecodePKCSContentInfoInternal
,
2442 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2443 ContentInfo
.pszObjId
), 0 },
2444 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2445 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2446 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2449 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
2450 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2451 pDecodePara
, digestedData
, pcbDigestedData
, NULL
);
2455 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2456 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2457 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2461 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2462 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2466 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2467 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2468 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2470 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2471 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2475 SetLastError(STATUS_ACCESS_VIOLATION
);
2482 struct PATH_LEN_CONSTRAINT
2484 BOOL fPathLenConstraint
;
2485 DWORD dwPathLenConstraint
;
2488 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2489 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2490 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2494 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2495 pvStructInfo
, *pcbStructInfo
);
2499 if (pbEncoded
[0] == ASN_INTEGER
)
2501 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2504 *pcbStructInfo
= bytesNeeded
;
2505 else if (*pcbStructInfo
< bytesNeeded
)
2507 SetLastError(ERROR_MORE_DATA
);
2508 *pcbStructInfo
= bytesNeeded
;
2513 struct PATH_LEN_CONSTRAINT
*constraint
=
2514 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2515 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2517 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
2518 pbEncoded
, cbEncoded
, 0, NULL
,
2519 &constraint
->dwPathLenConstraint
, &size
);
2521 constraint
->fPathLenConstraint
= TRUE
;
2522 TRACE("got an int, dwPathLenConstraint is %d\n",
2523 constraint
->dwPathLenConstraint
);
2528 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2532 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2536 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2537 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2538 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2541 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2542 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2543 offsetof(CERT_NAME_BLOB
, pbData
) };
2544 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2546 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2547 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2549 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2550 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2551 entries
? entries
->rgItems
: NULL
);
2552 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2556 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2557 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2558 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2564 struct AsnDecodeSequenceItem items
[] = {
2565 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2566 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2567 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2568 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2569 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2570 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2571 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2572 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2573 sizeof(struct GenericArray
), TRUE
, TRUE
,
2574 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2577 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2578 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2579 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2583 SetLastError(STATUS_ACCESS_VIOLATION
);
2590 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2591 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2592 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2598 struct AsnDecodeSequenceItem items
[] = {
2599 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2600 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2601 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2602 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2603 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2606 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2607 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2608 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2612 SetLastError(STATUS_ACCESS_VIOLATION
);
2619 #define RSA1_MAGIC 0x31415352
2621 struct DECODED_RSA_PUB_KEY
2624 CRYPT_INTEGER_BLOB modulus
;
2627 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2628 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2629 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2635 struct AsnDecodeSequenceItem items
[] = {
2636 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2637 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2638 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2640 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2641 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2643 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2646 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2647 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2648 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
2651 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2652 decodedKey
->modulus
.cbData
;
2656 *pcbStructInfo
= bytesNeeded
;
2659 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2660 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2663 RSAPUBKEY
*rsaPubKey
;
2665 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2666 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2667 hdr
= (BLOBHEADER
*)pvStructInfo
;
2668 hdr
->bType
= PUBLICKEYBLOB
;
2669 hdr
->bVersion
= CUR_BLOB_VERSION
;
2671 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2672 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2673 sizeof(BLOBHEADER
));
2674 rsaPubKey
->magic
= RSA1_MAGIC
;
2675 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2676 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2677 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2678 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2679 decodedKey
->modulus
.cbData
);
2681 LocalFree(decodedKey
);
2686 SetLastError(STATUS_ACCESS_VIOLATION
);
2693 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2694 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2695 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2698 DWORD bytesNeeded
, dataLen
;
2700 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2701 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2703 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2705 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2706 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2708 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2710 *pcbStructInfo
= bytesNeeded
;
2711 else if (*pcbStructInfo
< bytesNeeded
)
2713 SetLastError(ERROR_MORE_DATA
);
2714 *pcbStructInfo
= bytesNeeded
;
2719 CRYPT_DATA_BLOB
*blob
;
2720 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2722 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2723 blob
->cbData
= dataLen
;
2724 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2725 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2728 assert(blob
->pbData
);
2730 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2738 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2739 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2740 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2744 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2745 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2753 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2756 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2758 SetLastError(CRYPT_E_ASN1_BADTAG
);
2761 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2762 lpszStructType
, pbEncoded
, cbEncoded
,
2763 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2766 *pcbStructInfo
= bytesNeeded
;
2767 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2768 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2770 CRYPT_DATA_BLOB
*blob
;
2772 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2773 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2774 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2775 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2776 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2777 lpszStructType
, pbEncoded
, cbEncoded
,
2778 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2785 SetLastError(STATUS_ACCESS_VIOLATION
);
2792 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2793 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2794 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2798 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2799 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2801 if (pbEncoded
[0] == ASN_BITSTRING
)
2803 DWORD bytesNeeded
, dataLen
;
2805 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2807 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2808 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2810 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2812 *pcbStructInfo
= bytesNeeded
;
2813 else if (*pcbStructInfo
< bytesNeeded
)
2815 *pcbStructInfo
= bytesNeeded
;
2816 SetLastError(ERROR_MORE_DATA
);
2821 CRYPT_BIT_BLOB
*blob
;
2823 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2824 blob
->cbData
= dataLen
- 1;
2825 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2826 GET_LEN_BYTES(pbEncoded
[1]));
2827 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2829 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2830 GET_LEN_BYTES(pbEncoded
[1]);
2834 assert(blob
->pbData
);
2837 BYTE mask
= 0xff << blob
->cUnusedBits
;
2839 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2840 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2841 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2849 SetLastError(CRYPT_E_ASN1_BADTAG
);
2852 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2856 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2857 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2858 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2862 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2863 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2869 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2870 lpszStructType
, pbEncoded
, cbEncoded
,
2871 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2874 *pcbStructInfo
= bytesNeeded
;
2875 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2876 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2878 CRYPT_BIT_BLOB
*blob
;
2880 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2881 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2882 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2883 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2884 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2885 lpszStructType
, pbEncoded
, cbEncoded
,
2886 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2893 SetLastError(STATUS_ACCESS_VIOLATION
);
2897 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2901 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2902 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2903 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2909 *pcbStructInfo
= sizeof(int);
2914 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2915 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2916 DWORD size
= sizeof(buf
);
2918 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2919 if (pbEncoded
[0] != ASN_INTEGER
)
2921 SetLastError(CRYPT_E_ASN1_BADTAG
);
2925 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2926 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
,
2930 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2931 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2935 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2936 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2937 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2939 /* initialize to a negative value to sign-extend */
2944 for (i
= 0; i
< blob
->cbData
; i
++)
2947 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2949 memcpy(pvStructInfo
, &val
, sizeof(int));
2952 else if (GetLastError() == ERROR_MORE_DATA
)
2953 SetLastError(CRYPT_E_ASN1_LARGE
);
2957 SetLastError(STATUS_ACCESS_VIOLATION
);
2964 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2965 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2966 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2969 DWORD bytesNeeded
, dataLen
;
2971 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2973 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2975 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2977 *pcbStructInfo
= bytesNeeded
;
2978 else if (*pcbStructInfo
< bytesNeeded
)
2980 *pcbStructInfo
= bytesNeeded
;
2981 SetLastError(ERROR_MORE_DATA
);
2986 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2988 blob
->cbData
= dataLen
;
2989 assert(blob
->pbData
);
2994 for (i
= 0; i
< blob
->cbData
; i
++)
2996 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3005 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3006 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3007 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3015 if (pbEncoded
[0] != ASN_INTEGER
)
3017 SetLastError(CRYPT_E_ASN1_BADTAG
);
3021 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
3022 lpszStructType
, pbEncoded
, cbEncoded
,
3023 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
);
3027 *pcbStructInfo
= bytesNeeded
;
3028 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3029 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3031 CRYPT_INTEGER_BLOB
*blob
;
3033 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3034 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3035 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3036 blob
->pbData
= (BYTE
*)pvStructInfo
+
3037 sizeof(CRYPT_INTEGER_BLOB
);
3038 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
3039 lpszStructType
, pbEncoded
, cbEncoded
,
3040 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3047 SetLastError(STATUS_ACCESS_VIOLATION
);
3054 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
3055 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3056 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3057 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3061 if (pbEncoded
[0] == ASN_INTEGER
)
3063 DWORD bytesNeeded
, dataLen
;
3065 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3067 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3069 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3071 *pcbStructInfo
= bytesNeeded
;
3072 else if (*pcbStructInfo
< bytesNeeded
)
3074 *pcbStructInfo
= bytesNeeded
;
3075 SetLastError(ERROR_MORE_DATA
);
3080 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3082 blob
->cbData
= dataLen
;
3083 assert(blob
->pbData
);
3084 /* remove leading zero byte if it exists */
3085 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3094 for (i
= 0; i
< blob
->cbData
; i
++)
3096 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3105 SetLastError(CRYPT_E_ASN1_BADTAG
);
3111 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3112 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3113 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3121 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3122 lpszStructType
, pbEncoded
, cbEncoded
,
3123 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
3126 *pcbStructInfo
= bytesNeeded
;
3127 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3128 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3130 CRYPT_INTEGER_BLOB
*blob
;
3132 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3133 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3134 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3135 blob
->pbData
= (BYTE
*)pvStructInfo
+
3136 sizeof(CRYPT_INTEGER_BLOB
);
3137 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3138 lpszStructType
, pbEncoded
, cbEncoded
,
3139 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3146 SetLastError(STATUS_ACCESS_VIOLATION
);
3153 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3154 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3155 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3161 *pcbStructInfo
= sizeof(int);
3166 if (pbEncoded
[0] == ASN_ENUMERATED
)
3168 unsigned int val
= 0, i
;
3172 SetLastError(CRYPT_E_ASN1_EOD
);
3175 else if (pbEncoded
[1] == 0)
3177 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3182 /* A little strange looking, but we have to accept a sign byte:
3183 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3184 * assuming a small length is okay here, it has to be in short
3187 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3189 SetLastError(CRYPT_E_ASN1_LARGE
);
3192 for (i
= 0; i
< pbEncoded
[1]; i
++)
3195 val
|= pbEncoded
[2 + i
];
3197 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3198 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3200 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3201 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3202 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3208 SetLastError(CRYPT_E_ASN1_BADTAG
);
3214 SetLastError(STATUS_ACCESS_VIOLATION
);
3221 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3224 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3229 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3231 if (!isdigit(*(pbEncoded))) \
3233 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3239 (word) += *(pbEncoded)++ - '0'; \
3244 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3245 SYSTEMTIME
*sysTime
)
3252 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3254 WORD hours
, minutes
= 0;
3255 BYTE sign
= *pbEncoded
++;
3258 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3259 if (ret
&& hours
>= 24)
3261 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3266 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3267 if (ret
&& minutes
>= 60)
3269 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3277 sysTime
->wHour
+= hours
;
3278 sysTime
->wMinute
+= minutes
;
3282 if (hours
> sysTime
->wHour
)
3285 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3288 sysTime
->wHour
-= hours
;
3289 if (minutes
> sysTime
->wMinute
)
3292 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3295 sysTime
->wMinute
-= minutes
;
3302 SetLastError(STATUS_ACCESS_VIOLATION
);
3309 #define MIN_ENCODED_TIME_LENGTH 10
3311 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3312 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3313 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3319 *pcbStructInfo
= sizeof(FILETIME
);
3325 if (pbEncoded
[0] == ASN_UTCTIME
)
3329 SetLastError(CRYPT_E_ASN1_EOD
);
3332 else if (pbEncoded
[1] > 0x7f)
3334 /* long-form date strings really can't be valid */
3335 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3340 SYSTEMTIME sysTime
= { 0 };
3341 BYTE len
= pbEncoded
[1];
3343 if (len
< MIN_ENCODED_TIME_LENGTH
)
3345 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3351 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3352 if (sysTime
.wYear
>= 50)
3353 sysTime
.wYear
+= 1900;
3355 sysTime
.wYear
+= 2000;
3356 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3357 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3358 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3359 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3362 if (len
>= 2 && isdigit(*pbEncoded
) &&
3363 isdigit(*(pbEncoded
+ 1)))
3364 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3366 else if (isdigit(*pbEncoded
))
3367 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3370 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3373 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3374 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3377 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3378 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3379 ret
= SystemTimeToFileTime(&sysTime
,
3380 (FILETIME
*)pvStructInfo
);
3387 SetLastError(CRYPT_E_ASN1_BADTAG
);
3393 SetLastError(STATUS_ACCESS_VIOLATION
);
3400 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
3401 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3402 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3408 *pcbStructInfo
= sizeof(FILETIME
);
3414 if (pbEncoded
[0] == ASN_GENERALTIME
)
3418 SetLastError(CRYPT_E_ASN1_EOD
);
3421 else if (pbEncoded
[1] > 0x7f)
3423 /* long-form date strings really can't be valid */
3424 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3429 BYTE len
= pbEncoded
[1];
3431 if (len
< MIN_ENCODED_TIME_LENGTH
)
3433 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3438 SYSTEMTIME sysTime
= { 0 };
3441 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3442 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3443 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3444 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3447 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3450 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3452 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3459 /* workaround macro weirdness */
3460 digits
= min(len
, 3);
3461 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3462 sysTime
.wMilliseconds
);
3465 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3468 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3469 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3472 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3473 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3474 ret
= SystemTimeToFileTime(&sysTime
,
3475 (FILETIME
*)pvStructInfo
);
3482 SetLastError(CRYPT_E_ASN1_BADTAG
);
3488 SetLastError(STATUS_ACCESS_VIOLATION
);
3495 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3496 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3497 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3503 if (pbEncoded
[0] == ASN_UTCTIME
)
3504 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
3505 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3507 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3508 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
3509 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
3510 pvStructInfo
, pcbStructInfo
);
3513 SetLastError(CRYPT_E_ASN1_BADTAG
);
3519 SetLastError(STATUS_ACCESS_VIOLATION
);
3526 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3527 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3528 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3534 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3536 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3538 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3543 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3544 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3546 ptr
= pbEncoded
+ 1 + lenBytes
;
3547 remainingLen
= dataLen
;
3548 while (ret
&& remainingLen
)
3552 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3555 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3557 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3558 ptr
+= 1 + nextLenBytes
+ nextLen
;
3559 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3560 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3561 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3567 CRYPT_SEQUENCE_OF_ANY
*seq
;
3571 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3572 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3574 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3575 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3576 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3577 seq
->cValue
= cValue
;
3578 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3580 nextPtr
= (BYTE
*)seq
->rgValue
+
3581 cValue
* sizeof(CRYPT_DER_BLOB
);
3582 ptr
= pbEncoded
+ 1 + lenBytes
;
3583 remainingLen
= dataLen
;
3585 while (ret
&& remainingLen
)
3589 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3592 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3594 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3596 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3597 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3600 seq
->rgValue
[i
].pbData
= nextPtr
;
3601 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3603 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3605 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3606 ptr
+= 1 + nextLenBytes
+ nextLen
;
3616 SetLastError(CRYPT_E_ASN1_BADTAG
);
3622 SetLastError(STATUS_ACCESS_VIOLATION
);
3629 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3630 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3631 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3635 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3637 DWORD bytesNeeded
, dataLen
;
3639 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3641 struct AsnArrayDescriptor arrayDesc
= {
3642 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3643 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3644 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3645 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3651 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3652 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3653 0, NULL
, NULL
, &nameLen
, NULL
);
3654 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3657 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3659 *pcbStructInfo
= bytesNeeded
;
3660 else if (*pcbStructInfo
< bytesNeeded
)
3662 *pcbStructInfo
= bytesNeeded
;
3663 SetLastError(ERROR_MORE_DATA
);
3668 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3672 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3673 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3674 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3675 0, NULL
, &name
->u
.FullName
, pcbStructInfo
,
3676 name
->u
.FullName
.rgAltEntry
);
3679 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3685 SetLastError(CRYPT_E_ASN1_BADTAG
);
3691 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
3692 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3693 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3695 struct AsnDecodeSequenceItem items
[] = {
3696 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3697 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3698 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3699 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3700 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3701 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3702 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3703 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3704 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3705 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3709 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3710 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3711 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3715 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3716 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3717 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3721 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3722 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3726 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3727 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3728 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3730 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3731 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3735 SetLastError(STATUS_ACCESS_VIOLATION
);
3742 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3743 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3744 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3748 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3749 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3753 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3754 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3756 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3757 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3761 SetLastError(STATUS_ACCESS_VIOLATION
);
3768 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3769 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3770 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3774 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3775 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3779 struct AsnDecodeSequenceItem items
[] = {
3780 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3781 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3782 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3783 offsetof(CRL_ISSUING_DIST_POINT
,
3784 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3785 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3786 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3788 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
3789 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3791 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
3792 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
3793 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
3794 OnlySomeReasonFlags
.pbData
), 0 },
3795 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
3796 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
3799 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3800 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3801 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3805 SetLastError(STATUS_ACCESS_VIOLATION
);
3812 static BOOL WINAPI
CRYPT_AsnDecodeIssuerSerialNumber(DWORD dwCertEncodingType
,
3813 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3814 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3817 struct AsnDecodeSequenceItem items
[] = {
3818 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
3819 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
3821 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
3822 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
3823 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
3825 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
3826 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
3828 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3829 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3831 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3832 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3833 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
3834 issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
3835 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
3837 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3840 TRACE("returning %d\n", ret
);
3844 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfoInternal(
3845 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3846 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3847 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3849 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
3850 struct AsnDecodeSequenceItem items
[] = {
3851 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
3852 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3853 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
3854 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
3855 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
3856 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
3857 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3858 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
3859 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
3860 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
3861 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3862 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
3863 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
3864 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3865 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
3866 HashEncryptionAlgorithm
.pszObjId
), 0 },
3867 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
3868 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
3869 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
3870 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
3871 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
3872 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3873 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
3877 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3878 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3880 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3881 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3882 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
3883 info
? info
->Issuer
.pbData
: NULL
);
3887 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
3888 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3889 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3893 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3894 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3898 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(dwCertEncodingType
,
3899 lpszStructType
, pbEncoded
, cbEncoded
,
3900 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
3901 if (ret
&& pvStructInfo
)
3903 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3904 pcbStructInfo
, *pcbStructInfo
);
3907 CMSG_SIGNER_INFO
*info
;
3909 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3910 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3911 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
3912 info
->Issuer
.pbData
= ((BYTE
*)info
+
3913 sizeof(CMSG_SIGNER_INFO
));
3914 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(dwCertEncodingType
,
3915 lpszStructType
, pbEncoded
, cbEncoded
,
3916 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3923 SetLastError(STATUS_ACCESS_VIOLATION
);
3926 TRACE("returning %d\n", ret
);
3930 static BOOL WINAPI
CRYPT_DecodeSignerArray(DWORD dwCertEncodingType
,
3931 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3932 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3935 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
3936 CRYPT_AsnDecodePKCSSignerInfoInternal
, sizeof(CMSG_SIGNER_INFO
), TRUE
,
3937 offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
) };
3938 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
3940 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3941 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3943 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3944 pDecodePara
, pvStructInfo
, pcbStructInfo
, array
? array
->rgItems
: NULL
);
3948 BOOL
CRYPT_AsnDecodePKCSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3949 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3950 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
3953 struct AsnDecodeSequenceItem items
[] = {
3954 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
), CRYPT_AsnDecodeInt
,
3955 sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3956 /* Placeholder for the hash algorithms - redundant with those in the
3957 * signers, so just ignore them.
3959 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
3960 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
3961 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
3962 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
3963 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
3964 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
3965 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
3966 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
3967 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
3968 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
3969 sizeof(struct GenericArray
), TRUE
, TRUE
,
3970 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
3971 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
3972 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
3973 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
3976 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3977 pDecodePara
, signedInfo
, *pcbSignedInfo
);
3979 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
3980 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
3981 pDecodePara
, signedInfo
, pcbSignedInfo
, NULL
);
3982 TRACE("returning %d\n", ret
);
3986 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
3987 LPCSTR lpszStructType
)
3989 CryptDecodeObjectExFunc decodeFunc
= NULL
;
3991 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
3992 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
3994 SetLastError(ERROR_FILE_NOT_FOUND
);
3997 if (!HIWORD(lpszStructType
))
3999 switch (LOWORD(lpszStructType
))
4001 case (WORD
)X509_CERT
:
4002 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
4004 case (WORD
)X509_CERT_TO_BE_SIGNED
:
4005 decodeFunc
= CRYPT_AsnDecodeCert
;
4007 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
4008 decodeFunc
= CRYPT_AsnDecodeCRL
;
4010 case (WORD
)X509_EXTENSIONS
:
4011 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4013 case (WORD
)X509_NAME_VALUE
:
4014 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4016 case (WORD
)X509_NAME
:
4017 decodeFunc
= CRYPT_AsnDecodeName
;
4019 case (WORD
)X509_PUBLIC_KEY_INFO
:
4020 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4022 case (WORD
)X509_AUTHORITY_KEY_ID
:
4023 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4025 case (WORD
)X509_ALTERNATE_NAME
:
4026 decodeFunc
= CRYPT_AsnDecodeAltName
;
4028 case (WORD
)X509_BASIC_CONSTRAINTS
:
4029 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4031 case (WORD
)X509_BASIC_CONSTRAINTS2
:
4032 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4034 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
4035 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4037 case (WORD
)X509_UNICODE_NAME
:
4038 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4040 case (WORD
)PKCS_ATTRIBUTE
:
4041 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4043 case (WORD
)X509_UNICODE_NAME_VALUE
:
4044 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4046 case (WORD
)X509_OCTET_STRING
:
4047 decodeFunc
= CRYPT_AsnDecodeOctets
;
4049 case (WORD
)X509_BITS
:
4050 case (WORD
)X509_KEY_USAGE
:
4051 decodeFunc
= CRYPT_AsnDecodeBits
;
4053 case (WORD
)X509_INTEGER
:
4054 decodeFunc
= CRYPT_AsnDecodeInt
;
4056 case (WORD
)X509_MULTI_BYTE_INTEGER
:
4057 decodeFunc
= CRYPT_AsnDecodeInteger
;
4059 case (WORD
)X509_MULTI_BYTE_UINT
:
4060 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4062 case (WORD
)X509_ENUMERATED
:
4063 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4065 case (WORD
)X509_CHOICE_OF_TIME
:
4066 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4068 case (WORD
)X509_AUTHORITY_KEY_ID2
:
4069 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4071 case (WORD
)PKCS_CONTENT_INFO
:
4072 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4074 case (WORD
)X509_SEQUENCE_OF_ANY
:
4075 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4077 case (WORD
)PKCS_UTC_TIME
:
4078 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4080 case (WORD
)X509_CRL_DIST_POINTS
:
4081 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4083 case (WORD
)X509_ENHANCED_KEY_USAGE
:
4084 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4086 case (WORD
)PKCS_ATTRIBUTES
:
4087 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4089 case (WORD
)X509_ISSUING_DIST_POINT
:
4090 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4092 case (WORD
)PKCS7_SIGNER_INFO
:
4093 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4097 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4098 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4099 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4100 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4101 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4102 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4103 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4104 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4105 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4106 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4107 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4108 decodeFunc
= CRYPT_AsnDecodeBits
;
4109 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4110 decodeFunc
= CRYPT_AsnDecodeOctets
;
4111 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4112 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4113 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4114 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4115 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4116 decodeFunc
= CRYPT_AsnDecodeAltName
;
4117 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4118 decodeFunc
= CRYPT_AsnDecodeAltName
;
4119 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4120 decodeFunc
= CRYPT_AsnDecodeAltName
;
4121 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4122 decodeFunc
= CRYPT_AsnDecodeAltName
;
4123 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4124 decodeFunc
= CRYPT_AsnDecodeAltName
;
4125 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4126 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4127 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4128 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4129 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4130 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4134 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
4135 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4137 static HCRYPTOIDFUNCSET set
= NULL
;
4138 CryptDecodeObjectFunc decodeFunc
= NULL
;
4141 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
4142 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4143 (void **)&decodeFunc
, hFunc
);
4147 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
4148 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4150 static HCRYPTOIDFUNCSET set
= NULL
;
4151 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4154 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4155 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4156 (void **)&decodeFunc
, hFunc
);
4160 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4161 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
4162 DWORD
*pcbStructInfo
)
4165 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
4166 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
4167 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4169 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
4170 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
4171 pvStructInfo
, pcbStructInfo
);
4173 if (!pvStructInfo
&& !pcbStructInfo
)
4175 SetLastError(ERROR_INVALID_PARAMETER
);
4180 SetLastError(CRYPT_E_ASN1_EOD
);
4183 if (cbEncoded
> MAX_ENCODED_LEN
)
4185 SetLastError(CRYPT_E_ASN1_LARGE
);
4189 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
4192 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4193 debugstr_a(lpszStructType
));
4194 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
4195 lpszStructType
, &hFunc
);
4196 if (!pCryptDecodeObject
)
4197 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
4198 lpszStructType
, &hFunc
);
4200 if (pCryptDecodeObject
)
4201 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4202 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4203 else if (pCryptDecodeObjectEx
)
4204 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
4205 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4206 pvStructInfo
, pcbStructInfo
);
4208 CryptFreeOIDFunctionAddress(hFunc
, 0);
4209 TRACE_(crypt
)("returning %d\n", ret
);
4213 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4214 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4215 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4218 CryptDecodeObjectExFunc decodeFunc
;
4219 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4221 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4222 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
4223 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4225 if (!pvStructInfo
&& !pcbStructInfo
)
4227 SetLastError(ERROR_INVALID_PARAMETER
);
4232 SetLastError(CRYPT_E_ASN1_EOD
);
4235 if (cbEncoded
> MAX_ENCODED_LEN
)
4237 SetLastError(CRYPT_E_ASN1_LARGE
);
4241 SetLastError(NOERROR
);
4242 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
4243 *(BYTE
**)pvStructInfo
= NULL
;
4244 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
4247 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4248 debugstr_a(lpszStructType
));
4249 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
4253 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
4254 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4257 CryptDecodeObjectFunc pCryptDecodeObject
=
4258 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
4260 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4261 * directly, as that could cause an infinite loop.
4263 if (pCryptDecodeObject
)
4265 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4267 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4268 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
4269 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4270 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
4271 ret
= pCryptDecodeObject(dwCertEncodingType
,
4272 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
4273 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
4276 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4277 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4281 CryptFreeOIDFunctionAddress(hFunc
, 0);
4282 TRACE_(crypt
)("returning %d\n", ret
);