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