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