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