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