Sync with trunk head (part 1 of 2)
[reactos.git] / dll / win32 / crypt32 / decode.c
1 /*
2 * Copyright 2005-2009 Juan Lang
3 *
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.
8 *
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.
13 *
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
17 *
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.
22 *
23 * References:
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.)
27 *
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
29 *
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
31 */
32
33 #include "config.h"
34 #include "wine/port.h"
35
36 #include <assert.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40
41 #define NONAMELESSUNION
42
43 #include "windef.h"
44 #include "winbase.h"
45 #include "wincrypt.h"
46 #include "winnls.h"
47 #include "snmp.h"
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
51
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
54
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
57
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt);
60
61 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
62 DWORD, DWORD, void *, DWORD *);
63 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
64 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
65
66 /* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
68 */
69 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
70 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
71
72 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
73 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
74 DWORD *pcbDecoded);
75 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
76 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
77 DWORD *pcbDecoded);
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
79 */
80 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
81 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
84 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
85 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
86 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
89 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
90 DWORD *pcbDecoded);
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
93 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
94 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
95 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
99 * it.
100 */
101 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
102 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
103 DWORD *pcbDecoded);
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
105 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
106 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
107 DWORD *pcbDecoded);
108 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110 DWORD *pcbDecoded);
111
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
114
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
120 */
121 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
122 DWORD *len)
123 {
124 BOOL ret;
125
126 if (cbEncoded <= 1)
127 {
128 SetLastError(CRYPT_E_ASN1_CORRUPT);
129 ret = FALSE;
130 }
131 else if (pbEncoded[1] <= 0x7f)
132 {
133 if (pbEncoded[1] + 1 > cbEncoded)
134 {
135 SetLastError(CRYPT_E_ASN1_EOD);
136 ret = FALSE;
137 }
138 else
139 {
140 *len = pbEncoded[1];
141 ret = TRUE;
142 }
143 }
144 else if (pbEncoded[1] == 0x80)
145 {
146 *len = CMSG_INDEFINITE_LENGTH;
147 ret = TRUE;
148 }
149 else
150 {
151 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
152
153 if (lenLen > sizeof(DWORD) + 1)
154 {
155 SetLastError(CRYPT_E_ASN1_LARGE);
156 ret = FALSE;
157 }
158 else if (lenLen + 2 > cbEncoded)
159 {
160 SetLastError(CRYPT_E_ASN1_CORRUPT);
161 ret = FALSE;
162 }
163 else
164 {
165 DWORD out = 0;
166
167 pbEncoded += 2;
168 while (--lenLen)
169 {
170 out <<= 8;
171 out |= *pbEncoded++;
172 }
173 if (out + lenLen + 1 > cbEncoded)
174 {
175 SetLastError(CRYPT_E_ASN1_EOD);
176 ret = FALSE;
177 }
178 else
179 {
180 *len = out;
181 ret = TRUE;
182 }
183 }
184 }
185 return ret;
186 }
187
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
190 {
191 BOOL ret;
192
193 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
194 *len == CMSG_INDEFINITE_LENGTH)
195 {
196 SetLastError(CRYPT_E_ASN1_CORRUPT);
197 ret = FALSE;
198 }
199 return ret;
200 }
201
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.
206 */
207 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
208 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
209 DWORD bytesNeeded)
210 {
211 BOOL ret = TRUE;
212
213 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
214 {
215 if (pDecodePara && pDecodePara->pfnAlloc)
216 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
217 else
218 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
219 if (!*(BYTE **)pvStructInfo)
220 ret = FALSE;
221 else
222 *pcbStructInfo = bytesNeeded;
223 }
224 else if (*pcbStructInfo < bytesNeeded)
225 {
226 *pcbStructInfo = bytesNeeded;
227 SetLastError(ERROR_MORE_DATA);
228 ret = FALSE;
229 }
230 else
231 *pcbStructInfo = bytesNeeded;
232 return ret;
233 }
234
235 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
236 {
237 if (pDecodePara && pDecodePara->pfnFree)
238 pDecodePara->pfnFree(pv);
239 else
240 LocalFree(pv);
241 }
242
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
245 */
246 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
247 {
248 BOOL ret;
249
250 if (*pcbStructInfo < bytesNeeded)
251 {
252 *pcbStructInfo = bytesNeeded;
253 SetLastError(ERROR_MORE_DATA);
254 ret = FALSE;
255 }
256 else
257 {
258 *pcbStructInfo = bytesNeeded;
259 ret = TRUE;
260 }
261 return ret;
262 }
263
264 /* tag:
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
267 * offset:
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
270 * decodeFunc:
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
273 * minSize:
274 * The minimum amount of space occupied after decoding. You must set this.
275 * optional:
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
283 * size:
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
285 */
286 struct AsnDecodeSequenceItem
287 {
288 BYTE tag;
289 DWORD offset;
290 InternalDecodeFunc decodeFunc;
291 DWORD minSize;
292 BOOL optional;
293 BOOL hasPointer;
294 DWORD pointerOffset;
295 DWORD size;
296 };
297
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
301
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
308 */
309 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
310 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
311 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
312 {
313 BOOL ret;
314 DWORD i, decoded = 0;
315 const BYTE *ptr = pbEncoded;
316
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
318 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
319
320 for (i = 0, ret = TRUE; ret && i < cItem; i++)
321 {
322 if (cbEncoded - (ptr - pbEncoded) != 0)
323 {
324 DWORD itemLen;
325
326 if ((ret = CRYPT_GetLengthIndefinite(ptr,
327 cbEncoded - (ptr - pbEncoded), &itemLen)))
328 {
329 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
330
331 if (ptr[0] == items[i].tag || !items[i].tag)
332 {
333 DWORD itemEncodedLen;
334
335 if (itemLen == CMSG_INDEFINITE_LENGTH)
336 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
337 else
338 itemEncodedLen = 1 + itemLenBytes + itemLen;
339 if (nextData && pvStructInfo && items[i].hasPointer)
340 {
341 TRACE("Setting next pointer to %p\n",
342 nextData);
343 *(BYTE **)((BYTE *)pvStructInfo +
344 items[i].pointerOffset) = nextData;
345 }
346 if (items[i].decodeFunc)
347 {
348 DWORD itemDecoded;
349
350 if (pvStructInfo)
351 TRACE("decoding item %d\n", i);
352 else
353 TRACE("sizing item %d\n", i);
354 ret = items[i].decodeFunc(ptr, itemEncodedLen,
355 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
356 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
357 : NULL, &items[i].size, &itemDecoded);
358 if (ret)
359 {
360 if (items[i].size < items[i].minSize)
361 items[i].size = items[i].minSize;
362 else if (items[i].size > items[i].minSize)
363 {
364 /* Account for alignment padding */
365 items[i].size = ALIGN_DWORD_PTR(items[i].size);
366 }
367 TRACE("item %d size: %d\n", i, items[i].size);
368 if (nextData && items[i].hasPointer &&
369 items[i].size > items[i].minSize)
370 nextData += items[i].size - items[i].minSize;
371 if (itemDecoded > itemEncodedLen)
372 {
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded, itemEncodedLen);
375 SetLastError(CRYPT_E_ASN1_CORRUPT);
376 ret = FALSE;
377 }
378 else
379 {
380 ptr += itemDecoded;
381 decoded += itemDecoded;
382 TRACE("item %d: decoded %d bytes\n", i,
383 itemDecoded);
384 }
385 }
386 else if (items[i].optional &&
387 GetLastError() == CRYPT_E_ASN1_BADTAG)
388 {
389 TRACE("skipping optional item %d\n", i);
390 items[i].size = items[i].minSize;
391 SetLastError(NOERROR);
392 ret = TRUE;
393 }
394 else
395 TRACE("item %d failed: %08x\n", i,
396 GetLastError());
397 }
398 else if (itemLen == CMSG_INDEFINITE_LENGTH)
399 {
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT);
402 ret = FALSE;
403 }
404 else
405 {
406 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
407 ptr += itemEncodedLen;
408 decoded += itemEncodedLen;
409 items[i].size = items[i].minSize;
410 }
411 }
412 else if (items[i].optional)
413 {
414 TRACE("skipping optional item %d\n", i);
415 items[i].size = items[i].minSize;
416 }
417 else
418 {
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i, ptr[0], items[i].tag);
421 SetLastError(CRYPT_E_ASN1_BADTAG);
422 ret = FALSE;
423 }
424 }
425 }
426 else if (items[i].optional)
427 {
428 TRACE("missing optional item %d, skipping\n", i);
429 items[i].size = items[i].minSize;
430 }
431 else
432 {
433 TRACE("not enough bytes for item %d, failing\n", i);
434 SetLastError(CRYPT_E_ASN1_CORRUPT);
435 ret = FALSE;
436 }
437 }
438 if (cbDecoded)
439 *cbDecoded = decoded;
440 TRACE("returning %d\n", ret);
441 return ret;
442 }
443
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
450 */
451 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
452 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
454 DWORD *pcbDecoded, void *startingPointer)
455 {
456 BOOL ret;
457
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
459 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
460 startingPointer);
461
462 if (!cbEncoded)
463 {
464 SetLastError(CRYPT_E_ASN1_EOD);
465 return FALSE;
466 }
467 if (pbEncoded[0] == ASN_SEQUENCE)
468 {
469 DWORD dataLen;
470
471 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
472 {
473 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
474 const BYTE *ptr = pbEncoded + 1 + lenBytes;
475 BOOL indefinite = FALSE;
476
477 cbEncoded -= 1 + lenBytes;
478 if (dataLen == CMSG_INDEFINITE_LENGTH)
479 {
480 dataLen = cbEncoded;
481 indefinite = TRUE;
482 }
483 else if (cbEncoded < dataLen)
484 {
485 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
486 cbEncoded);
487 SetLastError(CRYPT_E_ASN1_CORRUPT);
488 ret = FALSE;
489 }
490 if (ret)
491 {
492 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
493 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
494 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
495 {
496 if (cbDecoded > cbEncoded - 2)
497 {
498 /* Not enough space for 0 TLV */
499 SetLastError(CRYPT_E_ASN1_CORRUPT);
500 ret = FALSE;
501 }
502 else if (*(ptr + cbDecoded) != 0 ||
503 *(ptr + cbDecoded + 1) != 0)
504 {
505 TRACE("expected 0 TLV\n");
506 SetLastError(CRYPT_E_ASN1_CORRUPT);
507 ret = FALSE;
508 }
509 else
510 cbDecoded += 2;
511 }
512 }
513 if (ret && !indefinite && cbDecoded != dataLen)
514 {
515 TRACE("expected %d decoded, got %d, failing\n", dataLen,
516 cbDecoded);
517 SetLastError(CRYPT_E_ASN1_CORRUPT);
518 ret = FALSE;
519 }
520 if (ret)
521 {
522 DWORD i, bytesNeeded = 0, structSize = 0;
523
524 for (i = 0; i < cItem; i++)
525 {
526 if (items[i].size > items[i].minSize)
527 bytesNeeded += items[i].size - items[i].minSize;
528 structSize = max( structSize, items[i].offset + items[i].minSize );
529 }
530 bytesNeeded += structSize;
531 if (pcbDecoded)
532 *pcbDecoded = 1 + lenBytes + cbDecoded;
533 if (!pvStructInfo)
534 *pcbStructInfo = bytesNeeded;
535 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
536 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
537 {
538 BYTE *nextData;
539
540 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
541 pvStructInfo = *(BYTE **)pvStructInfo;
542 if (startingPointer)
543 nextData = startingPointer;
544 else
545 nextData = (BYTE *)pvStructInfo + structSize;
546 memset(pvStructInfo, 0, structSize);
547 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
548 ptr, dataLen, dwFlags, pvStructInfo, nextData,
549 &cbDecoded);
550 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
551 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
552 }
553 }
554 }
555 }
556 else
557 {
558 SetLastError(CRYPT_E_ASN1_BADTAG);
559 ret = FALSE;
560 }
561 TRACE("returning %d (%08x)\n", ret, GetLastError());
562 return ret;
563 }
564
565 /* tag:
566 * The expected tag of the entire encoded array (usually a variant
567 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
568 * regardless of the tag seen.
569 * countOffset:
570 * The offset within the outer structure at which the count exists.
571 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
572 * while CRYPT_ATTRIBUTE has countOffset ==
573 * offsetof(CRYPT_ATTRIBUTE, cValue).
574 * arrayOffset:
575 * The offset within the outer structure at which the array pointer exists.
576 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
577 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
578 * minArraySize:
579 * The minimum size of the decoded array. On WIN32, this is always 8:
580 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
581 * alignment.
582 * decodeFunc:
583 * used to decode each item in the array
584 * itemSize:
585 * is the minimum size of each decoded item
586 * hasPointer:
587 * indicates whether each item has a dynamic pointer
588 * pointerOffset:
589 * indicates the offset within itemSize at which the pointer exists
590 */
591 struct AsnArrayDescriptor
592 {
593 BYTE tag;
594 DWORD countOffset;
595 DWORD arrayOffset;
596 DWORD minArraySize;
597 InternalDecodeFunc decodeFunc;
598 DWORD itemSize;
599 BOOL hasPointer;
600 DWORD pointerOffset;
601 };
602
603 struct AsnArrayItemSize
604 {
605 DWORD encodedLen;
606 DWORD size;
607 };
608
609 /* Decodes an array of like types into a structure described by a struct
610 * AsnArrayDescriptor.
611 */
612 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
613 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
614 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
615 DWORD *pcbDecoded)
616 {
617 BOOL ret = TRUE;
618
619 TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
620 cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
621
622 if (!cbEncoded)
623 {
624 SetLastError(CRYPT_E_ASN1_EOD);
625 ret = FALSE;
626 }
627 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
628 {
629 DWORD dataLen;
630
631 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
632 {
633 DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
634 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
635 /* There can be arbitrarily many items, but there is often only one.
636 */
637 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
638
639 decoded = 1 + lenBytes;
640 if (dataLen)
641 {
642 const BYTE *ptr;
643 BOOL doneDecoding = FALSE;
644
645 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
646 {
647 if (dataLen == CMSG_INDEFINITE_LENGTH)
648 {
649 if (ptr[0] == 0)
650 {
651 doneDecoding = TRUE;
652 if (ptr[1] != 0)
653 {
654 SetLastError(CRYPT_E_ASN1_CORRUPT);
655 ret = FALSE;
656 }
657 else
658 decoded += 2;
659 }
660 }
661 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
662 doneDecoding = TRUE;
663 if (!doneDecoding)
664 {
665 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
666
667 /* Each item decoded may not tolerate extraneous bytes,
668 * so get the length of the next element if known.
669 */
670 if ((ret = CRYPT_GetLengthIndefinite(ptr,
671 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
672 {
673 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
674 itemEncoded = cbEncoded - (ptr - pbEncoded);
675 else
676 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
677 itemDataLen;
678 }
679 if (ret)
680 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
681 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
682 &itemDecoded);
683 if (ret)
684 {
685 cItems++;
686 if (itemSizes != &itemSize)
687 itemSizes = CryptMemRealloc(itemSizes,
688 cItems * sizeof(struct AsnArrayItemSize));
689 else if (cItems > 1)
690 {
691 itemSizes =
692 CryptMemAlloc(
693 cItems * sizeof(struct AsnArrayItemSize));
694 if (itemSizes)
695 memcpy(itemSizes, &itemSize,
696 sizeof(itemSize));
697 }
698 if (itemSizes)
699 {
700 decoded += itemDecoded;
701 itemSizes[cItems - 1].encodedLen = itemEncoded;
702 itemSizes[cItems - 1].size = size;
703 bytesNeeded += size;
704 ptr += itemEncoded;
705 }
706 else
707 ret = FALSE;
708 }
709 }
710 }
711 }
712 if (ret)
713 {
714 if (pcbDecoded)
715 *pcbDecoded = decoded;
716 if (!pvStructInfo)
717 *pcbStructInfo = bytesNeeded;
718 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
719 pvStructInfo, pcbStructInfo, bytesNeeded)))
720 {
721 DWORD i, *pcItems;
722 BYTE *nextData;
723 const BYTE *ptr;
724 void *rgItems;
725
726 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
727 pvStructInfo = *(void **)pvStructInfo;
728 pcItems = pvStructInfo;
729 *pcItems = cItems;
730 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
731 {
732 rgItems = (BYTE *)pvStructInfo +
733 arrayDesc->minArraySize;
734 *(void **)((BYTE *)pcItems -
735 arrayDesc->countOffset + arrayDesc->arrayOffset) =
736 rgItems;
737 }
738 else
739 rgItems = *(void **)((BYTE *)pcItems -
740 arrayDesc->countOffset + arrayDesc->arrayOffset);
741 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
742 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
743 i < cItems && ptr - pbEncoded - 1 - lenBytes <
744 dataLen; i++)
745 {
746 DWORD itemDecoded;
747
748 if (arrayDesc->hasPointer)
749 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
750 + arrayDesc->pointerOffset) = nextData;
751 ret = arrayDesc->decodeFunc(ptr,
752 itemSizes[i].encodedLen,
753 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
754 (BYTE *)rgItems + i * arrayDesc->itemSize,
755 &itemSizes[i].size, &itemDecoded);
756 if (ret)
757 {
758 nextData += itemSizes[i].size - arrayDesc->itemSize;
759 ptr += itemDecoded;
760 }
761 }
762 }
763 }
764 if (itemSizes != &itemSize)
765 CryptMemFree(itemSizes);
766 }
767 }
768 else
769 {
770 SetLastError(CRYPT_E_ASN1_BADTAG);
771 ret = FALSE;
772 }
773 return ret;
774 }
775
776 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
777 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
778 * to CRYPT_E_ASN1_CORRUPT.
779 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
780 * set!
781 */
782 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
783 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
784 {
785 BOOL ret;
786 DWORD dataLen;
787
788 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
789 {
790 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
791 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
792
793 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
794 bytesNeeded += 1 + lenBytes + dataLen;
795
796 if (pcbDecoded)
797 *pcbDecoded = 1 + lenBytes + dataLen;
798 if (!pvStructInfo)
799 *pcbStructInfo = bytesNeeded;
800 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
801 {
802 CRYPT_DER_BLOB *blob;
803
804 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
805 pvStructInfo = *(BYTE **)pvStructInfo;
806 blob = pvStructInfo;
807 blob->cbData = 1 + lenBytes + dataLen;
808 if (blob->cbData)
809 {
810 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
811 blob->pbData = (BYTE *)pbEncoded;
812 else
813 {
814 assert(blob->pbData);
815 memcpy(blob->pbData, pbEncoded, blob->cbData);
816 }
817 }
818 else
819 {
820 SetLastError(CRYPT_E_ASN1_CORRUPT);
821 ret = FALSE;
822 }
823 }
824 }
825 return ret;
826 }
827
828 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
829 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
830 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
831 DWORD *pcbDecoded)
832 {
833 BOOL ret;
834
835 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
836 pvStructInfo, *pcbStructInfo, pcbDecoded);
837
838 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
839 * place.
840 */
841 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
842 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
843 pcbDecoded);
844 if (ret && pvStructInfo)
845 {
846 CRYPT_BIT_BLOB *blob = pvStructInfo;
847
848 if (blob->cbData)
849 {
850 DWORD i;
851 BYTE temp;
852
853 for (i = 0; i < blob->cbData / 2; i++)
854 {
855 temp = blob->pbData[i];
856 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
857 blob->pbData[blob->cbData - i - 1] = temp;
858 }
859 }
860 }
861 TRACE("returning %d (%08x)\n", ret, GetLastError());
862 return ret;
863 }
864
865 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
866 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
867 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
868 {
869 BOOL ret = TRUE;
870
871 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
872 pDecodePara, pvStructInfo, *pcbStructInfo);
873
874 __TRY
875 {
876 struct AsnDecodeSequenceItem items[] = {
877 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
878 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
879 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
880 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
881 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
882 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
883 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
884 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
885 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
886 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
887 };
888
889 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
890 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
891 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
892 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
893 pcbStructInfo, NULL, NULL);
894 }
895 __EXCEPT_PAGE_FAULT
896 {
897 SetLastError(STATUS_ACCESS_VIOLATION);
898 ret = FALSE;
899 }
900 __ENDTRY
901
902 TRACE("Returning %d (%08x)\n", ret, GetLastError());
903 return ret;
904 }
905
906 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
907 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
908 {
909 BOOL ret;
910 DWORD dataLen;
911
912 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
913 {
914 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
915
916 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
917 dwFlags, pvStructInfo, pcbStructInfo, NULL);
918 if (pcbDecoded)
919 *pcbDecoded = 1 + lenBytes + dataLen;
920 }
921 return ret;
922 }
923
924 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
925 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
926 {
927 BOOL ret;
928
929 struct AsnDecodeSequenceItem items[] = {
930 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
931 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
933 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
934 };
935
936 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
937 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
938 pcbDecoded, NULL);
939 return ret;
940 }
941
942 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
943 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
944 DWORD *pcbDecoded)
945 {
946 BOOL ret = TRUE;
947 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
948 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
949 FINALMEMBERSIZE(CERT_INFO, cExtension),
950 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
951 offsetof(CERT_EXTENSION, pszObjId) };
952
953 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
954 pvStructInfo, *pcbStructInfo, pcbDecoded);
955
956 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
957 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
958 return ret;
959 }
960
961 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
962 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
963 DWORD *pcbDecoded)
964 {
965 BOOL ret;
966 DWORD dataLen;
967
968 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
969 {
970 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
971
972 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
973 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
974 if (ret && pcbDecoded)
975 *pcbDecoded = 1 + lenBytes + dataLen;
976 }
977 return ret;
978 }
979
980 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
981 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
982 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
983 {
984 BOOL ret = TRUE;
985 struct AsnDecodeSequenceItem items[] = {
986 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
987 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
988 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
989 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
990 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
991 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
992 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
993 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
994 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
995 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
996 Issuer.pbData) },
997 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
998 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
999 FALSE, 0 },
1000 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1001 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1002 Subject.pbData) },
1003 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1004 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
1005 FALSE, TRUE, offsetof(CERT_INFO,
1006 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1007 { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
1008 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1009 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1010 { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId),
1011 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1012 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1013 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1014 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1015 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1016 };
1017
1018 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1019 pDecodePara, pvStructInfo, *pcbStructInfo);
1020
1021 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1022 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1023 NULL, NULL);
1024 if (ret && pvStructInfo)
1025 {
1026 CERT_INFO *info;
1027
1028 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1029 info = *(CERT_INFO **)pvStructInfo;
1030 else
1031 info = pvStructInfo;
1032 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1033 !info->Subject.cbData)
1034 {
1035 SetLastError(CRYPT_E_ASN1_CORRUPT);
1036 /* Don't need to deallocate, because it should have failed on the
1037 * first pass (and no memory was allocated.)
1038 */
1039 ret = FALSE;
1040 }
1041 }
1042
1043 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1044 return ret;
1045 }
1046
1047 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1048 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1049 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1050 {
1051 BOOL ret = FALSE;
1052
1053 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1054 pDecodePara, pvStructInfo, *pcbStructInfo);
1055
1056 __TRY
1057 {
1058 DWORD size = 0;
1059
1060 /* Unless told not to, first try to decode it as a signed cert. */
1061 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1062 {
1063 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1064
1065 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1066 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1067 &signedCert, &size);
1068 if (ret)
1069 {
1070 size = 0;
1071 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1072 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1073 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1074 pvStructInfo, pcbStructInfo);
1075 LocalFree(signedCert);
1076 }
1077 }
1078 /* Failing that, try it as an unsigned cert */
1079 if (!ret)
1080 {
1081 size = 0;
1082 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1083 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1084 pDecodePara, pvStructInfo, pcbStructInfo);
1085 }
1086 }
1087 __EXCEPT_PAGE_FAULT
1088 {
1089 SetLastError(STATUS_ACCESS_VIOLATION);
1090 }
1091 __ENDTRY
1092
1093 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1094 return ret;
1095 }
1096
1097 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1098 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1099 DWORD *pcbDecoded)
1100 {
1101 BOOL ret = TRUE;
1102 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1103 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1104 FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1105 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1106 offsetof(CERT_EXTENSION, pszObjId) };
1107
1108 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1109 pvStructInfo, *pcbStructInfo, pcbDecoded);
1110
1111 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1112 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1113 return ret;
1114 }
1115
1116 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1117 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1118 {
1119 BOOL ret;
1120 struct AsnDecodeSequenceItem items[] = {
1121 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1122 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1123 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1124 { 0, offsetof(CRL_ENTRY, RevocationDate),
1125 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1126 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1127 CRYPT_AsnDecodeCRLEntryExtensions,
1128 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1129 offsetof(CRL_ENTRY, rgExtension), 0 },
1130 };
1131 PCRL_ENTRY entry = pvStructInfo;
1132
1133 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1134 *pcbStructInfo);
1135
1136 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1137 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1138 entry ? entry->SerialNumber.pbData : NULL);
1139 if (ret && entry && !entry->SerialNumber.cbData)
1140 {
1141 WARN("empty CRL entry serial number\n");
1142 SetLastError(CRYPT_E_ASN1_CORRUPT);
1143 ret = FALSE;
1144 }
1145 return ret;
1146 }
1147
1148 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1149 * whose rgCRLEntry member has been set prior to calling.
1150 */
1151 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1152 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1153 {
1154 BOOL ret;
1155 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1156 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1157 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1158 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1159 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1160
1161 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1162 pvStructInfo, *pcbStructInfo, pcbDecoded);
1163
1164 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1165 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1166 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1167 return ret;
1168 }
1169
1170 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1171 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1172 DWORD *pcbDecoded)
1173 {
1174 BOOL ret = TRUE;
1175 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1176 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1177 FINALMEMBERSIZE(CRL_INFO, cExtension),
1178 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1179 offsetof(CERT_EXTENSION, pszObjId) };
1180
1181 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1182 pvStructInfo, *pcbStructInfo, pcbDecoded);
1183
1184 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1185 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1186 return ret;
1187 }
1188
1189 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1190 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1191 DWORD *pcbDecoded)
1192 {
1193 BOOL ret;
1194 DWORD dataLen;
1195
1196 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1197 {
1198 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1199
1200 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1201 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1202 if (ret && pcbDecoded)
1203 *pcbDecoded = 1 + lenBytes + dataLen;
1204 }
1205 return ret;
1206 }
1207
1208 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1209 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1210 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1211 {
1212 struct AsnDecodeSequenceItem items[] = {
1213 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1214 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1215 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1216 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1217 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1218 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1219 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1220 Issuer.pbData) },
1221 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1222 sizeof(FILETIME), FALSE, FALSE, 0 },
1223 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1224 sizeof(FILETIME), TRUE, FALSE, 0 },
1225 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1226 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1227 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1228 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1229 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1230 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1231 };
1232 BOOL ret = TRUE;
1233
1234 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1235 pDecodePara, pvStructInfo, *pcbStructInfo);
1236
1237 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1238 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1239 NULL, NULL);
1240
1241 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1242 return ret;
1243 }
1244
1245 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1246 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1247 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1248 {
1249 BOOL ret = FALSE;
1250
1251 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1252 pDecodePara, pvStructInfo, *pcbStructInfo);
1253
1254 __TRY
1255 {
1256 DWORD size = 0;
1257
1258 /* Unless told not to, first try to decode it as a signed crl. */
1259 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1260 {
1261 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1262
1263 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1264 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1265 &signedCrl, &size);
1266 if (ret)
1267 {
1268 size = 0;
1269 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1270 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1271 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1272 pvStructInfo, pcbStructInfo);
1273 LocalFree(signedCrl);
1274 }
1275 }
1276 /* Failing that, try it as an unsigned crl */
1277 if (!ret)
1278 {
1279 size = 0;
1280 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1281 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1282 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1283 }
1284 }
1285 __EXCEPT_PAGE_FAULT
1286 {
1287 SetLastError(STATUS_ACCESS_VIOLATION);
1288 }
1289 __ENDTRY
1290
1291 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1292 return ret;
1293 }
1294
1295 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1296 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1297 {
1298 BOOL ret = TRUE;
1299 DWORD dataLen;
1300
1301 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1302 pvStructInfo, *pcbStructInfo);
1303
1304 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1305 {
1306 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1307 DWORD bytesNeeded = sizeof(LPSTR);
1308
1309 if (dataLen)
1310 {
1311 /* The largest possible string for the first two components
1312 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1313 */
1314 char firstTwo[6];
1315 const BYTE *ptr;
1316
1317 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1318 pbEncoded[1 + lenBytes] / 40,
1319 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1320 * 40);
1321 bytesNeeded += strlen(firstTwo) + 1;
1322 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1323 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1324 {
1325 /* large enough for ".4000000" */
1326 char str[9];
1327 int val = 0;
1328
1329 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1330 (*ptr & 0x80))
1331 {
1332 val <<= 7;
1333 val |= *ptr & 0x7f;
1334 ptr++;
1335 }
1336 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1337 (*ptr & 0x80))
1338 {
1339 SetLastError(CRYPT_E_ASN1_CORRUPT);
1340 ret = FALSE;
1341 }
1342 else
1343 {
1344 val <<= 7;
1345 val |= *ptr++;
1346 snprintf(str, sizeof(str), ".%d", val);
1347 bytesNeeded += strlen(str);
1348 }
1349 }
1350 }
1351 if (pcbDecoded)
1352 *pcbDecoded = 1 + lenBytes + dataLen;
1353 if (!pvStructInfo)
1354 *pcbStructInfo = bytesNeeded;
1355 else if (*pcbStructInfo < bytesNeeded)
1356 {
1357 *pcbStructInfo = bytesNeeded;
1358 SetLastError(ERROR_MORE_DATA);
1359 ret = FALSE;
1360 }
1361 else
1362 {
1363 if (dataLen)
1364 {
1365 const BYTE *ptr;
1366 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1367
1368 *pszObjId = 0;
1369 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1370 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1371 40) * 40);
1372 pszObjId += strlen(pszObjId);
1373 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1374 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1375 {
1376 int val = 0;
1377
1378 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1379 (*ptr & 0x80))
1380 {
1381 val <<= 7;
1382 val |= *ptr & 0x7f;
1383 ptr++;
1384 }
1385 val <<= 7;
1386 val |= *ptr++;
1387 sprintf(pszObjId, ".%d", val);
1388 pszObjId += strlen(pszObjId);
1389 }
1390 }
1391 else
1392 *(LPSTR *)pvStructInfo = NULL;
1393 *pcbStructInfo = bytesNeeded;
1394 }
1395 }
1396 return ret;
1397 }
1398
1399 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1400 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1401 {
1402 BOOL ret;
1403
1404 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1405 pvStructInfo, *pcbStructInfo);
1406
1407 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1408 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1409 pvStructInfo, pcbStructInfo, pcbDecoded);
1410 else
1411 {
1412 SetLastError(CRYPT_E_ASN1_BADTAG);
1413 ret = FALSE;
1414 }
1415 return ret;
1416 }
1417
1418 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1419 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1420 {
1421 struct AsnDecodeSequenceItem items[] = {
1422 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1423 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1424 offsetof(CERT_EXTENSION, pszObjId), 0 },
1425 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1426 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1427 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1428 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1429 offsetof(CERT_EXTENSION, Value.pbData) },
1430 };
1431 BOOL ret = TRUE;
1432 PCERT_EXTENSION ext = pvStructInfo;
1433
1434 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1435 *pcbStructInfo);
1436
1437 if (ext)
1438 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1439 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1440 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1441 pcbDecoded, ext ? ext->pszObjId : NULL);
1442 if (ext)
1443 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1444 debugstr_a(ext->pszObjId));
1445 TRACE("returning %d (%08x)\n", ret, GetLastError());
1446 return ret;
1447 }
1448
1449 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1450 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1451 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1452 {
1453 BOOL ret = TRUE;
1454
1455 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1456 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1457
1458 __TRY
1459 {
1460 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1461 offsetof(CERT_EXTENSIONS, cExtension),
1462 offsetof(CERT_EXTENSIONS, rgExtension),
1463 sizeof(CERT_EXTENSIONS),
1464 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1465 offsetof(CERT_EXTENSION, pszObjId) };
1466
1467 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1468 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1469 }
1470 __EXCEPT_PAGE_FAULT
1471 {
1472 SetLastError(STATUS_ACCESS_VIOLATION);
1473 ret = FALSE;
1474 }
1475 __ENDTRY
1476 return ret;
1477 }
1478
1479 /* Warning: this assumes the address of value->Value.pbData is already set, in
1480 * order to avoid overwriting memory. (In some cases, it may change it, if it
1481 * doesn't copy anything to memory.) Be sure to set it correctly!
1482 */
1483 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1484 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1485 DWORD *pcbDecoded)
1486 {
1487 BOOL ret = TRUE;
1488 DWORD dataLen;
1489 CERT_NAME_VALUE *value = pvStructInfo;
1490
1491 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1492 {
1493 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1494 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1495
1496 switch (pbEncoded[0])
1497 {
1498 case ASN_OCTETSTRING:
1499 valueType = CERT_RDN_OCTET_STRING;
1500 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1501 bytesNeeded += dataLen;
1502 break;
1503 case ASN_NUMERICSTRING:
1504 valueType = CERT_RDN_NUMERIC_STRING;
1505 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1506 bytesNeeded += dataLen;
1507 break;
1508 case ASN_PRINTABLESTRING:
1509 valueType = CERT_RDN_PRINTABLE_STRING;
1510 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1511 bytesNeeded += dataLen;
1512 break;
1513 case ASN_IA5STRING:
1514 valueType = CERT_RDN_IA5_STRING;
1515 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1516 bytesNeeded += dataLen;
1517 break;
1518 case ASN_T61STRING:
1519 valueType = CERT_RDN_T61_STRING;
1520 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1521 bytesNeeded += dataLen;
1522 break;
1523 case ASN_VIDEOTEXSTRING:
1524 valueType = CERT_RDN_VIDEOTEX_STRING;
1525 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1526 bytesNeeded += dataLen;
1527 break;
1528 case ASN_GRAPHICSTRING:
1529 valueType = CERT_RDN_GRAPHIC_STRING;
1530 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1531 bytesNeeded += dataLen;
1532 break;
1533 case ASN_VISIBLESTRING:
1534 valueType = CERT_RDN_VISIBLE_STRING;
1535 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1536 bytesNeeded += dataLen;
1537 break;
1538 case ASN_GENERALSTRING:
1539 valueType = CERT_RDN_GENERAL_STRING;
1540 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1541 bytesNeeded += dataLen;
1542 break;
1543 case ASN_UNIVERSALSTRING:
1544 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545 SetLastError(CRYPT_E_ASN1_BADTAG);
1546 return FALSE;
1547 case ASN_BMPSTRING:
1548 valueType = CERT_RDN_BMP_STRING;
1549 bytesNeeded += dataLen;
1550 break;
1551 case ASN_UTF8STRING:
1552 valueType = CERT_RDN_UTF8_STRING;
1553 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1554 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1555 break;
1556 default:
1557 SetLastError(CRYPT_E_ASN1_BADTAG);
1558 return FALSE;
1559 }
1560
1561 if (pcbDecoded)
1562 *pcbDecoded = 1 + lenBytes + dataLen;
1563 if (!value)
1564 *pcbStructInfo = bytesNeeded;
1565 else if (*pcbStructInfo < bytesNeeded)
1566 {
1567 *pcbStructInfo = bytesNeeded;
1568 SetLastError(ERROR_MORE_DATA);
1569 ret = FALSE;
1570 }
1571 else
1572 {
1573 *pcbStructInfo = bytesNeeded;
1574 value->dwValueType = valueType;
1575 if (dataLen)
1576 {
1577 DWORD i;
1578
1579 assert(value->Value.pbData);
1580 switch (pbEncoded[0])
1581 {
1582 case ASN_OCTETSTRING:
1583 case ASN_NUMERICSTRING:
1584 case ASN_PRINTABLESTRING:
1585 case ASN_IA5STRING:
1586 case ASN_T61STRING:
1587 case ASN_VIDEOTEXSTRING:
1588 case ASN_GRAPHICSTRING:
1589 case ASN_VISIBLESTRING:
1590 case ASN_GENERALSTRING:
1591 value->Value.cbData = dataLen;
1592 if (dataLen)
1593 {
1594 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1595 memcpy(value->Value.pbData,
1596 pbEncoded + 1 + lenBytes, dataLen);
1597 else
1598 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1599 lenBytes;
1600 }
1601 break;
1602 case ASN_BMPSTRING:
1603 {
1604 LPWSTR str = (LPWSTR)value->Value.pbData;
1605
1606 value->Value.cbData = dataLen;
1607 for (i = 0; i < dataLen / 2; i++)
1608 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1609 pbEncoded[1 + lenBytes + 2 * i + 1];
1610 break;
1611 }
1612 case ASN_UTF8STRING:
1613 {
1614 LPWSTR str = (LPWSTR)value->Value.pbData;
1615
1616 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1617 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1618 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1619 break;
1620 }
1621 }
1622 }
1623 else
1624 {
1625 value->Value.cbData = 0;
1626 value->Value.pbData = NULL;
1627 }
1628 }
1629 }
1630 return ret;
1631 }
1632
1633 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1634 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1635 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1636 {
1637 BOOL ret = TRUE;
1638
1639 __TRY
1640 {
1641 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1642 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1643 if (ret && pvStructInfo)
1644 {
1645 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1646 pcbStructInfo, *pcbStructInfo);
1647 if (ret)
1648 {
1649 CERT_NAME_VALUE *value;
1650
1651 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1652 pvStructInfo = *(BYTE **)pvStructInfo;
1653 value = pvStructInfo;
1654 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1655 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1656 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1657 pcbStructInfo, NULL);
1658 }
1659 }
1660 }
1661 __EXCEPT_PAGE_FAULT
1662 {
1663 SetLastError(STATUS_ACCESS_VIOLATION);
1664 ret = FALSE;
1665 }
1666 __ENDTRY
1667 return ret;
1668 }
1669
1670 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1671 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1672 DWORD *pcbDecoded)
1673 {
1674 BOOL ret = TRUE;
1675 DWORD dataLen;
1676 CERT_NAME_VALUE *value = pvStructInfo;
1677
1678 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1679 {
1680 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1681 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1682
1683 switch (pbEncoded[0])
1684 {
1685 case ASN_NUMERICSTRING:
1686 valueType = CERT_RDN_NUMERIC_STRING;
1687 if (dataLen)
1688 bytesNeeded += (dataLen + 1) * 2;
1689 break;
1690 case ASN_PRINTABLESTRING:
1691 valueType = CERT_RDN_PRINTABLE_STRING;
1692 if (dataLen)
1693 bytesNeeded += (dataLen + 1) * 2;
1694 break;
1695 case ASN_IA5STRING:
1696 valueType = CERT_RDN_IA5_STRING;
1697 if (dataLen)
1698 bytesNeeded += (dataLen + 1) * 2;
1699 break;
1700 case ASN_T61STRING:
1701 valueType = CERT_RDN_T61_STRING;
1702 if (dataLen)
1703 bytesNeeded += (dataLen + 1) * 2;
1704 break;
1705 case ASN_VIDEOTEXSTRING:
1706 valueType = CERT_RDN_VIDEOTEX_STRING;
1707 if (dataLen)
1708 bytesNeeded += (dataLen + 1) * 2;
1709 break;
1710 case ASN_GRAPHICSTRING:
1711 valueType = CERT_RDN_GRAPHIC_STRING;
1712 if (dataLen)
1713 bytesNeeded += (dataLen + 1) * 2;
1714 break;
1715 case ASN_VISIBLESTRING:
1716 valueType = CERT_RDN_VISIBLE_STRING;
1717 if (dataLen)
1718 bytesNeeded += (dataLen + 1) * 2;
1719 break;
1720 case ASN_GENERALSTRING:
1721 valueType = CERT_RDN_GENERAL_STRING;
1722 if (dataLen)
1723 bytesNeeded += (dataLen + 1) * 2;
1724 break;
1725 case ASN_UNIVERSALSTRING:
1726 valueType = CERT_RDN_UNIVERSAL_STRING;
1727 if (dataLen)
1728 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1729 break;
1730 case ASN_BMPSTRING:
1731 valueType = CERT_RDN_BMP_STRING;
1732 if (dataLen)
1733 bytesNeeded += dataLen + sizeof(WCHAR);
1734 break;
1735 case ASN_UTF8STRING:
1736 valueType = CERT_RDN_UTF8_STRING;
1737 if (dataLen)
1738 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1739 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1740 break;
1741 default:
1742 SetLastError(CRYPT_E_ASN1_BADTAG);
1743 return FALSE;
1744 }
1745
1746 if (pcbDecoded)
1747 *pcbDecoded = 1 + lenBytes + dataLen;
1748 if (!value)
1749 *pcbStructInfo = bytesNeeded;
1750 else if (*pcbStructInfo < bytesNeeded)
1751 {
1752 *pcbStructInfo = bytesNeeded;
1753 SetLastError(ERROR_MORE_DATA);
1754 ret = FALSE;
1755 }
1756 else
1757 {
1758 *pcbStructInfo = bytesNeeded;
1759 value->dwValueType = valueType;
1760 if (dataLen)
1761 {
1762 DWORD i;
1763 LPWSTR str = (LPWSTR)value->Value.pbData;
1764
1765 assert(value->Value.pbData);
1766 switch (pbEncoded[0])
1767 {
1768 case ASN_NUMERICSTRING:
1769 case ASN_PRINTABLESTRING:
1770 case ASN_IA5STRING:
1771 case ASN_T61STRING:
1772 case ASN_VIDEOTEXSTRING:
1773 case ASN_GRAPHICSTRING:
1774 case ASN_VISIBLESTRING:
1775 case ASN_GENERALSTRING:
1776 value->Value.cbData = dataLen * 2;
1777 for (i = 0; i < dataLen; i++)
1778 str[i] = pbEncoded[1 + lenBytes + i];
1779 str[i] = 0;
1780 break;
1781 case ASN_UNIVERSALSTRING:
1782 value->Value.cbData = dataLen / 2;
1783 for (i = 0; i < dataLen / 4; i++)
1784 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1785 | pbEncoded[1 + lenBytes + 2 * i + 3];
1786 str[i] = 0;
1787 break;
1788 case ASN_BMPSTRING:
1789 value->Value.cbData = dataLen;
1790 for (i = 0; i < dataLen / 2; i++)
1791 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1792 pbEncoded[1 + lenBytes + 2 * i + 1];
1793 str[i] = 0;
1794 break;
1795 case ASN_UTF8STRING:
1796 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1797 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1798 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1799 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1800 value->Value.cbData += sizeof(WCHAR);
1801 break;
1802 }
1803 }
1804 else
1805 {
1806 value->Value.cbData = 0;
1807 value->Value.pbData = NULL;
1808 }
1809 }
1810 }
1811 return ret;
1812 }
1813
1814 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1815 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1816 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1817 {
1818 BOOL ret = TRUE;
1819
1820 __TRY
1821 {
1822 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1823 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1824 if (ret && pvStructInfo)
1825 {
1826 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1827 pcbStructInfo, *pcbStructInfo);
1828 if (ret)
1829 {
1830 CERT_NAME_VALUE *value;
1831
1832 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1833 pvStructInfo = *(BYTE **)pvStructInfo;
1834 value = pvStructInfo;
1835 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1836 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1837 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1838 pcbStructInfo, NULL);
1839 }
1840 }
1841 }
1842 __EXCEPT_PAGE_FAULT
1843 {
1844 SetLastError(STATUS_ACCESS_VIOLATION);
1845 ret = FALSE;
1846 }
1847 __ENDTRY
1848 return ret;
1849 }
1850
1851 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1852 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1853 {
1854 BOOL ret;
1855 struct AsnDecodeSequenceItem items[] = {
1856 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1857 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1858 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1859 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1860 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1861 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1862 };
1863 CERT_RDN_ATTR *attr = pvStructInfo;
1864
1865 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1866 pvStructInfo, *pcbStructInfo);
1867
1868 if (attr)
1869 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1870 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1871 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1872 attr ? attr->pszObjId : NULL);
1873 if (attr)
1874 {
1875 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1876 debugstr_a(attr->pszObjId));
1877 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1878 }
1879 TRACE("returning %d (%08x)\n", ret, GetLastError());
1880 return ret;
1881 }
1882
1883 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1884 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1885 {
1886 BOOL ret = TRUE;
1887 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1888 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1889 sizeof(CERT_RDN),
1890 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1891 offsetof(CERT_RDN_ATTR, pszObjId) };
1892
1893 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1894 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1895 return ret;
1896 }
1897
1898 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1899 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1900 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1901 {
1902 BOOL ret = TRUE;
1903
1904 __TRY
1905 {
1906 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1907 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1908 sizeof(CERT_NAME_INFO),
1909 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1910 offsetof(CERT_RDN, rgRDNAttr) };
1911 DWORD bytesNeeded;
1912
1913 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1914 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1915 NULL);
1916 if (ret)
1917 {
1918 if (!pvStructInfo)
1919 *pcbStructInfo = bytesNeeded;
1920 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1921 pvStructInfo, pcbStructInfo, bytesNeeded)))
1922 {
1923 CERT_NAME_INFO *info;
1924
1925 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1926 pvStructInfo = *(BYTE **)pvStructInfo;
1927 info = pvStructInfo;
1928 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1929 sizeof(CERT_NAME_INFO));
1930 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1931 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1932 &bytesNeeded, NULL);
1933 }
1934 }
1935 }
1936 __EXCEPT_PAGE_FAULT
1937 {
1938 SetLastError(STATUS_ACCESS_VIOLATION);
1939 ret = FALSE;
1940 }
1941 __ENDTRY
1942 return ret;
1943 }
1944
1945 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1946 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1947 DWORD *pcbDecoded)
1948 {
1949 BOOL ret;
1950 struct AsnDecodeSequenceItem items[] = {
1951 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1952 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1953 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1954 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1955 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1956 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1957 };
1958 CERT_RDN_ATTR *attr = pvStructInfo;
1959
1960 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1961 pvStructInfo, *pcbStructInfo);
1962
1963 if (attr)
1964 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1965 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1966 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1967 attr ? attr->pszObjId : NULL);
1968 if (attr)
1969 {
1970 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1971 debugstr_a(attr->pszObjId));
1972 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1973 }
1974 TRACE("returning %d (%08x)\n", ret, GetLastError());
1975 return ret;
1976 }
1977
1978 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1979 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1980 {
1981 BOOL ret = TRUE;
1982 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1983 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1984 sizeof(CERT_RDN),
1985 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1986 offsetof(CERT_RDN_ATTR, pszObjId) };
1987
1988 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1989 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1990 return ret;
1991 }
1992
1993 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1994 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1995 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1996 {
1997 BOOL ret = TRUE;
1998
1999 __TRY
2000 {
2001 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2002 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2003 sizeof(CERT_NAME_INFO),
2004 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2005 offsetof(CERT_RDN, rgRDNAttr) };
2006 DWORD bytesNeeded;
2007
2008 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2009 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2010 NULL);
2011 if (ret)
2012 {
2013 if (!pvStructInfo)
2014 *pcbStructInfo = bytesNeeded;
2015 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2016 pvStructInfo, pcbStructInfo, bytesNeeded)))
2017 {
2018 CERT_NAME_INFO *info;
2019
2020 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2021 pvStructInfo = *(BYTE **)pvStructInfo;
2022 info = pvStructInfo;
2023 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2024 sizeof(CERT_NAME_INFO));
2025 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2026 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2027 &bytesNeeded, NULL);
2028 }
2029 }
2030 }
2031 __EXCEPT_PAGE_FAULT
2032 {
2033 SetLastError(STATUS_ACCESS_VIOLATION);
2034 ret = FALSE;
2035 }
2036 __ENDTRY
2037 return ret;
2038 }
2039
2040 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2041 DWORD *pcbDecoded)
2042 {
2043 BOOL ret = TRUE, done = FALSE;
2044 DWORD indefiniteNestingLevels = 0, decoded = 0;
2045
2046 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2047
2048 do {
2049 DWORD dataLen;
2050
2051 if (!cbEncoded)
2052 done = TRUE;
2053 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2054 &dataLen)))
2055 {
2056 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2057
2058 if (dataLen == CMSG_INDEFINITE_LENGTH)
2059 {
2060 indefiniteNestingLevels++;
2061 pbEncoded += 1 + lenBytes;
2062 cbEncoded -= 1 + lenBytes;
2063 decoded += 1 + lenBytes;
2064 TRACE("indefiniteNestingLevels = %d\n",
2065 indefiniteNestingLevels);
2066 }
2067 else
2068 {
2069 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2070 indefiniteNestingLevels)
2071 {
2072 indefiniteNestingLevels--;
2073 TRACE("indefiniteNestingLevels = %d\n",
2074 indefiniteNestingLevels);
2075 }
2076 pbEncoded += 1 + lenBytes + dataLen;
2077 cbEncoded -= 1 + lenBytes + dataLen;
2078 decoded += 1 + lenBytes + dataLen;
2079 if (!indefiniteNestingLevels)
2080 done = TRUE;
2081 }
2082 }
2083 } while (ret && !done);
2084 /* If we haven't found all 0 TLVs, we haven't found the end */
2085 if (ret && indefiniteNestingLevels)
2086 {
2087 SetLastError(CRYPT_E_ASN1_EOD);
2088 ret = FALSE;
2089 }
2090 if (ret)
2091 *pcbDecoded = decoded;
2092 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2093 return ret;
2094 }
2095
2096 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2097 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2098 DWORD *pcbDecoded)
2099 {
2100 BOOL ret = TRUE;
2101 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2102
2103 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2104 pvStructInfo, *pcbStructInfo);
2105
2106 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2107 {
2108 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2109 bytesNeeded += encodedLen;
2110 if (!pvStructInfo)
2111 *pcbStructInfo = bytesNeeded;
2112 else if (*pcbStructInfo < bytesNeeded)
2113 {
2114 SetLastError(ERROR_MORE_DATA);
2115 *pcbStructInfo = bytesNeeded;
2116 ret = FALSE;
2117 }
2118 else
2119 {
2120 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2121
2122 *pcbStructInfo = bytesNeeded;
2123 blob->cbData = encodedLen;
2124 if (encodedLen)
2125 {
2126 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2127 blob->pbData = (LPBYTE)pbEncoded;
2128 else
2129 {
2130 assert(blob->pbData);
2131 memcpy(blob->pbData, pbEncoded, blob->cbData);
2132 }
2133 }
2134 else
2135 blob->pbData = NULL;
2136 }
2137 if (pcbDecoded)
2138 *pcbDecoded = encodedLen;
2139 }
2140 return ret;
2141 }
2142
2143 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2144 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2145 {
2146 BOOL ret;
2147 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2148 offsetof(CTL_USAGE, cUsageIdentifier),
2149 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2150 sizeof(CTL_USAGE),
2151 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2152
2153 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2154 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2155 return ret;
2156 }
2157
2158 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2159 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2160 DWORD *pcbDecoded)
2161 {
2162 struct AsnArrayDescriptor arrayDesc = { 0,
2163 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2164 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2165 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2166 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2167 BOOL ret;
2168
2169 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2170 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2171 return ret;
2172 }
2173
2174 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2175 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2176 {
2177 struct AsnDecodeSequenceItem items[] = {
2178 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2179 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2180 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2181 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2182 CRYPT_AsnDecodeCTLEntryAttributes,
2183 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2184 offsetof(CTL_ENTRY, rgAttribute), 0 },
2185 };
2186 BOOL ret = TRUE;
2187 CTL_ENTRY *entry = pvStructInfo;
2188
2189 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2190 *pcbStructInfo);
2191
2192 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2193 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2194 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2195 return ret;
2196 }
2197
2198 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2199 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2200 {
2201 BOOL ret;
2202 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2203 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2204 FINALMEMBERSIZE(CTL_INFO, cExtension),
2205 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2206 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2207
2208 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2209 pvStructInfo, *pcbStructInfo, pcbDecoded);
2210
2211 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2212 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2213 return ret;
2214 }
2215
2216 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2217 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2218 DWORD *pcbDecoded)
2219 {
2220 BOOL ret = TRUE;
2221 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2222 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2223 FINALMEMBERSIZE(CTL_INFO, cExtension),
2224 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2225 offsetof(CERT_EXTENSION, pszObjId) };
2226
2227 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2228 pvStructInfo, *pcbStructInfo, pcbDecoded);
2229
2230 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2231 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2232 return ret;
2233 }
2234
2235 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2236 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2237 DWORD *pcbDecoded)
2238 {
2239 BOOL ret;
2240 DWORD dataLen;
2241
2242 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2243 {
2244 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2245
2246 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2247 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2248 if (ret && pcbDecoded)
2249 *pcbDecoded = 1 + lenBytes + dataLen;
2250 }
2251 return ret;
2252 }
2253
2254 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2255 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2256 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2257 {
2258 BOOL ret = FALSE;
2259
2260 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2261 pDecodePara, pvStructInfo, *pcbStructInfo);
2262
2263 __TRY
2264 {
2265 struct AsnDecodeSequenceItem items[] = {
2266 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2267 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2268 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2269 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2270 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2271 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2272 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2273 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2274 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2275 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2276 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2277 { 0, offsetof(CTL_INFO, ThisUpdate),
2278 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2279 0 },
2280 { 0, offsetof(CTL_INFO, NextUpdate),
2281 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2282 0 },
2283 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2284 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2285 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2286 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2287 CRYPT_AsnDecodeCTLEntries,
2288 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2289 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2290 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2291 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2292 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2293 };
2294
2295 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2296 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2297 pcbStructInfo, NULL, NULL);
2298 }
2299 __EXCEPT_PAGE_FAULT
2300 {
2301 SetLastError(STATUS_ACCESS_VIOLATION);
2302 }
2303 __ENDTRY
2304 return ret;
2305 }
2306
2307 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2308 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2309 DWORD *pcbDecoded)
2310 {
2311 BOOL ret;
2312 struct AsnDecodeSequenceItem items[] = {
2313 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2314 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2315 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2316 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2317 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2318 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2319 };
2320 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2321
2322 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2323 pvStructInfo, *pcbStructInfo);
2324
2325 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2326 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2327 pcbDecoded, capability ? capability->pszObjId : NULL);
2328 TRACE("returning %d\n", ret);
2329 return ret;
2330 }
2331
2332 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2333 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2334 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2335 {
2336 BOOL ret = FALSE;
2337
2338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2339 pDecodePara, pvStructInfo, *pcbStructInfo);
2340
2341 __TRY
2342 {
2343 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2344 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2345 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2346 sizeof(CRYPT_SMIME_CAPABILITIES),
2347 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2348 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2349
2350 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2351 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2352 }
2353 __EXCEPT_PAGE_FAULT
2354 {
2355 SetLastError(STATUS_ACCESS_VIOLATION);
2356 }
2357 __ENDTRY
2358 TRACE("returning %d\n", ret);
2359 return ret;
2360 }
2361
2362 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2363 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2364 DWORD *pcbDecoded)
2365 {
2366 BOOL ret = TRUE;
2367 DWORD dataLen;
2368 LPSTR *pStr = pvStructInfo;
2369
2370 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2371 {
2372 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2373 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2374
2375 if (pbEncoded[0] != ASN_IA5STRING)
2376 {
2377 SetLastError(CRYPT_E_ASN1_CORRUPT);
2378 ret = FALSE;
2379 }
2380 else
2381 {
2382 bytesNeeded += dataLen;
2383 if (pcbDecoded)
2384 *pcbDecoded = 1 + lenBytes + dataLen;
2385 if (!pvStructInfo)
2386 *pcbStructInfo = bytesNeeded;
2387 else if (*pcbStructInfo < bytesNeeded)
2388 {
2389 *pcbStructInfo = bytesNeeded;
2390 SetLastError(ERROR_MORE_DATA);
2391 ret = FALSE;
2392 }
2393 else
2394 {
2395 *pcbStructInfo = bytesNeeded;
2396 if (dataLen)
2397 {
2398 LPSTR str = *pStr;
2399
2400 assert(str);
2401 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2402 str[dataLen] = 0;
2403 }
2404 else
2405 *pStr = NULL;
2406 }
2407 }
2408 }
2409 return ret;
2410 }
2411
2412 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2413 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2414 DWORD *pcbDecoded)
2415 {
2416 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2417 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2418 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2419 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2420 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2421 BOOL ret;
2422
2423 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2424 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2425
2426 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2427 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2428 TRACE("returning %d\n", ret);
2429 return ret;
2430 }
2431
2432 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2433 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2434 DWORD *pcbDecoded)
2435 {
2436 BOOL ret;
2437 struct AsnDecodeSequenceItem items[] = {
2438 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2439 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2440 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2441 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2442 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2443 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2444 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2445 rgNoticeNumbers), 0 },
2446 };
2447 DWORD bytesNeeded;
2448
2449 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2450 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2451
2452 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2453 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2454 NULL);
2455 if (ret)
2456 {
2457 /* The caller is expecting a pointer to a
2458 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2459 * CRYPT_AsnDecodeSequence is decoding a
2460 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2461 * needed, and decode again if the requisite space is available.
2462 */
2463 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2464 if (!pvStructInfo)
2465 *pcbStructInfo = bytesNeeded;
2466 else if (*pcbStructInfo < bytesNeeded)
2467 {
2468 *pcbStructInfo = bytesNeeded;
2469 SetLastError(ERROR_MORE_DATA);
2470 ret = FALSE;
2471 }
2472 else
2473 {
2474 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2475
2476 *pcbStructInfo = bytesNeeded;
2477 /* The pointer (pvStructInfo) passed in points to the first dynamic
2478 * pointer, so use it as the pointer to the
2479 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2480 * appropriate offset for the first dynamic pointer within the
2481 * notice reference by pointing to the first memory location past
2482 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2483 */
2484 noticeRef =
2485 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2486 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2487 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2488 ret = CRYPT_AsnDecodeSequence(items,
2489 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2490 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2491 noticeRef->pszOrganization);
2492 }
2493 }
2494 TRACE("returning %d\n", ret);
2495 return ret;
2496 }
2497
2498 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2499 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2500 DWORD *pcbDecoded)
2501 {
2502 BOOL ret = TRUE;
2503 DWORD dataLen;
2504
2505 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2506 {
2507 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2508 DWORD bytesNeeded = sizeof(LPWSTR);
2509
2510 switch (pbEncoded[0])
2511 {
2512 case ASN_NUMERICSTRING:
2513 if (dataLen)
2514 bytesNeeded += (dataLen + 1) * 2;
2515 break;
2516 case ASN_PRINTABLESTRING:
2517 if (dataLen)
2518 bytesNeeded += (dataLen + 1) * 2;
2519 break;
2520 case ASN_IA5STRING:
2521 if (dataLen)
2522 bytesNeeded += (dataLen + 1) * 2;
2523 break;
2524 case ASN_T61STRING:
2525 if (dataLen)
2526 bytesNeeded += (dataLen + 1) * 2;
2527 break;
2528 case ASN_VIDEOTEXSTRING:
2529 if (dataLen)
2530 bytesNeeded += (dataLen + 1) * 2;
2531 break;
2532 case ASN_GRAPHICSTRING:
2533 if (dataLen)
2534 bytesNeeded += (dataLen + 1) * 2;
2535 break;
2536 case ASN_VISIBLESTRING:
2537 if (dataLen)
2538 bytesNeeded += (dataLen + 1) * 2;
2539 break;
2540 case ASN_GENERALSTRING:
2541 if (dataLen)
2542 bytesNeeded += (dataLen + 1) * 2;
2543 break;
2544 case ASN_UNIVERSALSTRING:
2545 if (dataLen)
2546 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2547 break;
2548 case ASN_BMPSTRING:
2549 if (dataLen)
2550 bytesNeeded += dataLen + sizeof(WCHAR);
2551 break;
2552 case ASN_UTF8STRING:
2553 if (dataLen)
2554 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2555 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2556 break;
2557 default:
2558 SetLastError(CRYPT_E_ASN1_BADTAG);
2559 return FALSE;
2560 }
2561
2562 if (pcbDecoded)
2563 *pcbDecoded = 1 + lenBytes + dataLen;
2564 if (!pvStructInfo)
2565 *pcbStructInfo = bytesNeeded;
2566 else if (*pcbStructInfo < bytesNeeded)
2567 {
2568 *pcbStructInfo = bytesNeeded;
2569 SetLastError(ERROR_MORE_DATA);
2570 ret = FALSE;
2571 }
2572 else
2573 {
2574 LPWSTR *pStr = pvStructInfo;
2575
2576 *pcbStructInfo = bytesNeeded;
2577 if (dataLen)
2578 {
2579 DWORD i;
2580 LPWSTR str = *(LPWSTR *)pStr;
2581
2582 assert(str);
2583 switch (pbEncoded[0])
2584 {
2585 case ASN_NUMERICSTRING:
2586 case ASN_PRINTABLESTRING:
2587 case ASN_IA5STRING:
2588 case ASN_T61STRING:
2589 case ASN_VIDEOTEXSTRING:
2590 case ASN_GRAPHICSTRING:
2591 case ASN_VISIBLESTRING:
2592 case ASN_GENERALSTRING:
2593 for (i = 0; i < dataLen; i++)
2594 str[i] = pbEncoded[1 + lenBytes + i];
2595 str[i] = 0;
2596 break;
2597 case ASN_UNIVERSALSTRING:
2598 for (i = 0; i < dataLen / 4; i++)
2599 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2600 | pbEncoded[1 + lenBytes + 2 * i + 3];
2601 str[i] = 0;
2602 break;
2603 case ASN_BMPSTRING:
2604 for (i = 0; i < dataLen / 2; i++)
2605 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2606 pbEncoded[1 + lenBytes + 2 * i + 1];
2607 str[i] = 0;
2608 break;
2609 case ASN_UTF8STRING:
2610 {
2611 int len = MultiByteToWideChar(CP_UTF8, 0,
2612 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2613 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2614 str[len] = 0;
2615 break;
2616 }
2617 }
2618 }
2619 else
2620 *pStr = NULL;
2621 }
2622 }
2623 return ret;
2624 }
2625
2626 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2627 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2628 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2629 {
2630 BOOL ret;
2631 struct AsnDecodeSequenceItem items[] = {
2632 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2633 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2634 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2635 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2636 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2637 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2638 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2639 };
2640 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2641
2642 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2643 pvStructInfo, *pcbStructInfo);
2644
2645 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2646 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2647 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2648 TRACE("returning %d\n", ret);
2649 return ret;
2650 }
2651
2652 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2653 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2654 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2655 void *pvStructInfo, DWORD *pcbStructInfo)
2656 {
2657 BOOL ret = FALSE;
2658
2659 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2660 pDecodePara, pvStructInfo, *pcbStructInfo);
2661
2662 __TRY
2663 {
2664 DWORD bytesNeeded;
2665
2666 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2667 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2668 NULL);
2669 if (ret)
2670 {
2671 if (!pvStructInfo)
2672 *pcbStructInfo = bytesNeeded;
2673 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2674 pvStructInfo, pcbStructInfo, bytesNeeded)))
2675 {
2676 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2677
2678 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2679 pvStructInfo = *(BYTE **)pvStructInfo;
2680 notice = pvStructInfo;
2681 notice->pNoticeReference =
2682 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2683 ((BYTE *)pvStructInfo +
2684 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2685 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2686 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2687 pvStructInfo, &bytesNeeded, NULL);
2688 }
2689 }
2690 }
2691 __EXCEPT_PAGE_FAULT
2692 {
2693 SetLastError(STATUS_ACCESS_VIOLATION);
2694 }
2695 __ENDTRY
2696 TRACE("returning %d\n", ret);
2697 return ret;
2698 }
2699
2700 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2701 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2702 DWORD *pcbDecoded)
2703 {
2704 BOOL ret;
2705 struct AsnArrayDescriptor arrayDesc = { 0,
2706 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2707 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2708 CRYPT_AsnDecodeCopyBytes,
2709 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2710
2711 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2712 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2713
2714 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2715 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2716 return ret;
2717 }
2718
2719 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2720 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2721 DWORD *pcbDecoded)
2722 {
2723 BOOL ret;
2724 struct AsnDecodeSequenceItem items[] = {
2725 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2726 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2727 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2728 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2729 CRYPT_AsnDecodePKCSAttributeValue,
2730 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2731 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2732 };
2733 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2734
2735 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2736 pvStructInfo, *pcbStructInfo);
2737
2738 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2739 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2740 pcbDecoded, attr ? attr->pszObjId : NULL);
2741 TRACE("returning %d\n", ret);
2742 return ret;
2743 }
2744
2745 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2746 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2747 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2748 {
2749 BOOL ret = FALSE;
2750
2751 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2752 pDecodePara, pvStructInfo, *pcbStructInfo);
2753
2754 __TRY
2755 {
2756 DWORD bytesNeeded;
2757
2758 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2759 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2760 if (ret)
2761 {
2762 if (!pvStructInfo)
2763 *pcbStructInfo = bytesNeeded;
2764 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2765 pvStructInfo, pcbStructInfo, bytesNeeded)))
2766 {
2767 PCRYPT_ATTRIBUTE attr;
2768
2769 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2770 pvStructInfo = *(BYTE **)pvStructInfo;
2771 attr = pvStructInfo;
2772 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2773 sizeof(CRYPT_ATTRIBUTE));
2774 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2775 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2776 NULL);
2777 }
2778 }
2779 }
2780 __EXCEPT_PAGE_FAULT
2781 {
2782 SetLastError(STATUS_ACCESS_VIOLATION);
2783 }
2784 __ENDTRY
2785 TRACE("returning %d\n", ret);
2786 return ret;
2787 }
2788
2789 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2790 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2791 DWORD *pcbDecoded)
2792 {
2793 struct AsnArrayDescriptor arrayDesc = { 0,
2794 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2795 sizeof(CRYPT_ATTRIBUTES),
2796 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2797 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2798 BOOL ret;
2799
2800 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2801 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2802 return ret;
2803 }
2804
2805 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2806 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2807 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2808 {
2809 BOOL ret = FALSE;
2810
2811 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2812 pDecodePara, pvStructInfo, *pcbStructInfo);
2813
2814 __TRY
2815 {
2816 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2817 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2818 sizeof(CRYPT_ATTRIBUTES),
2819 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2820 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2821
2822 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2823 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2824 }
2825 __EXCEPT_PAGE_FAULT
2826 {
2827 SetLastError(STATUS_ACCESS_VIOLATION);
2828 }
2829 __ENDTRY
2830 TRACE("returning %d\n", ret);
2831 return ret;
2832 }
2833
2834 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2835 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2836 {
2837 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2838 BOOL ret = TRUE;
2839 struct AsnDecodeSequenceItem items[] = {
2840 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2841 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2842 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2843 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2844 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2845 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2846 };
2847
2848 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2849 pvStructInfo, *pcbStructInfo, pcbDecoded);
2850
2851 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2852 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2853 pcbDecoded, algo ? algo->pszObjId : NULL);
2854 if (ret && pvStructInfo)
2855 {
2856 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2857 debugstr_a(algo->pszObjId));
2858 }
2859 return ret;
2860 }
2861
2862 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2863 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2864 DWORD *pcbDecoded)
2865 {
2866 BOOL ret = TRUE;
2867 struct AsnDecodeSequenceItem items[] = {
2868 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2869 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2870 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2871 Algorithm.pszObjId) },
2872 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2873 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2874 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2875 };
2876 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2877
2878 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2879 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2880 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2881 return ret;
2882 }
2883
2884 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2885 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2886 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2887 {
2888 BOOL ret = TRUE;
2889
2890 __TRY
2891 {
2892 DWORD bytesNeeded;
2893
2894 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2895 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2896 {
2897 if (!pvStructInfo)
2898 *pcbStructInfo = bytesNeeded;
2899 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2900 pvStructInfo, pcbStructInfo, bytesNeeded)))
2901 {
2902 PCERT_PUBLIC_KEY_INFO info;
2903
2904 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2905 pvStructInfo = *(BYTE **)pvStructInfo;
2906 info = pvStructInfo;
2907 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2908 sizeof(CERT_PUBLIC_KEY_INFO);
2909 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2910 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2911 &bytesNeeded, NULL);
2912 }
2913 }
2914 }
2915 __EXCEPT_PAGE_FAULT
2916 {
2917 SetLastError(STATUS_ACCESS_VIOLATION);
2918 ret = FALSE;
2919 }
2920 __ENDTRY
2921 return ret;
2922 }
2923
2924 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2925 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2926 {
2927 BOOL ret;
2928
2929 if (cbEncoded < 3)
2930 {
2931 SetLastError(CRYPT_E_ASN1_CORRUPT);
2932 return FALSE;
2933 }
2934 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2935 {
2936 SetLastError(CRYPT_E_ASN1_CORRUPT);
2937 return FALSE;
2938 }
2939 if (pbEncoded[1] > 1)
2940 {
2941 SetLastError(CRYPT_E_ASN1_CORRUPT);
2942 return FALSE;
2943 }
2944 if (pcbDecoded)
2945 *pcbDecoded = 3;
2946 if (!pvStructInfo)
2947 {
2948 *pcbStructInfo = sizeof(BOOL);
2949 ret = TRUE;
2950 }
2951 else if (*pcbStructInfo < sizeof(BOOL))
2952 {
2953 *pcbStructInfo = sizeof(BOOL);
2954 SetLastError(ERROR_MORE_DATA);
2955 ret = FALSE;
2956 }
2957 else
2958 {
2959 *pcbStructInfo = sizeof(BOOL);
2960 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2961 ret = TRUE;
2962 }
2963 TRACE("returning %d (%08x)\n", ret, GetLastError());
2964 return ret;
2965 }
2966
2967 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2968 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2969 {
2970 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2971 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2972 BOOL ret;
2973
2974 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2975 pvStructInfo, *pcbStructInfo);
2976
2977 if (cbEncoded < 2)
2978 {
2979 SetLastError(CRYPT_E_ASN1_CORRUPT);
2980 return FALSE;
2981 }
2982 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2983 if (1 + lenBytes > cbEncoded)
2984 {
2985 SetLastError(CRYPT_E_ASN1_CORRUPT);
2986 return FALSE;
2987 }
2988 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2989 {
2990 switch (pbEncoded[0] & ASN_TYPE_MASK)
2991 {
2992 case 1: /* rfc822Name */
2993 case 2: /* dNSName */
2994 case 6: /* uniformResourceIdentifier */
2995 if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
2996 {
2997 SetLastError(CRYPT_E_ASN1_RULE);
2998 ret = FALSE;
2999 }
3000 else
3001 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3002 break;
3003 case 4: /* directoryName */
3004 case 7: /* iPAddress */
3005 bytesNeeded += dataLen;
3006 break;
3007 case 8: /* registeredID */
3008 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3009 &dataLen, NULL);
3010 if (ret)
3011 {
3012 /* FIXME: ugly, shouldn't need to know internals of OID decode
3013 * function to use it.
3014 */
3015 bytesNeeded += dataLen - sizeof(LPSTR);
3016 }
3017 break;
3018 case 0: /* otherName */
3019 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3020 SetLastError(CRYPT_E_ASN1_BADTAG);
3021 ret = FALSE;
3022 break;
3023 case 3: /* x400Address, unimplemented */
3024 case 5: /* ediPartyName, unimplemented */
3025 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3026 SetLastError(CRYPT_E_ASN1_BADTAG);
3027 ret = FALSE;
3028 break;
3029 default:
3030 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3031 SetLastError(CRYPT_E_ASN1_CORRUPT);
3032 ret = FALSE;
3033 }
3034 if (ret)
3035 {
3036 if (pcbDecoded)
3037 *pcbDecoded = 1 + lenBytes + dataLen;
3038 if (!entry)
3039 *pcbStructInfo = bytesNeeded;
3040 else if (*pcbStructInfo < bytesNeeded)
3041 {
3042 *pcbStructInfo = bytesNeeded;
3043 SetLastError(ERROR_MORE_DATA);
3044 ret = FALSE;
3045 }
3046 else
3047 {
3048 *pcbStructInfo = bytesNeeded;
3049 /* MS used values one greater than the asn1 ones.. sigh */
3050 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3051 switch (pbEncoded[0] & ASN_TYPE_MASK)
3052 {
3053 case 1: /* rfc822Name */
3054 case 2: /* dNSName */
3055 case 6: /* uniformResourceIdentifier */
3056 {
3057 DWORD i;
3058
3059 for (i = 0; i < dataLen; i++)
3060 entry->u.pwszURL[i] =
3061 (WCHAR)pbEncoded[1 + lenBytes + i];
3062 entry->u.pwszURL[i] = 0;
3063 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3064 debugstr_w(entry->u.pwszURL));
3065 break;
3066 }
3067 case 4: /* directoryName */
3068 /* The data are memory-equivalent with the IPAddress case,
3069 * fall-through
3070 */
3071 case 7: /* iPAddress */
3072 /* The next data pointer is in the pwszURL spot, that is,
3073 * the first 4 bytes. Need to move it to the next spot.
3074 */
3075 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3076 entry->u.IPAddress.cbData = dataLen;
3077 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3078 dataLen);
3079 break;
3080 case 8: /* registeredID */
3081 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3082 &entry->u.pszRegisteredID, &dataLen, NULL);
3083 break;
3084 }
3085 }
3086 }
3087 }
3088 return ret;
3089 }
3090
3091 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3092 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3093 DWORD *pcbDecoded)
3094 {
3095 BOOL ret;
3096 struct AsnArrayDescriptor arrayDesc = { 0,
3097 offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3098 offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3099 sizeof(CERT_ALT_NAME_INFO),
3100 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3101 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3102
3103 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3104 pvStructInfo, *pcbStructInfo, pcbDecoded);
3105
3106 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3107 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3108 return ret;
3109 }
3110
3111 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3112 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3113 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3114 {
3115 BOOL ret;
3116
3117 __TRY
3118 {
3119 struct AsnDecodeSequenceItem items[] = {
3120 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3121 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3122 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3123 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3124 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3125 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3126 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3127 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3128 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3129 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3130 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3131 };
3132
3133 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3134 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3135 pcbStructInfo, NULL, NULL);
3136 }
3137 __EXCEPT_PAGE_FAULT
3138 {
3139 SetLastError(STATUS_ACCESS_VIOLATION);
3140 ret = FALSE;
3141 }
3142 __ENDTRY
3143 return ret;
3144 }
3145
3146 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3147 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3148 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3149 {
3150 BOOL ret;
3151
3152 __TRY
3153 {
3154 struct AsnDecodeSequenceItem items[] = {
3155 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3156 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3157 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3158 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3159 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3160 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3161 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3162 AuthorityCertIssuer.rgAltEntry), 0 },
3163 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3164 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3165 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3166 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3167 AuthorityCertSerialNumber.pbData), 0 },
3168 };
3169
3170 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3171 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3172 pcbStructInfo, NULL, NULL);
3173 }
3174 __EXCEPT_PAGE_FAULT
3175 {
3176 SetLastError(STATUS_ACCESS_VIOLATION);
3177 ret = FALSE;
3178 }
3179 __ENDTRY
3180 return ret;
3181 }
3182
3183 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3184 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3185 DWORD *pcbDecoded)
3186 {
3187 struct AsnDecodeSequenceItem items[] = {
3188 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3189 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3190 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3191 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3192 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3193 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3194 };
3195 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3196
3197 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3198 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3199 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3200 }
3201
3202 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3203 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3204 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3205 {
3206 BOOL ret;
3207
3208 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3209 pDecodePara, pvStructInfo, *pcbStructInfo);
3210
3211 __TRY
3212 {
3213 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3214 offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3215 offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3216 sizeof(CERT_AUTHORITY_INFO_ACCESS),
3217 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3218 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3219
3220 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3221 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3222 }
3223 __EXCEPT_PAGE_FAULT
3224 {
3225 SetLastError(STATUS_ACCESS_VIOLATION);
3226 ret = FALSE;
3227 }
3228 __ENDTRY
3229 return ret;
3230 }
3231
3232 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3233 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3234 {
3235 BOOL ret;
3236 DWORD dataLen;
3237
3238 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3239 pvStructInfo, *pcbStructInfo, pcbDecoded);
3240
3241 /* The caller has already checked the tag, no need to check it again.
3242 * Check the outer length is valid:
3243 */
3244 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3245 {
3246 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3247 DWORD innerLen;
3248
3249 pbEncoded += 1 + lenBytes;
3250 cbEncoded -= 1 + lenBytes;
3251 if (dataLen == CMSG_INDEFINITE_LENGTH)
3252 cbEncoded -= 2; /* space for 0 TLV */
3253 /* Check the inner length is valid: */
3254 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3255 {
3256 DWORD decodedLen;
3257
3258 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3259 pvStructInfo, pcbStructInfo, &decodedLen);
3260 if (dataLen == CMSG_INDEFINITE_LENGTH)
3261 {
3262 if (*(pbEncoded + decodedLen) != 0 ||
3263 *(pbEncoded + decodedLen + 1) != 0)
3264 {
3265 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3266 *(pbEncoded + decodedLen),
3267 *(pbEncoded + decodedLen + 1));
3268 SetLastError(CRYPT_E_ASN1_CORRUPT);
3269 ret = FALSE;
3270 }
3271 else
3272 decodedLen += 2;
3273 }
3274 if (ret && pcbDecoded)
3275 {
3276 *pcbDecoded = 1 + lenBytes + decodedLen;
3277 TRACE("decoded %d bytes\n", *pcbDecoded);
3278 }
3279 }
3280 }
3281 return ret;
3282 }
3283
3284 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3285 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3286 DWORD *pcbDecoded)
3287 {
3288 CRYPT_CONTENT_INFO *info = pvStructInfo;
3289 struct AsnDecodeSequenceItem items[] = {
3290 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3291 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3292 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3293 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3294 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3295 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3296 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3297 };
3298 BOOL ret;
3299
3300 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3301 pvStructInfo, *pcbStructInfo, pcbDecoded);
3302
3303 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3304 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3305 pcbDecoded, info ? info->pszObjId : NULL);
3306 return ret;
3307 }
3308
3309 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3310 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3311 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3312 {
3313 BOOL ret = FALSE;
3314
3315 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3316 pDecodePara, pvStructInfo, *pcbStructInfo);
3317
3318 __TRY
3319 {
3320 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3321 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3322 if (ret && pvStructInfo)
3323 {
3324 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3325 pcbStructInfo, *pcbStructInfo);
3326 if (ret)
3327 {
3328 CRYPT_CONTENT_INFO *info;
3329
3330 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3331 pvStructInfo = *(BYTE **)pvStructInfo;
3332 info = pvStructInfo;
3333 info->pszObjId = (LPSTR)((BYTE *)info +
3334 sizeof(CRYPT_CONTENT_INFO));
3335 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3336 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3337 pcbStructInfo, NULL);
3338 }
3339 }
3340 }
3341 __EXCEPT_PAGE_FAULT
3342 {
3343 SetLastError(STATUS_ACCESS_VIOLATION);
3344 }
3345 __ENDTRY
3346 return ret;
3347 }
3348
3349 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3350 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3351 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3352 {
3353 BOOL ret;
3354 struct AsnDecodeSequenceItem items[] = {
3355 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3356 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3357 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3358 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3359 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3360 0 },
3361 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3362 CRYPT_AsnDecodePKCSContentInfoInternal,
3363 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3364 ContentInfo.pszObjId), 0 },
3365 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3366 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3367 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3368 };
3369
3370 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3371 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3372 NULL, NULL);
3373 return ret;
3374 }
3375
3376 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3377 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3378 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3379 {
3380 BOOL ret = TRUE;
3381
3382 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3383 pDecodePara, pvStructInfo, *pcbStructInfo);
3384
3385 __TRY
3386 {
3387 DWORD bytesNeeded;
3388
3389 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3390 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3391 {
3392 if (!pvStructInfo)
3393 *pcbStructInfo = bytesNeeded;
3394 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3395 pvStructInfo, pcbStructInfo, bytesNeeded)))
3396 {
3397 CERT_ALT_NAME_INFO *name;
3398
3399 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3400 pvStructInfo = *(BYTE **)pvStructInfo;
3401 name = pvStructInfo;
3402 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3403 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3404 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3405 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3406 &bytesNeeded, NULL);
3407 }
3408 }
3409 }
3410 __EXCEPT_PAGE_FAULT
3411 {
3412 SetLastError(STATUS_ACCESS_VIOLATION);
3413 ret = FALSE;
3414 }
3415 __ENDTRY
3416 return ret;
3417 }
3418
3419 struct PATH_LEN_CONSTRAINT
3420 {
3421 BOOL fPathLenConstraint;
3422 DWORD dwPathLenConstraint;
3423 };
3424
3425 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3426 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3427 DWORD *pcbDecoded)
3428 {
3429 BOOL ret = TRUE;
3430 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3431
3432 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3433 pvStructInfo, *pcbStructInfo, pcbDecoded);
3434
3435 if (!pvStructInfo)
3436 {
3437 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3438 &size, pcbDecoded);
3439 *pcbStructInfo = bytesNeeded;
3440 }
3441 else if (*pcbStructInfo < bytesNeeded)
3442 {
3443 SetLastError(ERROR_MORE_DATA);
3444 *pcbStructInfo = bytesNeeded;
3445 ret = FALSE;
3446 }
3447 else
3448 {
3449 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3450
3451 *pcbStructInfo = bytesNeeded;
3452 size = sizeof(constraint->dwPathLenConstraint);
3453 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3454 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3455 if (ret)
3456 constraint->fPathLenConstraint = TRUE;
3457 TRACE("got an int, dwPathLenConstraint is %d\n",
3458 constraint->dwPathLenConstraint);
3459 }
3460 TRACE("returning %d (%08x)\n", ret, GetLastError());
3461 return ret;
3462 }
3463
3464 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3465 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3466 DWORD *pcbDecoded)
3467 {
3468 BOOL ret;
3469 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3470 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3471 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3472 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3473 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3474 offsetof(CERT_NAME_BLOB, pbData) };
3475
3476 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3477 pvStructInfo, *pcbStructInfo, pcbDecoded);
3478
3479 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3480 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3481 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3482 return ret;
3483 }
3484
3485 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3486 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3487 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3488 {
3489 BOOL ret;
3490
3491 __TRY
3492 {
3493 struct AsnDecodeSequenceItem items[] = {
3494 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3495 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3496 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3497 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3498 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3499 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3500 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3501 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3502 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3503 TRUE, TRUE,
3504 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3505 };
3506
3507 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3508 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3509 pcbStructInfo, NULL, NULL);
3510 }
3511 __EXCEPT_PAGE_FAULT
3512 {
3513 SetLastError(STATUS_ACCESS_VIOLATION);
3514 ret = FALSE;
3515 }
3516 __ENDTRY
3517 return ret;
3518 }
3519
3520 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3521 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3522 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3523 {
3524 BOOL ret;
3525
3526 __TRY
3527 {
3528 struct AsnDecodeSequenceItem items[] = {
3529 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3530 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3531 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3532 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3533 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3534 };
3535
3536 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3537 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3538 pcbStructInfo, NULL, NULL);
3539 }
3540 __EXCEPT_PAGE_FAULT
3541 {
3542 SetLastError(STATUS_ACCESS_VIOLATION);
3543 ret = FALSE;
3544 }
3545 __ENDTRY
3546 return ret;
3547 }
3548
3549 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3550 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3551 DWORD *pcbDecoded)
3552 {
3553 struct AsnDecodeSequenceItem items[] = {
3554 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3555 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3556 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3557 0 },
3558 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3559 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3560 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3561 };
3562 BOOL ret;
3563 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3564
3565 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3566 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3567
3568 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3569 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3570 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3571 return ret;
3572 }
3573
3574 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3575 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3576 DWORD *pcbDecoded)
3577 {
3578 BOOL ret;
3579 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3580 offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3581 offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3582 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3583 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3584 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3585
3586 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3587 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3588
3589 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3590 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3591 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3592 return ret;
3593 }
3594
3595 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3596 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3597 {
3598 struct AsnDecodeSequenceItem items[] = {
3599 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3600 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3601 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3602 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3603 CRYPT_AsnDecodePolicyQualifiers,
3604 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3605 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3606 };
3607 CERT_POLICY_INFO *info = pvStructInfo;
3608 BOOL ret;
3609
3610 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3611 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3612
3613 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3614 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3615 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3616 return ret;
3617 }
3618
3619 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3620 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3621 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3622 {
3623 BOOL ret = FALSE;
3624
3625 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3626 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3627
3628 __TRY
3629 {
3630 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3631 offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3632 offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3633 sizeof(CERT_POLICIES_INFO),
3634 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3635 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3636
3637 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3638 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3639 }
3640 __EXCEPT_PAGE_FAULT
3641 {
3642 SetLastError(STATUS_ACCESS_VIOLATION);
3643 }
3644 __ENDTRY
3645 return ret;
3646 }
3647
3648 static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
3649 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3650 DWORD *pcbDecoded)
3651 {
3652 struct AsnDecodeSequenceItem items[] = {
3653 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3654 pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3655 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 },
3656 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3657 pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3658 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 },
3659 };
3660 CERT_POLICY_MAPPING *mapping = pvStructInfo;
3661 BOOL ret;
3662
3663 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3664 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3665
3666 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3667 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3668 pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
3669 return ret;
3670 }
3671
3672 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType,
3673 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3674 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3675 {
3676 BOOL ret = FALSE;
3677
3678 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3679 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3680
3681 __TRY
3682 {
3683 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3684 offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping),
3685 offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping),
3686 sizeof(CERT_POLICY_MAPPING),
3687 CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE,
3688 offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) };
3689
3690 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3691 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3692 }
3693 __EXCEPT_PAGE_FAULT
3694 {
3695 SetLastError(STATUS_ACCESS_VIOLATION);
3696 }
3697 __ENDTRY
3698 return ret;
3699 }
3700
3701 static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded,
3702 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3703 DWORD *pcbDecoded)
3704 {
3705 BOOL ret;
3706 DWORD skip, size = sizeof(skip);
3707
3708 if (!cbEncoded)
3709 {
3710 SetLastError(CRYPT_E_ASN1_EOD);
3711 return FALSE;
3712 }
3713 if (pbEncoded[0] != (ASN_CONTEXT | 0))
3714 {
3715 SetLastError(CRYPT_E_ASN1_BADTAG);
3716 return FALSE;
3717 }
3718 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3719 &skip, &size, pcbDecoded)))
3720 {
3721 DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3722 fRequireExplicitPolicy, fInhibitPolicyMapping);
3723
3724 if (!pvStructInfo)
3725 *pcbStructInfo = bytesNeeded;
3726 else if (*pcbStructInfo < bytesNeeded)
3727 {
3728 *pcbStructInfo = bytesNeeded;
3729 SetLastError(ERROR_MORE_DATA);
3730 ret = FALSE;
3731 }
3732 else
3733 {
3734 CERT_POLICY_CONSTRAINTS_INFO *info =
3735 (CERT_POLICY_CONSTRAINTS_INFO *)((BYTE *)pvStructInfo -
3736 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy));
3737
3738 *pcbStructInfo = bytesNeeded;
3739 /* The BOOL is implicit: if the integer is present, then it's
3740 * TRUE.
3741 */
3742 info->fRequireExplicitPolicy = TRUE;
3743 info->dwRequireExplicitPolicySkipCerts = skip;
3744 }
3745 }
3746 return ret;
3747 }
3748
3749 static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded,
3750 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3751 DWORD *pcbDecoded)
3752 {
3753 BOOL ret;
3754 DWORD skip, size = sizeof(skip);
3755
3756 if (!cbEncoded)
3757 {
3758 SetLastError(CRYPT_E_ASN1_EOD);
3759 return FALSE;
3760 }
3761 if (pbEncoded[0] != (ASN_CONTEXT | 1))
3762 {
3763 SetLastError(CRYPT_E_ASN1_BADTAG);
3764 return FALSE;
3765 }
3766 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3767 &skip, &size, pcbDecoded)))
3768 {
3769 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3770 fInhibitPolicyMapping);
3771
3772 if (!pvStructInfo)
3773 *pcbStructInfo = bytesNeeded;
3774 else if (*pcbStructInfo < bytesNeeded)
3775 {
3776 *pcbStructInfo = bytesNeeded;
3777 SetLastError(ERROR_MORE_DATA);
3778 ret = FALSE;
3779 }
3780 else
3781 {
3782 CERT_POLICY_CONSTRAINTS_INFO *info =
3783 (CERT_POLICY_CONSTRAINTS_INFO *)((BYTE *)pvStructInfo -
3784 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping));
3785
3786 *pcbStructInfo = bytesNeeded;
3787 /* The BOOL is implicit: if the integer is present, then it's
3788 * TRUE.
3789 */
3790 info->fInhibitPolicyMapping = TRUE;
3791 info->dwInhibitPolicyMappingSkipCerts = skip;
3792 }
3793 }
3794 return ret;
3795 }
3796
3797 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
3798 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
3799 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3800 void *pvStructInfo, DWORD *pcbStructInfo)
3801 {
3802 BOOL ret = FALSE;
3803
3804 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3805 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3806
3807 __TRY
3808 {
3809 struct AsnDecodeSequenceItem items[] = {
3810 { ASN_CONTEXT | 0,
3811 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy),
3812 CRYPT_AsnDecodeRequireExplicit,
3813 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy,
3814 fInhibitPolicyMapping), TRUE, FALSE, 0, 0 },
3815 { ASN_CONTEXT | 1,
3816 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3817 CRYPT_AsnDecodeInhibitMapping,
3818 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3819 TRUE, FALSE, 0, 0 },
3820 };
3821
3822 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3823 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3824 pcbStructInfo, NULL, NULL);
3825 }
3826 __EXCEPT_PAGE_FAULT
3827 {
3828 SetLastError(STATUS_ACCESS_VIOLATION);
3829 }
3830 __ENDTRY
3831 return ret;
3832 }
3833
3834 #define RSA1_MAGIC 0x31415352
3835
3836 struct DECODED_RSA_PUB_KEY
3837 {
3838 DWORD pubexp;
3839 CRYPT_INTEGER_BLOB modulus;
3840 };
3841
3842 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3843 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3844 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3845 {
3846 BOOL ret;
3847
3848 __TRY
3849 {
3850 struct AsnDecodeSequenceItem items[] = {
3851 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3852 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3853 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3854 0 },
3855 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3856 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3857 };
3858 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3859 DWORD size = 0;
3860
3861 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3862 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3863 &size, NULL, NULL);
3864 if (ret)
3865 {
3866 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3867 decodedKey->modulus.cbData;
3868
3869 if (!pvStructInfo)
3870 {
3871 *pcbStructInfo = bytesNeeded;
3872 ret = TRUE;
3873 }
3874 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3875 pvStructInfo, pcbStructInfo, bytesNeeded)))
3876 {
3877 BLOBHEADER *hdr;
3878 RSAPUBKEY *rsaPubKey;
3879
3880 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3881 pvStructInfo = *(BYTE **)pvStructInfo;
3882 hdr = pvStructInfo;
3883 hdr->bType = PUBLICKEYBLOB;
3884 hdr->bVersion = CUR_BLOB_VERSION;
3885 hdr->reserved = 0;
3886 hdr->aiKeyAlg = CALG_RSA_KEYX;
3887 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3888 sizeof(BLOBHEADER));
3889 rsaPubKey->magic = RSA1_MAGIC;
3890 rsaPubKey->pubexp = decodedKey->pubexp;
3891 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3892 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3893 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3894 decodedKey->modulus.cbData);
3895 }
3896 LocalFree(decodedKey);
3897 }
3898 }
3899 __EXCEPT_PAGE_FAULT
3900 {
3901 SetLastError(STATUS_ACCESS_VIOLATION);
3902 ret = FALSE;
3903 }
3904 __ENDTRY
3905 return ret;
3906 }
3907
3908 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3909 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3910 DWORD *pcbDecoded)
3911 {
3912 BOOL ret;
3913 DWORD bytesNeeded, dataLen;
3914
3915 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3916 pvStructInfo, *pcbStructInfo, pcbDecoded);
3917
3918 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3919 {
3920 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3921
3922 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3923 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3924 else
3925 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3926 if (pcbDecoded)
3927 *pcbDecoded = 1 + lenBytes + dataLen;
3928 if (!pvStructInfo)
3929 *pcbStructInfo = bytesNeeded;
3930 else if (*pcbStructInfo < bytesNeeded)
3931 {
3932 SetLastError(ERROR_MORE_DATA);
3933 *pcbStructInfo = bytesNeeded;
3934 ret = FALSE;
3935 }
3936 else
3937 {
3938 CRYPT_DATA_BLOB *blob;
3939
3940 *pcbStructInfo = bytesNeeded;
3941 blob = pvStructInfo;
3942 blob->cbData = dataLen;
3943 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3944 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3945 else
3946 {
3947 assert(blob->pbData);
3948 if (blob->cbData)
3949 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3950 blob->cbData);
3951 }
3952 }
3953 }
3954 return ret;
3955 }
3956
3957 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3958 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3959 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3960 {
3961 BOOL ret;
3962
3963 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3964 pDecodePara, pvStructInfo, *pcbStructInfo);
3965
3966 __TRY
3967 {
3968 DWORD bytesNeeded;
3969
3970 if (!cbEncoded)
3971 {
3972 SetLastError(CRYPT_E_ASN1_CORRUPT);
3973 ret = FALSE;
3974 }
3975 else if (pbEncoded[0] != ASN_OCTETSTRING)
3976 {
3977 SetLastError(CRYPT_E_ASN1_BADTAG);
3978 ret = FALSE;
3979 }
3980 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3981 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3982 {
3983 if (!pvStructInfo)
3984 *pcbStructInfo = bytesNeeded;
3985 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3986 pvStructInfo, pcbStructInfo, bytesNeeded)))
3987 {
3988 CRYPT_DATA_BLOB *blob;
3989
3990 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3991 pvStructInfo = *(BYTE **)pvStructInfo;
3992 blob = pvStructInfo;
3993 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3994 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3995 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3996 &bytesNeeded, NULL);
3997 }
3998 }
3999 }
4000 __EXCEPT_PAGE_FAULT
4001 {
4002 SetLastError(STATUS_ACCESS_VIOLATION);
4003 ret = FALSE;
4004 }
4005 __ENDTRY
4006 return ret;
4007 }
4008
4009 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4010 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4011 {
4012 BOOL ret;
4013 DWORD bytesNeeded, dataLen;
4014 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4015
4016 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
4017 pvStructInfo, *pcbStructInfo, pcbDecoded);
4018
4019 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4020 {
4021 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4022 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
4023 else
4024 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
4025 if (pcbDecoded)
4026 *pcbDecoded = 1 + lenBytes + dataLen;
4027 if (!pvStructInfo)
4028 *pcbStructInfo = bytesNeeded;
4029 else if (*pcbStructInfo < bytesNeeded)
4030 {
4031 *pcbStructInfo = bytesNeeded;
4032 SetLastError(ERROR_MORE_DATA);
4033 ret = FALSE;
4034 }
4035 else
4036 {
4037 CRYPT_BIT_BLOB *blob;
4038
4039 *pcbStructInfo = bytesNeeded;
4040 blob = pvStructInfo;
4041 blob->cbData = dataLen - 1;
4042 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
4043 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4044 {
4045 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
4046 }
4047 else
4048 {
4049 assert(blob->pbData);
4050 if (blob->cbData)
4051 {
4052 BYTE mask = 0xff << blob->cUnusedBits;
4053
4054 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
4055 blob->cbData);
4056 blob->pbData[blob->cbData - 1] &= mask;
4057 }
4058 }
4059 }
4060 }
4061 return ret;
4062 }
4063
4064 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
4065 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4066 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4067 {
4068 BOOL ret;
4069
4070 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
4071 pDecodePara, pvStructInfo, pcbStructInfo);
4072
4073 __TRY
4074 {
4075 DWORD bytesNeeded;
4076
4077 if (!cbEncoded)
4078 {
4079 SetLastError(CRYPT_E_ASN1_CORRUPT);
4080 ret = FALSE;
4081 }
4082 else if (pbEncoded[0] != ASN_BITSTRING)
4083 {
4084 SetLastError(CRYPT_E_ASN1_BADTAG);
4085 ret = FALSE;
4086 }
4087 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4088 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4089 {
4090 if (!pvStructInfo)
4091 *pcbStructInfo = bytesNeeded;
4092 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4093 pvStructInfo, pcbStructInfo, bytesNeeded)))
4094 {
4095 CRYPT_BIT_BLOB *blob;
4096
4097 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4098 pvStructInfo = *(BYTE **)pvStructInfo;
4099 blob = pvStructInfo;
4100 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
4101 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4102 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4103 &bytesNeeded, NULL);
4104 }
4105 }
4106 }
4107 __EXCEPT_PAGE_FAULT
4108 {
4109 SetLastError(STATUS_ACCESS_VIOLATION);
4110 ret = FALSE;
4111 }
4112 __ENDTRY
4113 TRACE("returning %d (%08x)\n", ret, GetLastError());
4114 return ret;
4115 }
4116
4117 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4118 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4119 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4120 {
4121 BOOL ret;
4122 DWORD dataLen;
4123
4124 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4125 {
4126 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4127
4128 if (pcbDecoded)
4129 *pcbDecoded = 1 + lenBytes + dataLen;
4130 if (dataLen > sizeof(int))
4131 {
4132 SetLastError(CRYPT_E_ASN1_LARGE);
4133 ret = FALSE;
4134 }
4135 else if (!pvStructInfo)
4136 *pcbStructInfo = sizeof(int);
4137 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
4138 {
4139 int val, i;
4140
4141 if (dataLen && pbEncoded[1 + lenBytes] & 0x80)
4142 {
4143 /* initialize to a negative value to sign-extend */
4144 val = -1;
4145 }
4146 else
4147 val = 0;
4148 for (i = 0; i < dataLen; i++)
4149 {
4150 val <<= 8;
4151 val |= pbEncoded[1 + lenBytes + i];
4152 }
4153 memcpy(pvStructInfo, &val, sizeof(int));
4154 }
4155 }
4156 return ret;
4157 }
4158
4159 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
4160 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4161 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4162 {
4163 BOOL ret;
4164
4165 __TRY
4166 {
4167 DWORD bytesNeeded;
4168
4169 if (!cbEncoded)
4170 {
4171 SetLastError(CRYPT_E_ASN1_EOD);
4172 ret = FALSE;
4173 }
4174 else if (pbEncoded[0] != ASN_INTEGER)
4175 {
4176 SetLastError(CRYPT_E_ASN1_BADTAG);
4177 ret = FALSE;
4178 }
4179 else
4180 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4181 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4182 if (ret)
4183 {
4184 if (!pvStructInfo)
4185 *pcbStructInfo = bytesNeeded;
4186 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4187 pvStructInfo, pcbStructInfo, bytesNeeded)))
4188 {
4189 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4190 pvStructInfo = *(BYTE **)pvStructInfo;
4191 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4192 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4193 &bytesNeeded, NULL);
4194 }
4195 }
4196 }
4197 __EXCEPT_PAGE_FAULT
4198 {
4199 SetLastError(STATUS_ACCESS_VIOLATION);
4200 ret = FALSE;
4201 }
4202 __ENDTRY
4203 return ret;
4204 }
4205
4206 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4207 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4208 DWORD *pcbDecoded)
4209 {
4210 BOOL ret;
4211 DWORD bytesNeeded, dataLen;
4212
4213 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4214 {
4215 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4216
4217 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4218 if (pcbDecoded)
4219 *pcbDecoded = 1 + lenBytes + dataLen;
4220 if (!pvStructInfo)
4221 *pcbStructInfo = bytesNeeded;
4222 else if (*pcbStructInfo < bytesNeeded)
4223 {
4224 *pcbStructInfo = bytesNeeded;
4225 SetLastError(ERROR_MORE_DATA);
4226 ret = FALSE;
4227 }
4228 else
4229 {
4230 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4231
4232 *pcbStructInfo = bytesNeeded;
4233 blob->cbData = dataLen;
4234 assert(blob->pbData);
4235 if (blob->cbData)
4236 {
4237 DWORD i;
4238
4239 for (i = 0; i < blob->cbData; i++)
4240 {
4241 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4242 dataLen - i - 1);
4243 }
4244 }
4245 }
4246 }
4247 return ret;
4248 }
4249
4250 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4251 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4252 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4253 {
4254 BOOL ret;
4255
4256 __TRY
4257 {
4258 DWORD bytesNeeded;
4259
4260 if (pbEncoded[0] != ASN_INTEGER)
4261 {
4262 SetLastError(CRYPT_E_ASN1_BADTAG);
4263 ret = FALSE;
4264 }
4265 else
4266 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4267 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4268 if (ret)
4269 {
4270 if (!pvStructInfo)
4271 *pcbStructInfo = bytesNeeded;
4272 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4273 pvStructInfo, pcbStructInfo, bytesNeeded)))
4274 {
4275 CRYPT_INTEGER_BLOB *blob;
4276
4277 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4278 pvStructInfo = *(BYTE **)pvStructInfo;
4279 blob = pvStructInfo;
4280 blob->pbData = (BYTE *)pvStructInfo +
4281 sizeof(CRYPT_INTEGER_BLOB);
4282 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4283 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4284 &bytesNeeded, NULL);
4285 }
4286 }
4287 }
4288 __EXCEPT_PAGE_FAULT
4289 {
4290 SetLastError(STATUS_ACCESS_VIOLATION);
4291 ret = FALSE;
4292 }
4293 __ENDTRY
4294 return ret;
4295 }
4296
4297 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4298 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4299 DWORD *pcbDecoded)
4300 {
4301 BOOL ret;
4302
4303 if (pbEncoded[0] == ASN_INTEGER)
4304 {
4305 DWORD bytesNeeded, dataLen;
4306
4307 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4308 {
4309 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4310
4311 if (pcbDecoded)
4312 *pcbDecoded = 1 + lenBytes + dataLen;
4313 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4314 if (!pvStructInfo)
4315 *pcbStructInfo = bytesNeeded;
4316 else if (*pcbStructInfo < bytesNeeded)
4317 {
4318 *pcbStructInfo = bytesNeeded;
4319 SetLastError(ERROR_MORE_DATA);
4320 ret = FALSE;
4321 }
4322 else
4323 {
4324 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4325
4326 *pcbStructInfo = bytesNeeded;
4327 blob->cbData = dataLen;
4328 assert(blob->pbData);
4329 /* remove leading zero byte if it exists */
4330 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4331 {
4332 blob->cbData--;
4333 blob->pbData++;
4334 }
4335 if (blob->cbData)
4336 {
4337 DWORD i;
4338
4339 for (i = 0; i < blob->cbData; i++)
4340 {
4341 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4342 dataLen - i - 1);
4343 }
4344 }
4345 }
4346 }
4347 }
4348 else
4349 {
4350 SetLastError(CRYPT_E_ASN1_BADTAG);
4351 ret = FALSE;
4352 }
4353 return ret;
4354 }
4355
4356 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4357 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4358 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4359 {
4360 BOOL ret;
4361
4362 __TRY
4363 {
4364 DWORD bytesNeeded;
4365
4366 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4367 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4368 {
4369 if (!pvStructInfo)
4370 *pcbStructInfo = bytesNeeded;
4371 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4372 pvStructInfo, pcbStructInfo, bytesNeeded)))
4373 {
4374 CRYPT_INTEGER_BLOB *blob;
4375
4376 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4377 pvStructInfo = *(BYTE **)pvStructInfo;
4378 blob = pvStructInfo;
4379 blob->pbData = (BYTE *)pvStructInfo +
4380 sizeof(CRYPT_INTEGER_BLOB);
4381 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4382 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4383 &bytesNeeded, NULL);
4384 }
4385 }
4386 }
4387 __EXCEPT_PAGE_FAULT
4388 {
4389 SetLastError(STATUS_ACCESS_VIOLATION);
4390 ret = FALSE;
4391 }
4392 __ENDTRY
4393 return ret;
4394 }
4395
4396 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4397 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4398 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4399 {
4400 BOOL ret;
4401
4402 if (!pvStructInfo)
4403 {
4404 *pcbStructInfo = sizeof(int);
4405 return TRUE;
4406 }
4407 __TRY
4408 {
4409 if (pbEncoded[0] == ASN_ENUMERATED)
4410 {
4411 unsigned int val = 0, i;
4412
4413 if (cbEncoded <= 1)
4414 {
4415 SetLastError(CRYPT_E_ASN1_EOD);
4416 ret = FALSE;
4417 }
4418 else if (pbEncoded[1] == 0)
4419 {
4420 SetLastError(CRYPT_E_ASN1_CORRUPT);
4421 ret = FALSE;
4422 }
4423 else
4424 {
4425 /* A little strange looking, but we have to accept a sign byte:
4426 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4427 * assuming a small length is okay here, it has to be in short
4428 * form.
4429 */
4430 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4431 {
4432 SetLastError(CRYPT_E_ASN1_LARGE);
4433 return FALSE;
4434 }
4435 for (i = 0; i < pbEncoded[1]; i++)
4436 {
4437 val <<= 8;
4438 val |= pbEncoded[2 + i];
4439 }
4440 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4441 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4442 {
4443 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4444 pvStructInfo = *(BYTE **)pvStructInfo;
4445 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4446 }
4447 }
4448 }
4449 else
4450 {
4451 SetLastError(CRYPT_E_ASN1_BADTAG);
4452 ret = FALSE;
4453 }
4454 }
4455 __EXCEPT_PAGE_FAULT
4456 {
4457 SetLastError(STATUS_ACCESS_VIOLATION);
4458 ret = FALSE;
4459 }
4460 __ENDTRY
4461 return ret;
4462 }
4463
4464 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4465 * if it fails.
4466 */
4467 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4468 do { \
4469 BYTE i; \
4470 \
4471 (word) = 0; \
4472 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4473 { \
4474 if (!isdigit(*(pbEncoded))) \
4475 { \
4476 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4477 ret = FALSE; \
4478 } \
4479 else \
4480 { \
4481 (word) *= 10; \
4482 (word) += *(pbEncoded)++ - '0'; \
4483 } \
4484 } \
4485 } while (0)
4486
4487 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4488 SYSTEMTIME *sysTime)
4489 {
4490 BOOL ret = TRUE;
4491
4492 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4493 {
4494 WORD hours, minutes = 0;
4495 BYTE sign = *pbEncoded++;
4496
4497 len--;
4498 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4499 if (ret && hours >= 24)
4500 {
4501 SetLastError(CRYPT_E_ASN1_CORRUPT);
4502 ret = FALSE;
4503 }
4504 else if (len >= 2)
4505 {
4506 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4507 if (ret && minutes >= 60)
4508 {
4509 SetLastError(CRYPT_E_ASN1_CORRUPT);
4510 ret = FALSE;
4511 }
4512 }
4513 if (ret)
4514 {
4515 if (sign == '+')
4516 {
4517 sysTime->wHour += hours;
4518 sysTime->wMinute += minutes;
4519 }
4520 else
4521 {
4522 if (hours > sysTime->wHour)
4523 {
4524 sysTime->wDay--;
4525 sysTime->wHour = 24 - (hours - sysTime->wHour);
4526 }
4527 else
4528 sysTime->wHour -= hours;
4529 if (minutes > sysTime->wMinute)
4530 {
4531 sysTime->wHour--;
4532 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4533 }
4534 else
4535 sysTime->wMinute -= minutes;
4536 }
4537 }
4538 }
4539 return ret;
4540 }
4541
4542 #define MIN_ENCODED_TIME_LENGTH 10
4543
4544 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4545 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4546 DWORD *pcbDecoded)
4547 {
4548 BOOL ret = FALSE;
4549
4550 if (pbEncoded[0] == ASN_UTCTIME)
4551 {
4552 if (cbEncoded <= 1)
4553 SetLastError(CRYPT_E_ASN1_EOD);
4554 else if (pbEncoded[1] > 0x7f)
4555 {
4556 /* long-form date strings really can't be valid */
4557 SetLastError(CRYPT_E_ASN1_CORRUPT);
4558 }
4559 else
4560 {
4561 SYSTEMTIME sysTime = { 0 };
4562 BYTE len = pbEncoded[1];
4563
4564 if (len < MIN_ENCODED_TIME_LENGTH)
4565 SetLastError(CRYPT_E_ASN1_CORRUPT);
4566 else
4567 {
4568 ret = TRUE;
4569 if (pcbDecoded)
4570 *pcbDecoded = 2 + len;
4571 pbEncoded += 2;
4572 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4573 if (sysTime.wYear >= 50)
4574 sysTime.wYear += 1900;
4575 else
4576 sysTime.wYear += 2000;
4577 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4578 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4579 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4580 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4581 if (ret && len > 0)
4582 {
4583 if (len >= 2 && isdigit(*pbEncoded) &&
4584 isdigit(*(pbEncoded + 1)))
4585 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4586 sysTime.wSecond);
4587 else if (isdigit(*pbEncoded))
4588 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4589 sysTime.wSecond);
4590 if (ret)
4591 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4592 &sysTime);
4593 }
4594 if (ret)
4595 {
4596 if (!pvStructInfo)
4597 *pcbStructInfo = sizeof(FILETIME);
4598 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4599 sizeof(FILETIME))))
4600 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4601 }
4602 }
4603 }
4604 }
4605 else
4606 SetLastError(CRYPT_E_ASN1_BADTAG);
4607 return ret;
4608 }
4609
4610 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4611 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4612 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4613 {
4614 BOOL ret = FALSE;
4615
4616 __TRY
4617 {
4618 DWORD bytesNeeded;
4619
4620 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4621 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4622 if (ret)
4623 {
4624 if (!pvStructInfo)
4625 *pcbStructInfo = bytesNeeded;
4626 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4627 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4628 {
4629 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4630 pvStructInfo = *(BYTE **)pvStructInfo;
4631 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4632 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4633 &bytesNeeded, NULL);
4634 }
4635 }
4636 }
4637 __EXCEPT_PAGE_FAULT
4638 {
4639 SetLastError(STATUS_ACCESS_VIOLATION);
4640 }
4641 __ENDTRY
4642 return ret;
4643 }
4644
4645 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4646 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4647 DWORD *pcbDecoded)
4648 {
4649 BOOL ret = FALSE;
4650
4651 if (pbEncoded[0] == ASN_GENERALTIME)
4652 {
4653 if (cbEncoded <= 1)
4654 SetLastError(CRYPT_E_ASN1_EOD);
4655 else if (pbEncoded[1] > 0x7f)
4656 {
4657 /* long-form date strings really can't be valid */
4658 SetLastError(CRYPT_E_ASN1_CORRUPT);
4659 }
4660 else
4661 {
4662 BYTE len = pbEncoded[1];
4663
4664 if (len < MIN_ENCODED_TIME_LENGTH)
4665 SetLastError(CRYPT_E_ASN1_CORRUPT);
4666 else
4667 {
4668 SYSTEMTIME sysTime = { 0 };
4669
4670 ret = TRUE;
4671 if (pcbDecoded)
4672 *pcbDecoded = 2 + len;
4673 pbEncoded += 2;
4674 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4675 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4676 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4677 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4678 if (ret && len > 0)
4679 {
4680 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4681 sysTime.wMinute);
4682 if (ret && len > 0)
4683 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4684 sysTime.wSecond);
4685 if (ret && len > 0 && (*pbEncoded == '.' ||
4686 *pbEncoded == ','))
4687 {
4688 BYTE digits;
4689
4690 pbEncoded++;
4691 len--;
4692 /* workaround macro weirdness */
4693 digits = min(len, 3);
4694 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4695 sysTime.wMilliseconds);
4696 }
4697 if (ret)
4698 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4699 &sysTime);
4700 }
4701 if (ret)
4702 {
4703 if (!pvStructInfo)
4704 *pcbStructInfo = sizeof(FILETIME);
4705 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4706 sizeof(FILETIME))))
4707 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4708 }
4709 }
4710 }
4711 }
4712 else
4713 SetLastError(CRYPT_E_ASN1_BADTAG);
4714 return ret;
4715 }
4716
4717 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4718 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4719 DWORD *pcbDecoded)
4720 {
4721 BOOL ret;
4722 InternalDecodeFunc decode = NULL;
4723
4724 if (pbEncoded[0] == ASN_UTCTIME)
4725 decode = CRYPT_AsnDecodeUtcTimeInternal;
4726 else if (pbEncoded[0] == ASN_GENERALTIME)
4727 decode = CRYPT_AsnDecodeGeneralizedTime;
4728 if (decode)
4729 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4730 pcbStructInfo, pcbDecoded);
4731 else
4732 {
4733 SetLastError(CRYPT_E_ASN1_BADTAG);
4734 ret = FALSE;
4735 }
4736 return ret;
4737 }
4738
4739 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4740 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4741 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4742 {
4743 BOOL ret;
4744
4745 __TRY
4746 {
4747 DWORD bytesNeeded;
4748
4749 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4750 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4751 if (ret)
4752 {
4753 if (!pvStructInfo)
4754 *pcbStructInfo = bytesNeeded;
4755 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4756 pvStructInfo, pcbStructInfo, bytesNeeded)))
4757 {
4758 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4759 pvStructInfo = *(BYTE **)pvStructInfo;
4760 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4761 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4762 &bytesNeeded, NULL);
4763 }
4764 }
4765 }
4766 __EXCEPT_PAGE_FAULT
4767 {
4768 SetLastError(STATUS_ACCESS_VIOLATION);
4769 ret = FALSE;
4770 }
4771 __ENDTRY
4772 return ret;
4773 }
4774
4775 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4776 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4777 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4778 {
4779 BOOL ret = TRUE;
4780
4781 __TRY
4782 {
4783 if (pbEncoded[0] == ASN_SEQUENCEOF)
4784 {
4785 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4786
4787 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4788 {
4789 BYTE lenBytes;
4790 const BYTE *ptr;
4791
4792 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4793 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4794 cValue = 0;
4795 ptr = pbEncoded + 1 + lenBytes;
4796 remainingLen = dataLen;
4797 while (ret && remainingLen)
4798 {
4799 DWORD nextLen;
4800
4801 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4802 if (ret)
4803 {
4804 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4805
4806 remainingLen -= 1 + nextLenBytes + nextLen;
4807 ptr += 1 + nextLenBytes + nextLen;
4808 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4809 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4810 bytesNeeded += 1 + nextLenBytes + nextLen;
4811 cValue++;
4812 }
4813 }
4814 if (ret)
4815 {
4816 CRYPT_SEQUENCE_OF_ANY *seq;
4817 BYTE *nextPtr;
4818 DWORD i;
4819
4820 if (!pvStructInfo)
4821 *pcbStructInfo = bytesNeeded;
4822 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4823 pvStructInfo, pcbStructInfo, bytesNeeded)))
4824 {
4825 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4826 pvStructInfo = *(BYTE **)pvStructInfo;
4827 seq = pvStructInfo;
4828 seq->cValue = cValue;
4829 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4830 sizeof(*seq));
4831 nextPtr = (BYTE *)seq->rgValue +
4832 cValue * sizeof(CRYPT_DER_BLOB);
4833 ptr = pbEncoded + 1 + lenBytes;
4834 remainingLen = dataLen;
4835 i = 0;
4836 while (ret && remainingLen)
4837 {
4838 DWORD nextLen;
4839
4840 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4841 if (ret)
4842 {
4843 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4844
4845 seq->rgValue[i].cbData = 1 + nextLenBytes +
4846 nextLen;
4847 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4848 seq->rgValue[i].pbData = (BYTE *)ptr;
4849 else
4850 {
4851 seq->rgValue[i].pbData = nextPtr;
4852 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4853 nextLen);
4854 nextPtr += 1 + nextLenBytes + nextLen;
4855 }
4856 remainingLen -= 1 + nextLenBytes + nextLen;
4857 ptr += 1 + nextLenBytes + nextLen;
4858 i++;
4859 }
4860 }
4861 }
4862 }
4863 }
4864 }
4865 else
4866 {
4867 SetLastError(CRYPT_E_ASN1_BADTAG);
4868 ret = FALSE;
4869 }
4870 }
4871 __EXCEPT_PAGE_FAULT
4872 {
4873 SetLastError(STATUS_ACCESS_VIOLATION);
4874 ret = FALSE;
4875 }
4876 __ENDTRY
4877 return ret;
4878 }
4879
4880 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4881 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4882 DWORD *pcbDecoded)
4883 {
4884 BOOL ret;
4885
4886 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4887 {
4888 DWORD bytesNeeded, dataLen;
4889
4890 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4891 {
4892 struct AsnArrayDescriptor arrayDesc = {
4893 ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4894 offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
4895 offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
4896 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
4897 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4898 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4899 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4900 DWORD nameLen;
4901
4902 if (dataLen)
4903 {
4904 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4905 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4906 dwFlags, NULL, NULL, &nameLen, NULL);
4907 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4908 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
4909 }
4910 else
4911 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4912 if (pcbDecoded)
4913 *pcbDecoded = 1 + lenBytes + dataLen;
4914 if (!pvStructInfo)
4915 *pcbStructInfo = bytesNeeded;
4916 else if (*pcbStructInfo < bytesNeeded)
4917 {
4918 *pcbStructInfo = bytesNeeded;
4919 SetLastError(ERROR_MORE_DATA);
4920 ret = FALSE;
4921 }
4922 else
4923 {
4924 CRL_DIST_POINT_NAME *name = pvStructInfo;
4925
4926 *pcbStructInfo = bytesNeeded;
4927 if (dataLen)
4928 {
4929 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4930 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4931 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4932 dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
4933 NULL);
4934 }
4935 else
4936 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4937 }
4938 }
4939 }
4940 else
4941 {
4942 SetLastError(CRYPT_E_ASN1_BADTAG);
4943 ret = FALSE;
4944 }
4945 return ret;
4946 }
4947
4948 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4949 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4950 {
4951 struct AsnDecodeSequenceItem items[] = {
4952 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
4953 DistPointName), CRYPT_AsnDecodeDistPointName,
4954 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
4955 DistPointName.u.FullName.rgAltEntry), 0 },
4956 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
4957 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
4958 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
4959 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
4960 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
4961 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
4962 };
4963 CRL_DIST_POINT *point = pvStructInfo;
4964 BOOL ret;
4965
4966 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4967 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4968 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
4969 return ret;
4970 }
4971
4972 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
4973 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4974 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4975 {
4976 BOOL ret;
4977
4978 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4979 pDecodePara, pvStructInfo, *pcbStructInfo);
4980
4981 __TRY
4982 {
4983 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4984 offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
4985 offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
4986 sizeof(CRL_DIST_POINTS_INFO),
4987 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4988 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4989
4990 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4991 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
4992 }
4993 __EXCEPT_PAGE_FAULT
4994 {
4995 SetLastError(STATUS_ACCESS_VIOLATION);
4996 ret = FALSE;
4997 }
4998 __ENDTRY
4999 return ret;
5000 }
5001
5002 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
5003 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5004 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5005 {
5006 BOOL ret;
5007
5008 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5009 pDecodePara, pvStructInfo, *pcbStructInfo);
5010
5011 __TRY
5012 {
5013 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5014 offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
5015 offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
5016 sizeof(CERT_ENHKEY_USAGE),
5017 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
5018
5019 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5020 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5021 }
5022 __EXCEPT_PAGE_FAULT
5023 {
5024 SetLastError(STATUS_ACCESS_VIOLATION);
5025 ret = FALSE;
5026 }
5027 __ENDTRY
5028 return ret;
5029 }
5030
5031 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
5032 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5033 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5034 {
5035 BOOL ret;
5036
5037 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5038 pDecodePara, pvStructInfo, *pcbStructInfo);
5039
5040 __TRY
5041 {
5042 struct AsnDecodeSequenceItem items[] = {
5043 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
5044 DistPointName), CRYPT_AsnDecodeDistPointName,
5045 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
5046 offsetof(CRL_ISSUING_DIST_POINT,
5047 DistPointName.u.FullName.rgAltEntry), 0 },
5048 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
5049 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5050 FALSE, 0 },
5051 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
5052 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5053 FALSE, 0 },
5054 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
5055 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
5056 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
5057 OnlySomeReasonFlags.pbData), 0 },
5058 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
5059 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
5060 };
5061
5062 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5063 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5064 pcbStructInfo, NULL, NULL);
5065 }
5066 __EXCEPT_PAGE_FAULT
5067 {
5068 SetLastError(STATUS_ACCESS_VIOLATION);
5069 ret = FALSE;
5070 }
5071 __ENDTRY
5072 return ret;
5073 }
5074
5075 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
5076 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5077 DWORD *pcbDecoded)
5078 {
5079 BOOL ret;
5080 DWORD max, size = sizeof(max);
5081
5082 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5083 pvStructInfo, *pcbStructInfo, pcbDecoded);
5084
5085 if (!cbEncoded)
5086 {
5087 SetLastError(CRYPT_E_ASN1_EOD);
5088 return FALSE;
5089 }
5090 if (pbEncoded[0] != (ASN_CONTEXT | 1))
5091 {
5092 SetLastError(CRYPT_E_ASN1_BADTAG);
5093 return FALSE;
5094 }
5095 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
5096 &max, &size, pcbDecoded)))
5097 {
5098 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum);
5099
5100 if (!pvStructInfo)
5101 *pcbStructInfo = bytesNeeded;
5102 else if (*pcbStructInfo < bytesNeeded)
5103 {
5104 *pcbStructInfo = bytesNeeded;
5105 SetLastError(ERROR_MORE_DATA);
5106 ret = FALSE;
5107 }
5108 else
5109 {
5110 CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)
5111 ((BYTE *)pvStructInfo - offsetof(CERT_GENERAL_SUBTREE, fMaximum));
5112
5113 *pcbStructInfo = bytesNeeded;
5114 /* The BOOL is implicit: if the integer is present, then it's
5115 * TRUE.
5116 */
5117 subtree->fMaximum = TRUE;
5118 subtree->dwMaximum = max;
5119 }
5120 }
5121 TRACE("returning %d\n", ret);
5122 return ret;
5123 }
5124
5125 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
5126 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5127 DWORD *pcbDecoded)
5128 {
5129 BOOL ret;
5130 struct AsnDecodeSequenceItem items[] = {
5131 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
5132 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
5133 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
5134 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
5135 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
5136 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
5137 CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum),
5138 TRUE, FALSE, 0, 0 },
5139 };
5140 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
5141
5142 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5143 pvStructInfo, *pcbStructInfo, pcbDecoded);
5144
5145 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5146 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5147 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
5148 if (pcbDecoded)
5149 {
5150 TRACE("%d\n", *pcbDecoded);
5151 if (*pcbDecoded < cbEncoded)
5152 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
5153 *(pbEncoded + *pcbDecoded + 1));
5154 }
5155 TRACE("returning %d\n", ret);
5156 return ret;
5157 }
5158
5159 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
5160 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5161 DWORD *pcbDecoded)
5162 {
5163 BOOL ret = TRUE;
5164 struct AsnArrayDescriptor arrayDesc = { 0,
5165 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5166 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
5167 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5168 cExcludedSubtree),
5169 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5170 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5171
5172 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5173 pvStructInfo, *pcbStructInfo, pcbDecoded);
5174
5175 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5176 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5177 return ret;
5178 }
5179
5180 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
5181 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5182 DWORD *pcbDecoded)
5183 {
5184 BOOL ret = TRUE;
5185 struct AsnArrayDescriptor arrayDesc = { 0,
5186 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5187 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
5188 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5189 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5190 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5191
5192 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5193 pvStructInfo, *pcbStructInfo, pcbDecoded);
5194
5195 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5196 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5197 return ret;
5198 }
5199
5200 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
5201 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5202 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5203 {
5204 BOOL ret = FALSE;
5205
5206 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5207 pDecodePara, pvStructInfo, *pcbStructInfo);
5208
5209 __TRY
5210 {
5211 struct AsnDecodeSequenceItem items[] = {
5212 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5213 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5214 CRYPT_AsnDecodePermittedSubtree,
5215 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5216 cExcludedSubtree), TRUE, TRUE,
5217 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
5218 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
5219 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5220 CRYPT_AsnDecodeExcludedSubtree,
5221 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5222 TRUE, TRUE,
5223 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
5224 };
5225
5226 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5227 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5228 pcbStructInfo, NULL, NULL);
5229 }
5230 __EXCEPT_PAGE_FAULT
5231 {
5232 SetLastError(STATUS_ACCESS_VIOLATION);
5233 }
5234 __ENDTRY
5235 return ret;
5236 }
5237
5238 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5239 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5240 DWORD *pcbDecoded)
5241 {
5242 BOOL ret;
5243 struct AsnDecodeSequenceItem items[] = {
5244 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5245 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5246 Issuer.pbData) },
5247 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5248 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5249 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5250 };
5251 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5252
5253 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5254 pvStructInfo, *pcbStructInfo, pcbDecoded);
5255
5256 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5257 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5258 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5259 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5260 {
5261 SetLastError(CRYPT_E_ASN1_CORRUPT);
5262 ret = FALSE;
5263 }
5264 TRACE("returning %d\n", ret);
5265 return ret;
5266 }
5267
5268 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5269 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5270 DWORD *pcbDecoded)
5271 {
5272 CMSG_SIGNER_INFO *info = pvStructInfo;
5273 struct AsnDecodeSequenceItem items[] = {
5274 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5275 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5276 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5277 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5278 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5279 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5280 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5281 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5282 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5283 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5284 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5285 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5286 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5287 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5288 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5289 HashEncryptionAlgorithm.pszObjId), 0 },
5290 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5291 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5292 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5293 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5294 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5295 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5296 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5297 };
5298 BOOL ret;
5299
5300 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5301 pvStructInfo, *pcbStructInfo);
5302
5303 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5304 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5305 pcbDecoded, info ? info->Issuer.pbData : NULL);
5306 return ret;
5307 }
5308
5309 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5310 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5311 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5312 {
5313 BOOL ret = FALSE;
5314
5315 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5316 pDecodePara, pvStructInfo, *pcbStructInfo);
5317
5318 __TRY
5319 {
5320 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5321 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5322 if (ret && pvStructInfo)
5323 {
5324 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5325 pcbStructInfo, *pcbStructInfo);
5326 if (ret)
5327 {
5328 CMSG_SIGNER_INFO *info;
5329
5330 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5331 pvStructInfo = *(BYTE **)pvStructInfo;
5332 info = pvStructInfo;
5333 info->Issuer.pbData = ((BYTE *)info +
5334 sizeof(CMSG_SIGNER_INFO));
5335 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5336 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5337 pcbStructInfo, NULL);
5338 }
5339 }
5340 }
5341 __EXCEPT_PAGE_FAULT
5342 {
5343 SetLastError(STATUS_ACCESS_VIOLATION);
5344 }
5345 __ENDTRY
5346 TRACE("returning %d\n", ret);
5347 return ret;
5348 }
5349
5350 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5351 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5352 DWORD *pcbDecoded)
5353 {
5354 BOOL ret;
5355 struct AsnArrayDescriptor arrayDesc = { 0,
5356 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5357 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5358 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5359 CRYPT_AsnDecodeCopyBytes,
5360 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5361
5362 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5363 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5364
5365 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5366 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5367 return ret;
5368 }
5369
5370 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5371 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5372 DWORD *pcbDecoded)
5373 {
5374 BOOL ret;
5375 struct AsnArrayDescriptor arrayDesc = { 0,
5376 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5377 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5378 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5379 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5380 TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5381
5382 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5383 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5384
5385 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5386 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5387 return ret;
5388 }
5389
5390 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5391 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5392 DWORD *pcbDecoded)
5393 {
5394 CERT_ID *id = pvStructInfo;
5395 BOOL ret = FALSE;
5396
5397 if (*pbEncoded == ASN_SEQUENCEOF)
5398 {
5399 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5400 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5401 if (ret)
5402 {
5403 if (id)
5404 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5405 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5406 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5407 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5408 else
5409 *pcbStructInfo = sizeof(CERT_ID);
5410 }
5411 }
5412 else if (*pbEncoded == (ASN_CONTEXT | 0))
5413 {
5414 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5415 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5416 if (ret)
5417 {
5418 if (id)
5419 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5420 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5421 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5422 sizeof(CRYPT_DATA_BLOB);
5423 else
5424 *pcbStructInfo = sizeof(CERT_ID);
5425 }
5426 }
5427 else
5428 SetLastError(CRYPT_E_ASN1_BADTAG);
5429 return ret;
5430 }
5431
5432 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5433 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5434 DWORD *pcbDecoded)
5435 {
5436 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5437 struct AsnDecodeSequenceItem items[] = {
5438 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5439 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5440 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5441 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5442 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5443 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5444 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5445 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5446 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5447 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5448 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5449 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5450 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5451 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5452 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5453 HashEncryptionAlgorithm.pszObjId), 0 },
5454 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5455 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5456 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5457 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5458 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5459 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5460 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5461 };
5462 BOOL ret;
5463
5464 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5465 pvStructInfo, *pcbStructInfo);
5466
5467 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5468 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5469 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5470 return ret;
5471 }
5472
5473 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5474 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5475 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5476 {
5477 BOOL ret = FALSE;
5478
5479 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5480 pDecodePara, pvStructInfo, *pcbStructInfo);
5481
5482 __TRY
5483 {
5484 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5485 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5486 if (ret && pvStructInfo)
5487 {
5488 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5489 pcbStructInfo, *pcbStructInfo);
5490 if (ret)
5491 {
5492 CMSG_CMS_SIGNER_INFO *info;
5493
5494 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5495 pvStructInfo = *(BYTE **)pvStructInfo;
5496 info = pvStructInfo;
5497 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5498 sizeof(CMSG_CMS_SIGNER_INFO));
5499 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5500 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5501 pcbStructInfo, NULL);
5502 }
5503 }
5504 }
5505 __EXCEPT_PAGE_FAULT
5506 {
5507 SetLastError(STATUS_ACCESS_VIOLATION);
5508 }
5509 __ENDTRY
5510 TRACE("returning %d\n", ret);
5511 return ret;
5512 }
5513
5514 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5515 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5516 {
5517 BOOL ret;
5518 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5519 offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5520 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5521 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5522 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5523 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5524
5525 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5526 pvStructInfo, *pcbStructInfo, pcbDecoded);
5527
5528 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5529 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5530 return ret;
5531 }
5532
5533 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5534 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5535 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5536 {
5537 BOOL ret = FALSE;
5538 struct AsnDecodeSequenceItem items[] = {
5539 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5540 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5541 /* Placeholder for the hash algorithms - redundant with those in the
5542 * signers, so just ignore them.
5543 */
5544 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5545 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5546 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5547 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5548 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5549 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5550 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5551 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5552 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5553 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5554 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5555 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5556 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5557 CRYPT_DecodeSignerArray,
5558 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5559 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5560 };
5561
5562 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5563 pDecodePara, signedInfo, *pcbSignedInfo);
5564
5565 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5566 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5567 NULL, NULL);
5568 TRACE("returning %d\n", ret);
5569 return ret;
5570 }
5571
5572 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5573 LPCSTR lpszStructType)
5574 {
5575 CryptDecodeObjectExFunc decodeFunc = NULL;
5576
5577 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5578 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5579 {
5580 SetLastError(ERROR_FILE_NOT_FOUND);
5581 return NULL;
5582 }
5583 if (IS_INTOID(lpszStructType))
5584 {
5585 switch (LOWORD(lpszStructType))
5586 {
5587 case LOWORD(X509_CERT):
5588 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5589 break;
5590 case LOWORD(X509_CERT_TO_BE_SIGNED):
5591 decodeFunc = CRYPT_AsnDecodeCert;
5592 break;
5593 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5594 decodeFunc = CRYPT_AsnDecodeCRL;
5595 break;
5596 case LOWORD(X509_EXTENSIONS):
5597 decodeFunc = CRYPT_AsnDecodeExtensions;
5598 break;
5599 case LOWORD(X509_NAME_VALUE):
5600 decodeFunc = CRYPT_AsnDecodeNameValue;
5601 break;
5602 case LOWORD(X509_NAME):
5603 decodeFunc = CRYPT_AsnDecodeName;
5604 break;
5605 case LOWORD(X509_PUBLIC_KEY_INFO):
5606 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5607 break;
5608 case LOWORD(X509_AUTHORITY_KEY_ID):
5609 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5610 break;
5611 case LOWORD(X509_ALTERNATE_NAME):
5612 decodeFunc = CRYPT_AsnDecodeAltName;
5613 break;
5614 case LOWORD(X509_BASIC_CONSTRAINTS):
5615 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5616 break;
5617 case LOWORD(X509_BASIC_CONSTRAINTS2):
5618 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5619 break;
5620 case LOWORD(X509_CERT_POLICIES):
5621 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5622 break;
5623 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5624 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5625 break;
5626 case LOWORD(X509_UNICODE_NAME):
5627 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5628 break;
5629 case LOWORD(PKCS_ATTRIBUTE):
5630 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5631 break;
5632 case LOWORD(X509_UNICODE_NAME_VALUE):
5633 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5634 break;
5635 case LOWORD(X509_OCTET_STRING):
5636 decodeFunc = CRYPT_AsnDecodeOctets;
5637 break;
5638 case LOWORD(X509_BITS):
5639 case LOWORD(X509_KEY_USAGE):
5640 decodeFunc = CRYPT_AsnDecodeBits;
5641 break;
5642 case LOWORD(X509_INTEGER):
5643 decodeFunc = CRYPT_AsnDecodeInt;
5644 break;
5645 case LOWORD(X509_MULTI_BYTE_INTEGER):
5646 decodeFunc = CRYPT_AsnDecodeInteger;
5647 break;
5648 case LOWORD(X509_MULTI_BYTE_UINT):
5649 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5650 break;
5651 case LOWORD(X509_ENUMERATED):
5652 decodeFunc = CRYPT_AsnDecodeEnumerated;
5653 break;
5654 case LOWORD(X509_CHOICE_OF_TIME):
5655 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5656 break;
5657 case LOWORD(X509_AUTHORITY_KEY_ID2):
5658 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5659 break;
5660 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5661 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5662 break;
5663 case LOWORD(PKCS_CONTENT_INFO):
5664 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5665 break;
5666 case LOWORD(X509_SEQUENCE_OF_ANY):
5667 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5668 break;
5669 case LOWORD(PKCS_UTC_TIME):
5670 decodeFunc = CRYPT_AsnDecodeUtcTime;
5671 break;
5672 case LOWORD(X509_CRL_DIST_POINTS):
5673 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5674 break;
5675 case LOWORD(X509_ENHANCED_KEY_USAGE):
5676 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5677 break;
5678 case LOWORD(PKCS_CTL):
5679 decodeFunc = CRYPT_AsnDecodeCTL;
5680 break;
5681 case LOWORD(PKCS_SMIME_CAPABILITIES):
5682 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5683 break;
5684 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5685 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5686 break;
5687 case LOWORD(PKCS_ATTRIBUTES):
5688 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5689 break;
5690 case LOWORD(X509_ISSUING_DIST_POINT):
5691 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5692 break;
5693 case LOWORD(X509_NAME_CONSTRAINTS):
5694 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5695 break;
5696 case LOWORD(X509_POLICY_MAPPINGS):
5697 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5698 break;
5699 case LOWORD(X509_POLICY_CONSTRAINTS):
5700 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5701 break;
5702 case LOWORD(PKCS7_SIGNER_INFO):
5703 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5704 break;
5705 case LOWORD(CMS_SIGNER_INFO):
5706 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5707 break;
5708 }
5709 }
5710 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5711 decodeFunc = CRYPT_AsnDecodeExtensions;
5712 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5713 decodeFunc = CRYPT_AsnDecodeUtcTime;
5714 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5715 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5716 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5717 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5718 else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
5719 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5720 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5721 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5722 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5723 decodeFunc = CRYPT_AsnDecodeEnumerated;
5724 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5725 decodeFunc = CRYPT_AsnDecodeBits;
5726 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5727 decodeFunc = CRYPT_AsnDecodeOctets;
5728 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5729 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5730 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5731 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5732 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5733 decodeFunc = CRYPT_AsnDecodeAltName;
5734 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5735 decodeFunc = CRYPT_AsnDecodeAltName;
5736 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5737 decodeFunc = CRYPT_AsnDecodeAltName;
5738 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5739 decodeFunc = CRYPT_AsnDecodeAltName;
5740 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5741 decodeFunc = CRYPT_AsnDecodeAltName;
5742 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5743 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5744 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5745 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5746 else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS))
5747 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5748 else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
5749 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5750 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5751 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5752 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5753 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5754 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5755 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5756 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5757 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5758 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5759 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5760 else if (!strcmp(lpszStructType, szOID_CTL))
5761 decodeFunc = CRYPT_AsnDecodeCTL;
5762 return decodeFunc;
5763 }
5764
5765 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5766 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5767 {
5768 static HCRYPTOIDFUNCSET set = NULL;
5769 CryptDecodeObjectFunc decodeFunc = NULL;
5770
5771 if (!set)
5772 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5773 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5774 (void **)&decodeFunc, hFunc);
5775 return decodeFunc;
5776 }
5777
5778 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5779 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5780 {
5781 static HCRYPTOIDFUNCSET set = NULL;
5782 CryptDecodeObjectExFunc decodeFunc = NULL;
5783
5784 if (!set)
5785 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5786 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5787 (void **)&decodeFunc, hFunc);
5788 return decodeFunc;
5789 }
5790
5791 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5792 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5793 DWORD *pcbStructInfo)
5794 {
5795 BOOL ret = FALSE;
5796 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5797 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5798 HCRYPTOIDFUNCADDR hFunc = NULL;
5799
5800 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5801 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5802 pvStructInfo, pcbStructInfo);
5803
5804 if (!pvStructInfo && !pcbStructInfo)
5805 {
5806 SetLastError(ERROR_INVALID_PARAMETER);
5807 return FALSE;
5808 }
5809 if (cbEncoded > MAX_ENCODED_LEN)
5810 {
5811 SetLastError(CRYPT_E_ASN1_LARGE);
5812 return FALSE;
5813 }
5814
5815 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5816 lpszStructType)))
5817 {
5818 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5819 debugstr_a(lpszStructType));
5820 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5821 lpszStructType, &hFunc);
5822 if (!pCryptDecodeObject)
5823 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5824 lpszStructType, &hFunc);
5825 }
5826 if (pCryptDecodeObject)
5827 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5828 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5829 else if (pCryptDecodeObjectEx)
5830 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
5831 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
5832 pvStructInfo, pcbStructInfo);
5833 if (hFunc)
5834 CryptFreeOIDFunctionAddress(hFunc, 0);
5835 TRACE_(crypt)("returning %d\n", ret);
5836 return ret;
5837 }
5838
5839 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5840 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5841 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5842 {
5843 BOOL ret = FALSE;
5844 CryptDecodeObjectExFunc decodeFunc;
5845 HCRYPTOIDFUNCADDR hFunc = NULL;
5846
5847 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5848 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
5849 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5850
5851 if (!pvStructInfo && !pcbStructInfo)
5852 {
5853 SetLastError(ERROR_INVALID_PARAMETER);
5854 return FALSE;
5855 }
5856 if (cbEncoded > MAX_ENCODED_LEN)
5857 {
5858 SetLastError(CRYPT_E_ASN1_LARGE);
5859 return FALSE;
5860 }
5861
5862 SetLastError(NOERROR);
5863 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
5864 *(BYTE **)pvStructInfo = NULL;
5865 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
5866 if (!decodeFunc)
5867 {
5868 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5869 debugstr_a(lpszStructType));
5870 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
5871 &hFunc);
5872 }
5873 if (decodeFunc)
5874 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
5875 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5876 else
5877 {
5878 CryptDecodeObjectFunc pCryptDecodeObject =
5879 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
5880
5881 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5882 * directly, as that could cause an infinite loop.
5883 */
5884 if (pCryptDecodeObject)
5885 {
5886 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5887 {
5888 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5889 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
5890 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5891 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
5892 ret = pCryptDecodeObject(dwCertEncodingType,
5893 lpszStructType, pbEncoded, cbEncoded, dwFlags,
5894 *(BYTE **)pvStructInfo, pcbStructInfo);
5895 }
5896 else
5897 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5898 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5899 }
5900 }
5901 if (hFunc)
5902 CryptFreeOIDFunctionAddress(hFunc, 0);
5903 TRACE_(crypt)("returning %d\n", ret);
5904 return ret;
5905 }
5906
5907 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
5908 {
5909 BOOL ret;
5910
5911 TRACE_(crypt)("(%p)\n", pPFX);
5912
5913 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5914 * version integer of length 1 (3 encoded byes) and at least one other
5915 * datum (two encoded bytes), plus at least two bytes for the outer
5916 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5917 */
5918 if (pPFX->cbData < 7)
5919 ret = FALSE;
5920 else if (pPFX->pbData[0] == ASN_SEQUENCE)
5921 {
5922 DWORD len;
5923
5924 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
5925 {
5926 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
5927
5928 /* Need at least three bytes for the integer version */
5929 if (pPFX->cbData < 1 + lenLen + 3)
5930 ret = FALSE;
5931 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
5932 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
5933 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
5934 ret = FALSE;
5935 }
5936 }
5937 else
5938 ret = FALSE;
5939 return ret;
5940 }
5941
5942 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
5943 DWORD dwFlags)
5944 {
5945 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
5946 return NULL;
5947 }