[CRYPT32] Sync with Wine Staging 4.0. CORE-15682
[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(LPTR, 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, ARRAY_SIZE(items),
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, ARRAY_SIZE(items),
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, ARRAY_SIZE(items),
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, ARRAY_SIZE(items),
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, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags,
1240 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1241
1242 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1243 return ret;
1244 }
1245
1246 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1247 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1248 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1249 {
1250 BOOL ret = FALSE;
1251
1252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1253 pDecodePara, pvStructInfo, *pcbStructInfo);
1254
1255 __TRY
1256 {
1257 DWORD size = 0;
1258
1259 /* Unless told not to, first try to decode it as a signed crl. */
1260 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1261 {
1262 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1263
1264 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1265 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1266 &signedCrl, &size);
1267 if (ret)
1268 {
1269 size = 0;
1270 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1271 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1272 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1273 pvStructInfo, pcbStructInfo);
1274 LocalFree(signedCrl);
1275 }
1276 }
1277 /* Failing that, try it as an unsigned crl */
1278 if (!ret)
1279 {
1280 size = 0;
1281 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1282 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1283 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1284 }
1285 }
1286 __EXCEPT_PAGE_FAULT
1287 {
1288 SetLastError(STATUS_ACCESS_VIOLATION);
1289 }
1290 __ENDTRY
1291
1292 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1293 return ret;
1294 }
1295
1296 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1297 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1298 {
1299 BOOL ret = TRUE;
1300 DWORD dataLen;
1301
1302 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1303 pvStructInfo, *pcbStructInfo);
1304
1305 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1306 {
1307 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1308 DWORD bytesNeeded = sizeof(LPSTR);
1309
1310 if (dataLen)
1311 {
1312 const BYTE *ptr;
1313 char str[32];
1314
1315 snprintf(str, sizeof(str), "%d.%d",
1316 pbEncoded[1 + lenBytes] / 40,
1317 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1318 * 40);
1319 bytesNeeded += strlen(str) + 1;
1320 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1321 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1322 {
1323 int val = 0;
1324
1325 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1326 (*ptr & 0x80))
1327 {
1328 val <<= 7;
1329 val |= *ptr & 0x7f;
1330 ptr++;
1331 }
1332 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1333 (*ptr & 0x80))
1334 {
1335 SetLastError(CRYPT_E_ASN1_CORRUPT);
1336 ret = FALSE;
1337 }
1338 else
1339 {
1340 val <<= 7;
1341 val |= *ptr++;
1342 snprintf(str, sizeof(str), ".%d", val);
1343 bytesNeeded += strlen(str);
1344 }
1345 }
1346 }
1347 if (pcbDecoded)
1348 *pcbDecoded = 1 + lenBytes + dataLen;
1349 if (!pvStructInfo)
1350 *pcbStructInfo = bytesNeeded;
1351 else if (*pcbStructInfo < bytesNeeded)
1352 {
1353 *pcbStructInfo = bytesNeeded;
1354 SetLastError(ERROR_MORE_DATA);
1355 ret = FALSE;
1356 }
1357 else
1358 {
1359 if (dataLen)
1360 {
1361 const BYTE *ptr;
1362 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1363
1364 *pszObjId = 0;
1365 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1366 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1367 40) * 40);
1368 pszObjId += strlen(pszObjId);
1369 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1370 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1371 {
1372 int val = 0;
1373
1374 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1375 (*ptr & 0x80))
1376 {
1377 val <<= 7;
1378 val |= *ptr & 0x7f;
1379 ptr++;
1380 }
1381 val <<= 7;
1382 val |= *ptr++;
1383 sprintf(pszObjId, ".%d", val);
1384 pszObjId += strlen(pszObjId);
1385 }
1386 }
1387 else
1388 *(LPSTR *)pvStructInfo = NULL;
1389 *pcbStructInfo = bytesNeeded;
1390 }
1391 }
1392 return ret;
1393 }
1394
1395 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1396 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1397 {
1398 BOOL ret;
1399
1400 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1401 pvStructInfo, *pcbStructInfo);
1402
1403 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1404 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1405 pvStructInfo, pcbStructInfo, pcbDecoded);
1406 else
1407 {
1408 SetLastError(CRYPT_E_ASN1_BADTAG);
1409 ret = FALSE;
1410 }
1411 return ret;
1412 }
1413
1414 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1415 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1416 {
1417 struct AsnDecodeSequenceItem items[] = {
1418 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1419 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1420 offsetof(CERT_EXTENSION, pszObjId), 0 },
1421 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1422 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1423 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1424 CRYPT_AsnDecodeOctets, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1425 offsetof(CERT_EXTENSION, Value.pbData) },
1426 };
1427 BOOL ret = TRUE;
1428 PCERT_EXTENSION ext = pvStructInfo;
1429
1430 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1431 *pcbStructInfo);
1432
1433 if (ext)
1434 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1435 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
1436 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1437 pcbDecoded, ext ? ext->pszObjId : NULL);
1438 if (ext)
1439 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1440 debugstr_a(ext->pszObjId));
1441 TRACE("returning %d (%08x)\n", ret, GetLastError());
1442 return ret;
1443 }
1444
1445 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1446 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1447 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1448 {
1449 BOOL ret = TRUE;
1450
1451 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1452 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1453
1454 __TRY
1455 {
1456 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1457 offsetof(CERT_EXTENSIONS, cExtension),
1458 offsetof(CERT_EXTENSIONS, rgExtension),
1459 sizeof(CERT_EXTENSIONS),
1460 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1461 offsetof(CERT_EXTENSION, pszObjId) };
1462 CERT_EXTENSIONS *exts = pvStructInfo;
1463
1464 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1465 exts->rgExtension = (CERT_EXTENSION *)(exts + 1);
1466 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1467 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1468 }
1469 __EXCEPT_PAGE_FAULT
1470 {
1471 SetLastError(STATUS_ACCESS_VIOLATION);
1472 ret = FALSE;
1473 }
1474 __ENDTRY
1475 return ret;
1476 }
1477
1478 /* Warning: this assumes the address of value->Value.pbData is already set, in
1479 * order to avoid overwriting memory. (In some cases, it may change it, if it
1480 * doesn't copy anything to memory.) Be sure to set it correctly!
1481 */
1482 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1483 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1484 DWORD *pcbDecoded)
1485 {
1486 BOOL ret = TRUE;
1487 DWORD dataLen;
1488 CERT_NAME_VALUE *value = pvStructInfo;
1489
1490 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1491 {
1492 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1493 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1494
1495 switch (pbEncoded[0])
1496 {
1497 case ASN_OCTETSTRING:
1498 valueType = CERT_RDN_OCTET_STRING;
1499 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1500 bytesNeeded += dataLen;
1501 break;
1502 case ASN_NUMERICSTRING:
1503 valueType = CERT_RDN_NUMERIC_STRING;
1504 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1505 bytesNeeded += dataLen;
1506 break;
1507 case ASN_PRINTABLESTRING:
1508 valueType = CERT_RDN_PRINTABLE_STRING;
1509 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1510 bytesNeeded += dataLen;
1511 break;
1512 case ASN_IA5STRING:
1513 valueType = CERT_RDN_IA5_STRING;
1514 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1515 bytesNeeded += dataLen;
1516 break;
1517 case ASN_T61STRING:
1518 valueType = CERT_RDN_T61_STRING;
1519 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1520 bytesNeeded += dataLen;
1521 break;
1522 case ASN_VIDEOTEXSTRING:
1523 valueType = CERT_RDN_VIDEOTEX_STRING;
1524 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1525 bytesNeeded += dataLen;
1526 break;
1527 case ASN_GRAPHICSTRING:
1528 valueType = CERT_RDN_GRAPHIC_STRING;
1529 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1530 bytesNeeded += dataLen;
1531 break;
1532 case ASN_VISIBLESTRING:
1533 valueType = CERT_RDN_VISIBLE_STRING;
1534 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1535 bytesNeeded += dataLen;
1536 break;
1537 case ASN_GENERALSTRING:
1538 valueType = CERT_RDN_GENERAL_STRING;
1539 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1540 bytesNeeded += dataLen;
1541 break;
1542 case ASN_UNIVERSALSTRING:
1543 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1544 SetLastError(CRYPT_E_ASN1_BADTAG);
1545 return FALSE;
1546 case ASN_BMPSTRING:
1547 valueType = CERT_RDN_BMP_STRING;
1548 bytesNeeded += dataLen;
1549 break;
1550 case ASN_UTF8STRING:
1551 valueType = CERT_RDN_UTF8_STRING;
1552 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1553 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * sizeof(WCHAR);
1554 break;
1555 default:
1556 SetLastError(CRYPT_E_ASN1_BADTAG);
1557 return FALSE;
1558 }
1559
1560 if (pcbDecoded)
1561 *pcbDecoded = 1 + lenBytes + dataLen;
1562 if (!value)
1563 *pcbStructInfo = bytesNeeded;
1564 else if (*pcbStructInfo < bytesNeeded)
1565 {
1566 *pcbStructInfo = bytesNeeded;
1567 SetLastError(ERROR_MORE_DATA);
1568 ret = FALSE;
1569 }
1570 else
1571 {
1572 *pcbStructInfo = bytesNeeded;
1573 value->dwValueType = valueType;
1574 if (dataLen)
1575 {
1576 DWORD i;
1577
1578 assert(value->Value.pbData);
1579 switch (pbEncoded[0])
1580 {
1581 case ASN_OCTETSTRING:
1582 case ASN_NUMERICSTRING:
1583 case ASN_PRINTABLESTRING:
1584 case ASN_IA5STRING:
1585 case ASN_T61STRING:
1586 case ASN_VIDEOTEXSTRING:
1587 case ASN_GRAPHICSTRING:
1588 case ASN_VISIBLESTRING:
1589 case ASN_GENERALSTRING:
1590 value->Value.cbData = dataLen;
1591 if (dataLen)
1592 {
1593 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1594 memcpy(value->Value.pbData,
1595 pbEncoded + 1 + lenBytes, dataLen);
1596 else
1597 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1598 lenBytes;
1599 }
1600 break;
1601 case ASN_BMPSTRING:
1602 {
1603 LPWSTR str = (LPWSTR)value->Value.pbData;
1604
1605 value->Value.cbData = dataLen;
1606 for (i = 0; i < dataLen / 2; i++)
1607 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1608 pbEncoded[1 + lenBytes + 2 * i + 1];
1609 break;
1610 }
1611 case ASN_UTF8STRING:
1612 {
1613 LPWSTR str = (LPWSTR)value->Value.pbData;
1614
1615 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1616 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1617 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1618 break;
1619 }
1620 }
1621 }
1622 else
1623 {
1624 value->Value.cbData = 0;
1625 value->Value.pbData = NULL;
1626 }
1627 }
1628 }
1629 return ret;
1630 }
1631
1632 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1633 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1634 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1635 {
1636 BOOL ret = TRUE;
1637
1638 __TRY
1639 {
1640 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1641 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1642 if (ret && pvStructInfo)
1643 {
1644 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1645 pcbStructInfo, *pcbStructInfo);
1646 if (ret)
1647 {
1648 CERT_NAME_VALUE *value;
1649
1650 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1651 pvStructInfo = *(BYTE **)pvStructInfo;
1652 value = pvStructInfo;
1653 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1654 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1655 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1656 pcbStructInfo, NULL);
1657 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1658 CRYPT_FreeSpace(pDecodePara, value);
1659 }
1660 }
1661 }
1662 __EXCEPT_PAGE_FAULT
1663 {
1664 SetLastError(STATUS_ACCESS_VIOLATION);
1665 ret = FALSE;
1666 }
1667 __ENDTRY
1668 return ret;
1669 }
1670
1671 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1672 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1673 DWORD *pcbDecoded)
1674 {
1675 BOOL ret = TRUE;
1676 DWORD dataLen;
1677 CERT_NAME_VALUE *value = pvStructInfo;
1678
1679 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1680 {
1681 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1682 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1683
1684 switch (pbEncoded[0])
1685 {
1686 case ASN_NUMERICSTRING:
1687 valueType = CERT_RDN_NUMERIC_STRING;
1688 if (dataLen)
1689 bytesNeeded += (dataLen + 1) * 2;
1690 break;
1691 case ASN_PRINTABLESTRING:
1692 valueType = CERT_RDN_PRINTABLE_STRING;
1693 if (dataLen)
1694 bytesNeeded += (dataLen + 1) * 2;
1695 break;
1696 case ASN_IA5STRING:
1697 valueType = CERT_RDN_IA5_STRING;
1698 if (dataLen)
1699 bytesNeeded += (dataLen + 1) * 2;
1700 break;
1701 case ASN_T61STRING:
1702 valueType = CERT_RDN_T61_STRING;
1703 if (dataLen)
1704 bytesNeeded += (dataLen + 1) * 2;
1705 break;
1706 case ASN_VIDEOTEXSTRING:
1707 valueType = CERT_RDN_VIDEOTEX_STRING;
1708 if (dataLen)
1709 bytesNeeded += (dataLen + 1) * 2;
1710 break;
1711 case ASN_GRAPHICSTRING:
1712 valueType = CERT_RDN_GRAPHIC_STRING;
1713 if (dataLen)
1714 bytesNeeded += (dataLen + 1) * 2;
1715 break;
1716 case ASN_VISIBLESTRING:
1717 valueType = CERT_RDN_VISIBLE_STRING;
1718 if (dataLen)
1719 bytesNeeded += (dataLen + 1) * 2;
1720 break;
1721 case ASN_GENERALSTRING:
1722 valueType = CERT_RDN_GENERAL_STRING;
1723 if (dataLen)
1724 bytesNeeded += (dataLen + 1) * 2;
1725 break;
1726 case ASN_UNIVERSALSTRING:
1727 valueType = CERT_RDN_UNIVERSAL_STRING;
1728 if (dataLen)
1729 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1730 break;
1731 case ASN_BMPSTRING:
1732 valueType = CERT_RDN_BMP_STRING;
1733 if (dataLen)
1734 bytesNeeded += dataLen + sizeof(WCHAR);
1735 break;
1736 case ASN_UTF8STRING:
1737 valueType = CERT_RDN_UTF8_STRING;
1738 if (dataLen)
1739 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1740 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1741 break;
1742 default:
1743 SetLastError(CRYPT_E_ASN1_BADTAG);
1744 return FALSE;
1745 }
1746
1747 if (pcbDecoded)
1748 *pcbDecoded = 1 + lenBytes + dataLen;
1749 if (!value)
1750 *pcbStructInfo = bytesNeeded;
1751 else if (*pcbStructInfo < bytesNeeded)
1752 {
1753 *pcbStructInfo = bytesNeeded;
1754 SetLastError(ERROR_MORE_DATA);
1755 ret = FALSE;
1756 }
1757 else
1758 {
1759 *pcbStructInfo = bytesNeeded;
1760 value->dwValueType = valueType;
1761 if (dataLen)
1762 {
1763 DWORD i;
1764 LPWSTR str = (LPWSTR)value->Value.pbData;
1765
1766 assert(value->Value.pbData);
1767 switch (pbEncoded[0])
1768 {
1769 case ASN_NUMERICSTRING:
1770 case ASN_PRINTABLESTRING:
1771 case ASN_IA5STRING:
1772 case ASN_T61STRING:
1773 case ASN_VIDEOTEXSTRING:
1774 case ASN_GRAPHICSTRING:
1775 case ASN_VISIBLESTRING:
1776 case ASN_GENERALSTRING:
1777 value->Value.cbData = dataLen * 2;
1778 for (i = 0; i < dataLen; i++)
1779 str[i] = pbEncoded[1 + lenBytes + i];
1780 str[i] = 0;
1781 break;
1782 case ASN_UNIVERSALSTRING:
1783 value->Value.cbData = dataLen / 2;
1784 for (i = 0; i < dataLen / 4; i++)
1785 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1786 | pbEncoded[1 + lenBytes + 2 * i + 3];
1787 str[i] = 0;
1788 break;
1789 case ASN_BMPSTRING:
1790 value->Value.cbData = dataLen;
1791 for (i = 0; i < dataLen / 2; i++)
1792 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1793 pbEncoded[1 + lenBytes + 2 * i + 1];
1794 str[i] = 0;
1795 break;
1796 case ASN_UTF8STRING:
1797 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1798 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1799 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1800 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1801 value->Value.cbData += sizeof(WCHAR);
1802 break;
1803 }
1804 }
1805 else
1806 {
1807 value->Value.cbData = 0;
1808 value->Value.pbData = NULL;
1809 }
1810 }
1811 }
1812 return ret;
1813 }
1814
1815 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1816 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1817 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1818 {
1819 BOOL ret = TRUE;
1820
1821 __TRY
1822 {
1823 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1824 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1825 if (ret && pvStructInfo)
1826 {
1827 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1828 pcbStructInfo, *pcbStructInfo);
1829 if (ret)
1830 {
1831 CERT_NAME_VALUE *value;
1832
1833 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1834 pvStructInfo = *(BYTE **)pvStructInfo;
1835 value = pvStructInfo;
1836 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1837 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1838 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1839 pcbStructInfo, NULL);
1840 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1841 CRYPT_FreeSpace(pDecodePara, value);
1842 }
1843 }
1844 }
1845 __EXCEPT_PAGE_FAULT
1846 {
1847 SetLastError(STATUS_ACCESS_VIOLATION);
1848 ret = FALSE;
1849 }
1850 __ENDTRY
1851 return ret;
1852 }
1853
1854 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1855 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1856 {
1857 BOOL ret;
1858 struct AsnDecodeSequenceItem items[] = {
1859 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1860 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1861 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1862 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1863 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1864 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1865 };
1866 CERT_RDN_ATTR *attr = pvStructInfo;
1867
1868 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1869 pvStructInfo, *pcbStructInfo);
1870
1871 if (attr)
1872 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1873 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
1874 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1875 attr ? attr->pszObjId : NULL);
1876 if (attr)
1877 {
1878 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1879 debugstr_a(attr->pszObjId));
1880 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1881 }
1882 TRACE("returning %d (%08x)\n", ret, GetLastError());
1883 return ret;
1884 }
1885
1886 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1887 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1888 {
1889 BOOL ret = TRUE;
1890 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1891 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1892 sizeof(CERT_RDN),
1893 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1894 offsetof(CERT_RDN_ATTR, pszObjId) };
1895
1896 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1897 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1898 return ret;
1899 }
1900
1901 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1902 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1903 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1904 {
1905 BOOL ret = TRUE;
1906
1907 __TRY
1908 {
1909 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1910 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1911 sizeof(CERT_NAME_INFO),
1912 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1913 offsetof(CERT_RDN, rgRDNAttr) };
1914 DWORD bytesNeeded = 0;
1915
1916 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1917 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1918 NULL);
1919 if (ret)
1920 {
1921 if (!pvStructInfo)
1922 *pcbStructInfo = bytesNeeded;
1923 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1924 pvStructInfo, pcbStructInfo, bytesNeeded)))
1925 {
1926 CERT_NAME_INFO *info;
1927
1928 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1929 pvStructInfo = *(BYTE **)pvStructInfo;
1930 info = pvStructInfo;
1931 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1932 sizeof(CERT_NAME_INFO));
1933 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1934 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1935 &bytesNeeded, NULL);
1936 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1937 CRYPT_FreeSpace(pDecodePara, info);
1938 }
1939 }
1940 }
1941 __EXCEPT_PAGE_FAULT
1942 {
1943 SetLastError(STATUS_ACCESS_VIOLATION);
1944 ret = FALSE;
1945 }
1946 __ENDTRY
1947 return ret;
1948 }
1949
1950 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1951 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1952 DWORD *pcbDecoded)
1953 {
1954 BOOL ret;
1955 struct AsnDecodeSequenceItem items[] = {
1956 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1957 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1958 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1959 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1960 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1961 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1962 };
1963 CERT_RDN_ATTR *attr = pvStructInfo;
1964
1965 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1966 pvStructInfo, *pcbStructInfo);
1967
1968 if (attr)
1969 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1970 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
1971 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1972 attr ? attr->pszObjId : NULL);
1973 if (attr)
1974 {
1975 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1976 debugstr_a(attr->pszObjId));
1977 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1978 }
1979 TRACE("returning %d (%08x)\n", ret, GetLastError());
1980 return ret;
1981 }
1982
1983 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1984 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1985 {
1986 BOOL ret = TRUE;
1987 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1988 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1989 sizeof(CERT_RDN),
1990 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1991 offsetof(CERT_RDN_ATTR, pszObjId) };
1992
1993 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1994 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1995 return ret;
1996 }
1997
1998 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1999 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2000 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2001 {
2002 BOOL ret = TRUE;
2003
2004 __TRY
2005 {
2006 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2007 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2008 sizeof(CERT_NAME_INFO),
2009 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2010 offsetof(CERT_RDN, rgRDNAttr) };
2011 DWORD bytesNeeded = 0;
2012
2013 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2014 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2015 NULL);
2016 if (ret)
2017 {
2018 if (!pvStructInfo)
2019 *pcbStructInfo = bytesNeeded;
2020 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2021 pvStructInfo, pcbStructInfo, bytesNeeded)))
2022 {
2023 CERT_NAME_INFO *info;
2024
2025 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2026 pvStructInfo = *(BYTE **)pvStructInfo;
2027 info = pvStructInfo;
2028 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2029 sizeof(CERT_NAME_INFO));
2030 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2031 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2032 &bytesNeeded, NULL);
2033 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2034 CRYPT_FreeSpace(pDecodePara, info);
2035 }
2036 }
2037 }
2038 __EXCEPT_PAGE_FAULT
2039 {
2040 SetLastError(STATUS_ACCESS_VIOLATION);
2041 ret = FALSE;
2042 }
2043 __ENDTRY
2044 return ret;
2045 }
2046
2047 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2048 DWORD *pcbDecoded)
2049 {
2050 BOOL ret = TRUE, done = FALSE;
2051 DWORD indefiniteNestingLevels = 0, decoded = 0;
2052
2053 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2054
2055 do {
2056 DWORD dataLen;
2057
2058 if (!cbEncoded)
2059 done = TRUE;
2060 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2061 &dataLen)))
2062 {
2063 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2064
2065 if (dataLen == CMSG_INDEFINITE_LENGTH)
2066 {
2067 indefiniteNestingLevels++;
2068 pbEncoded += 1 + lenBytes;
2069 cbEncoded -= 1 + lenBytes;
2070 decoded += 1 + lenBytes;
2071 TRACE("indefiniteNestingLevels = %d\n",
2072 indefiniteNestingLevels);
2073 }
2074 else
2075 {
2076 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2077 indefiniteNestingLevels)
2078 {
2079 indefiniteNestingLevels--;
2080 TRACE("indefiniteNestingLevels = %d\n",
2081 indefiniteNestingLevels);
2082 }
2083 pbEncoded += 1 + lenBytes + dataLen;
2084 cbEncoded -= 1 + lenBytes + dataLen;
2085 decoded += 1 + lenBytes + dataLen;
2086 if (!indefiniteNestingLevels)
2087 done = TRUE;
2088 }
2089 }
2090 } while (ret && !done);
2091 /* If we haven't found all 0 TLVs, we haven't found the end */
2092 if (ret && indefiniteNestingLevels)
2093 {
2094 SetLastError(CRYPT_E_ASN1_EOD);
2095 ret = FALSE;
2096 }
2097 if (ret)
2098 *pcbDecoded = decoded;
2099 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2100 return ret;
2101 }
2102
2103 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2104 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2105 DWORD *pcbDecoded)
2106 {
2107 BOOL ret = TRUE;
2108 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2109
2110 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2111 pvStructInfo, *pcbStructInfo);
2112
2113 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2114 {
2115 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2116 bytesNeeded += encodedLen;
2117 if (!pvStructInfo)
2118 *pcbStructInfo = bytesNeeded;
2119 else if (*pcbStructInfo < bytesNeeded)
2120 {
2121 SetLastError(ERROR_MORE_DATA);
2122 *pcbStructInfo = bytesNeeded;
2123 ret = FALSE;
2124 }
2125 else
2126 {
2127 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2128
2129 *pcbStructInfo = bytesNeeded;
2130 blob->cbData = encodedLen;
2131 if (encodedLen)
2132 {
2133 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2134 blob->pbData = (LPBYTE)pbEncoded;
2135 else
2136 {
2137 assert(blob->pbData);
2138 memcpy(blob->pbData, pbEncoded, blob->cbData);
2139 }
2140 }
2141 else
2142 blob->pbData = NULL;
2143 }
2144 if (pcbDecoded)
2145 *pcbDecoded = encodedLen;
2146 }
2147 return ret;
2148 }
2149
2150 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2151 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2152 {
2153 BOOL ret;
2154 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2155 offsetof(CTL_USAGE, cUsageIdentifier),
2156 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2157 sizeof(CTL_USAGE),
2158 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2159
2160 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2161 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2162 return ret;
2163 }
2164
2165 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2166 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2167 DWORD *pcbDecoded)
2168 {
2169 struct AsnArrayDescriptor arrayDesc = { 0,
2170 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2171 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2172 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2173 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2174 BOOL ret;
2175
2176 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2177 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2178 return ret;
2179 }
2180
2181 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2182 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2183 {
2184 struct AsnDecodeSequenceItem items[] = {
2185 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2186 CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2187 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2188 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2189 CRYPT_AsnDecodeCTLEntryAttributes,
2190 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2191 offsetof(CTL_ENTRY, rgAttribute), 0 },
2192 };
2193 BOOL ret = TRUE;
2194 CTL_ENTRY *entry = pvStructInfo;
2195
2196 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2197 *pcbStructInfo);
2198
2199 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2200 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2201 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2202 return ret;
2203 }
2204
2205 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2206 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2207 {
2208 BOOL ret;
2209 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2210 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2211 FINALMEMBERSIZE(CTL_INFO, cExtension),
2212 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2213 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2214
2215 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2216 pvStructInfo, *pcbStructInfo, pcbDecoded);
2217
2218 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2219 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2220 return ret;
2221 }
2222
2223 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2224 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2225 DWORD *pcbDecoded)
2226 {
2227 BOOL ret = TRUE;
2228 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2229 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2230 FINALMEMBERSIZE(CTL_INFO, cExtension),
2231 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2232 offsetof(CERT_EXTENSION, pszObjId) };
2233
2234 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2235 pvStructInfo, *pcbStructInfo, pcbDecoded);
2236
2237 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2238 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2239 return ret;
2240 }
2241
2242 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2243 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2244 DWORD *pcbDecoded)
2245 {
2246 BOOL ret;
2247 DWORD dataLen;
2248
2249 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2250 {
2251 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2252
2253 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2254 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2255 if (ret && pcbDecoded)
2256 *pcbDecoded = 1 + lenBytes + dataLen;
2257 }
2258 return ret;
2259 }
2260
2261 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2262 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2263 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2264 {
2265 BOOL ret = FALSE;
2266
2267 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2268 pDecodePara, pvStructInfo, *pcbStructInfo);
2269
2270 __TRY
2271 {
2272 struct AsnDecodeSequenceItem items[] = {
2273 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2274 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2275 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2276 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2277 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2278 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2279 CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB), TRUE,
2280 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2281 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2282 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2283 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2284 { 0, offsetof(CTL_INFO, ThisUpdate),
2285 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2286 0 },
2287 { 0, offsetof(CTL_INFO, NextUpdate),
2288 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2289 0 },
2290 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2291 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2292 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2293 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2294 CRYPT_AsnDecodeCTLEntries,
2295 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2296 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2297 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2298 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2299 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2300 };
2301
2302 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2303 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2304 pcbStructInfo, NULL, NULL);
2305 }
2306 __EXCEPT_PAGE_FAULT
2307 {
2308 SetLastError(STATUS_ACCESS_VIOLATION);
2309 }
2310 __ENDTRY
2311 return ret;
2312 }
2313
2314 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2315 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2316 DWORD *pcbDecoded)
2317 {
2318 BOOL ret;
2319 struct AsnDecodeSequenceItem items[] = {
2320 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2321 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2322 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2323 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2324 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2325 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2326 };
2327 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2328
2329 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2330 pvStructInfo, *pcbStructInfo);
2331
2332 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2333 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2334 pcbDecoded, capability ? capability->pszObjId : NULL);
2335 TRACE("returning %d\n", ret);
2336 return ret;
2337 }
2338
2339 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2340 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2341 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2342 {
2343 BOOL ret = FALSE;
2344
2345 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2346 pDecodePara, pvStructInfo, *pcbStructInfo);
2347
2348 __TRY
2349 {
2350 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2351 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2352 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2353 sizeof(CRYPT_SMIME_CAPABILITIES),
2354 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2355 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2356 CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo;
2357
2358 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2359 capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1);
2360 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2361 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2362 }
2363 __EXCEPT_PAGE_FAULT
2364 {
2365 SetLastError(STATUS_ACCESS_VIOLATION);
2366 }
2367 __ENDTRY
2368 TRACE("returning %d\n", ret);
2369 return ret;
2370 }
2371
2372 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2373 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2374 DWORD *pcbDecoded)
2375 {
2376 BOOL ret = TRUE;
2377 DWORD dataLen;
2378 LPSTR *pStr = pvStructInfo;
2379
2380 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2381 {
2382 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2383 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2384
2385 if (pbEncoded[0] != ASN_IA5STRING)
2386 {
2387 SetLastError(CRYPT_E_ASN1_CORRUPT);
2388 ret = FALSE;
2389 }
2390 else
2391 {
2392 bytesNeeded += dataLen;
2393 if (pcbDecoded)
2394 *pcbDecoded = 1 + lenBytes + dataLen;
2395 if (!pvStructInfo)
2396 *pcbStructInfo = bytesNeeded;
2397 else if (*pcbStructInfo < bytesNeeded)
2398 {
2399 *pcbStructInfo = bytesNeeded;
2400 SetLastError(ERROR_MORE_DATA);
2401 ret = FALSE;
2402 }
2403 else
2404 {
2405 *pcbStructInfo = bytesNeeded;
2406 if (dataLen)
2407 {
2408 LPSTR str = *pStr;
2409
2410 assert(str);
2411 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2412 str[dataLen] = 0;
2413 }
2414 else
2415 *pStr = NULL;
2416 }
2417 }
2418 }
2419 return ret;
2420 }
2421
2422 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2423 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2424 DWORD *pcbDecoded)
2425 {
2426 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2427 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2429 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2430 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2431 BOOL ret;
2432
2433 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2434 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2435
2436 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2437 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2438 TRACE("returning %d\n", ret);
2439 return ret;
2440 }
2441
2442 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2443 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2444 DWORD *pcbDecoded)
2445 {
2446 BOOL ret;
2447 struct AsnDecodeSequenceItem items[] = {
2448 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2449 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2450 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2451 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2452 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2453 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2454 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2455 rgNoticeNumbers), 0 },
2456 };
2457 DWORD bytesNeeded = 0;
2458
2459 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2460 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2461
2462 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2463 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2464 NULL);
2465 if (ret)
2466 {
2467 /* The caller is expecting a pointer to a
2468 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2469 * CRYPT_AsnDecodeSequence is decoding a
2470 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2471 * needed, and decode again if the requisite space is available.
2472 */
2473 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2474 if (!pvStructInfo)
2475 *pcbStructInfo = bytesNeeded;
2476 else if (*pcbStructInfo < bytesNeeded)
2477 {
2478 *pcbStructInfo = bytesNeeded;
2479 SetLastError(ERROR_MORE_DATA);
2480 ret = FALSE;
2481 }
2482 else
2483 {
2484 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2485
2486 *pcbStructInfo = bytesNeeded;
2487 /* The pointer (pvStructInfo) passed in points to the first dynamic
2488 * pointer, so use it as the pointer to the
2489 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2490 * appropriate offset for the first dynamic pointer within the
2491 * notice reference by pointing to the first memory location past
2492 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2493 */
2494 noticeRef =
2495 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2496 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2497 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2498 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags,
2499 NULL, noticeRef, &bytesNeeded, pcbDecoded, noticeRef->pszOrganization);
2500 }
2501 }
2502 TRACE("returning %d\n", ret);
2503 return ret;
2504 }
2505
2506 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2507 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2508 DWORD *pcbDecoded)
2509 {
2510 BOOL ret = TRUE;
2511 DWORD dataLen;
2512
2513 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2514 {
2515 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2516 DWORD bytesNeeded = sizeof(LPWSTR);
2517
2518 switch (pbEncoded[0])
2519 {
2520 case ASN_NUMERICSTRING:
2521 if (dataLen)
2522 bytesNeeded += (dataLen + 1) * 2;
2523 break;
2524 case ASN_PRINTABLESTRING:
2525 if (dataLen)
2526 bytesNeeded += (dataLen + 1) * 2;
2527 break;
2528 case ASN_IA5STRING:
2529 if (dataLen)
2530 bytesNeeded += (dataLen + 1) * 2;
2531 break;
2532 case ASN_T61STRING:
2533 if (dataLen)
2534 bytesNeeded += (dataLen + 1) * 2;
2535 break;
2536 case ASN_VIDEOTEXSTRING:
2537 if (dataLen)
2538 bytesNeeded += (dataLen + 1) * 2;
2539 break;
2540 case ASN_GRAPHICSTRING:
2541 if (dataLen)
2542 bytesNeeded += (dataLen + 1) * 2;
2543 break;
2544 case ASN_VISIBLESTRING:
2545 if (dataLen)
2546 bytesNeeded += (dataLen + 1) * 2;
2547 break;
2548 case ASN_GENERALSTRING:
2549 if (dataLen)
2550 bytesNeeded += (dataLen + 1) * 2;
2551 break;
2552 case ASN_UNIVERSALSTRING:
2553 if (dataLen)
2554 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2555 break;
2556 case ASN_BMPSTRING:
2557 if (dataLen)
2558 bytesNeeded += dataLen + sizeof(WCHAR);
2559 break;
2560 case ASN_UTF8STRING:
2561 if (dataLen)
2562 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2563 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2564 break;
2565 default:
2566 SetLastError(CRYPT_E_ASN1_BADTAG);
2567 return FALSE;
2568 }
2569
2570 if (pcbDecoded)
2571 *pcbDecoded = 1 + lenBytes + dataLen;
2572 if (!pvStructInfo)
2573 *pcbStructInfo = bytesNeeded;
2574 else if (*pcbStructInfo < bytesNeeded)
2575 {
2576 *pcbStructInfo = bytesNeeded;
2577 SetLastError(ERROR_MORE_DATA);
2578 ret = FALSE;
2579 }
2580 else
2581 {
2582 LPWSTR *pStr = pvStructInfo;
2583
2584 *pcbStructInfo = bytesNeeded;
2585 if (dataLen)
2586 {
2587 DWORD i;
2588 LPWSTR str = *(LPWSTR *)pStr;
2589
2590 assert(str);
2591 switch (pbEncoded[0])
2592 {
2593 case ASN_NUMERICSTRING:
2594 case ASN_PRINTABLESTRING:
2595 case ASN_IA5STRING:
2596 case ASN_T61STRING:
2597 case ASN_VIDEOTEXSTRING:
2598 case ASN_GRAPHICSTRING:
2599 case ASN_VISIBLESTRING:
2600 case ASN_GENERALSTRING:
2601 for (i = 0; i < dataLen; i++)
2602 str[i] = pbEncoded[1 + lenBytes + i];
2603 str[i] = 0;
2604 break;
2605 case ASN_UNIVERSALSTRING:
2606 for (i = 0; i < dataLen / 4; i++)
2607 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2608 | pbEncoded[1 + lenBytes + 2 * i + 3];
2609 str[i] = 0;
2610 break;
2611 case ASN_BMPSTRING:
2612 for (i = 0; i < dataLen / 2; i++)
2613 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2614 pbEncoded[1 + lenBytes + 2 * i + 1];
2615 str[i] = 0;
2616 break;
2617 case ASN_UTF8STRING:
2618 {
2619 int len = MultiByteToWideChar(CP_UTF8, 0,
2620 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2621 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2622 str[len] = 0;
2623 break;
2624 }
2625 }
2626 }
2627 else
2628 *pStr = NULL;
2629 }
2630 }
2631 return ret;
2632 }
2633
2634 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2635 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2636 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2637 {
2638 BOOL ret;
2639 struct AsnDecodeSequenceItem items[] = {
2640 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2641 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2642 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2643 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2644 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2645 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2646 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2647 };
2648 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2649
2650 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2651 pvStructInfo, *pcbStructInfo);
2652
2653 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2654 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2655 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2656 TRACE("returning %d\n", ret);
2657 return ret;
2658 }
2659
2660 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2661 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2662 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2663 void *pvStructInfo, DWORD *pcbStructInfo)
2664 {
2665 BOOL ret = FALSE;
2666
2667 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2668 pDecodePara, pvStructInfo, *pcbStructInfo);
2669
2670 __TRY
2671 {
2672 DWORD bytesNeeded = 0;
2673
2674 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2675 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2676 NULL);
2677 if (ret)
2678 {
2679 if (!pvStructInfo)
2680 *pcbStructInfo = bytesNeeded;
2681 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2682 pvStructInfo, pcbStructInfo, bytesNeeded)))
2683 {
2684 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2685
2686 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2687 pvStructInfo = *(BYTE **)pvStructInfo;
2688 notice = pvStructInfo;
2689 notice->pNoticeReference =
2690 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2691 ((BYTE *)pvStructInfo +
2692 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2693 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2694 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2695 pvStructInfo, &bytesNeeded, NULL);
2696 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2697 CRYPT_FreeSpace(pDecodePara, notice);
2698 }
2699 }
2700 }
2701 __EXCEPT_PAGE_FAULT
2702 {
2703 SetLastError(STATUS_ACCESS_VIOLATION);
2704 }
2705 __ENDTRY
2706 TRACE("returning %d\n", ret);
2707 return ret;
2708 }
2709
2710 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2711 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2712 DWORD *pcbDecoded)
2713 {
2714 BOOL ret;
2715 struct AsnArrayDescriptor arrayDesc = { 0,
2716 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2717 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2718 CRYPT_AsnDecodeCopyBytes,
2719 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2720
2721 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2722 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2723
2724 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2725 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2726 return ret;
2727 }
2728
2729 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2730 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2731 DWORD *pcbDecoded)
2732 {
2733 BOOL ret;
2734 struct AsnDecodeSequenceItem items[] = {
2735 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2736 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2737 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2738 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2739 CRYPT_AsnDecodePKCSAttributeValue,
2740 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2741 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2742 };
2743 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2744
2745 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2746 pvStructInfo, *pcbStructInfo);
2747
2748 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2749 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2750 pcbDecoded, attr ? attr->pszObjId : NULL);
2751 TRACE("returning %d\n", ret);
2752 return ret;
2753 }
2754
2755 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2756 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2757 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2758 {
2759 BOOL ret = FALSE;
2760
2761 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2762 pDecodePara, pvStructInfo, *pcbStructInfo);
2763
2764 __TRY
2765 {
2766 DWORD bytesNeeded = 0;
2767
2768 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2769 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2770 if (ret)
2771 {
2772 if (!pvStructInfo)
2773 *pcbStructInfo = bytesNeeded;
2774 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2775 pvStructInfo, pcbStructInfo, bytesNeeded)))
2776 {
2777 PCRYPT_ATTRIBUTE attr;
2778
2779 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2780 pvStructInfo = *(BYTE **)pvStructInfo;
2781 attr = pvStructInfo;
2782 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2783 sizeof(CRYPT_ATTRIBUTE));
2784 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2785 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2786 NULL);
2787 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2788 CRYPT_FreeSpace(pDecodePara, attr);
2789 }
2790 }
2791 }
2792 __EXCEPT_PAGE_FAULT
2793 {
2794 SetLastError(STATUS_ACCESS_VIOLATION);
2795 }
2796 __ENDTRY
2797 TRACE("returning %d\n", ret);
2798 return ret;
2799 }
2800
2801 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2802 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2803 DWORD *pcbDecoded)
2804 {
2805 struct AsnArrayDescriptor arrayDesc = { 0,
2806 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2807 sizeof(CRYPT_ATTRIBUTES),
2808 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2809 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2810 BOOL ret;
2811
2812 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2813 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2814 return ret;
2815 }
2816
2817 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2818 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2819 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2820 {
2821 BOOL ret = FALSE;
2822
2823 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2824 pDecodePara, pvStructInfo, *pcbStructInfo);
2825
2826 __TRY
2827 {
2828 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2829 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2830 sizeof(CRYPT_ATTRIBUTES),
2831 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2832 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2833 CRYPT_ATTRIBUTES *attrs = pvStructInfo;
2834
2835 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2836 attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1);
2837 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2838 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2839 }
2840 __EXCEPT_PAGE_FAULT
2841 {
2842 SetLastError(STATUS_ACCESS_VIOLATION);
2843 }
2844 __ENDTRY
2845 TRACE("returning %d\n", ret);
2846 return ret;
2847 }
2848
2849 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2850 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2851 {
2852 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2853 BOOL ret = TRUE;
2854 struct AsnDecodeSequenceItem items[] = {
2855 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2856 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2857 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2858 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2859 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2860 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2861 };
2862
2863 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2864 pvStructInfo, *pcbStructInfo, pcbDecoded);
2865
2866 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2867 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2868 pcbDecoded, algo ? algo->pszObjId : NULL);
2869 if (ret && pvStructInfo)
2870 {
2871 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2872 debugstr_a(algo->pszObjId));
2873 }
2874 return ret;
2875 }
2876
2877 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2878 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2879 DWORD *pcbDecoded)
2880 {
2881 BOOL ret = TRUE;
2882 struct AsnDecodeSequenceItem items[] = {
2883 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2884 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2885 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2886 Algorithm.pszObjId) },
2887 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2888 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2889 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2890 };
2891 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2892
2893 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
2894 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2895 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2896 return ret;
2897 }
2898
2899 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2900 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2901 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2902 {
2903 BOOL ret = TRUE;
2904
2905 __TRY
2906 {
2907 DWORD bytesNeeded = 0;
2908
2909 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2910 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2911 {
2912 if (!pvStructInfo)
2913 *pcbStructInfo = bytesNeeded;
2914 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2915 pvStructInfo, pcbStructInfo, bytesNeeded)))
2916 {
2917 PCERT_PUBLIC_KEY_INFO info;
2918
2919 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2920 pvStructInfo = *(BYTE **)pvStructInfo;
2921 info = pvStructInfo;
2922 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2923 sizeof(CERT_PUBLIC_KEY_INFO);
2924 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2925 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2926 &bytesNeeded, NULL);
2927 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2928 CRYPT_FreeSpace(pDecodePara, info);
2929 }
2930 }
2931 }
2932 __EXCEPT_PAGE_FAULT
2933 {
2934 SetLastError(STATUS_ACCESS_VIOLATION);
2935 ret = FALSE;
2936 }
2937 __ENDTRY
2938 return ret;
2939 }
2940
2941 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2942 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2943 {
2944 BOOL ret;
2945
2946 if (cbEncoded < 3)
2947 {
2948 SetLastError(CRYPT_E_ASN1_CORRUPT);
2949 return FALSE;
2950 }
2951 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2952 {
2953 SetLastError(CRYPT_E_ASN1_CORRUPT);
2954 return FALSE;
2955 }
2956 if (pbEncoded[1] > 1)
2957 {
2958 SetLastError(CRYPT_E_ASN1_CORRUPT);
2959 return FALSE;
2960 }
2961 if (pcbDecoded)
2962 *pcbDecoded = 3;
2963 if (!pvStructInfo)
2964 {
2965 *pcbStructInfo = sizeof(BOOL);
2966 ret = TRUE;
2967 }
2968 else if (*pcbStructInfo < sizeof(BOOL))
2969 {
2970 *pcbStructInfo = sizeof(BOOL);
2971 SetLastError(ERROR_MORE_DATA);
2972 ret = FALSE;
2973 }
2974 else
2975 {
2976 *pcbStructInfo = sizeof(BOOL);
2977 *(BOOL *)pvStructInfo = pbEncoded[2] != 0;
2978 ret = TRUE;
2979 }
2980 TRACE("returning %d (%08x)\n", ret, GetLastError());
2981 return ret;
2982 }
2983
2984 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2985 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2986 {
2987 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2988 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2989 BOOL ret;
2990
2991 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2992 pvStructInfo, *pcbStructInfo);
2993
2994 if (cbEncoded < 2)
2995 {
2996 SetLastError(CRYPT_E_ASN1_CORRUPT);
2997 return FALSE;
2998 }
2999 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3000 if (1 + lenBytes > cbEncoded)
3001 {
3002 SetLastError(CRYPT_E_ASN1_CORRUPT);
3003 return FALSE;
3004 }
3005 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3006 {
3007 switch (pbEncoded[0] & ASN_TYPE_MASK)
3008 {
3009 case 1: /* rfc822Name */
3010 case 2: /* dNSName */
3011 case 6: /* uniformResourceIdentifier */
3012 if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
3013 {
3014 SetLastError(CRYPT_E_ASN1_RULE);
3015 ret = FALSE;
3016 }
3017 else
3018 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3019 break;
3020 case 4: /* directoryName */
3021 case 7: /* iPAddress */
3022 bytesNeeded += dataLen;
3023 break;
3024 case 8: /* registeredID */
3025 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3026 &dataLen, NULL);
3027 if (ret)
3028 {
3029 /* FIXME: ugly, shouldn't need to know internals of OID decode
3030 * function to use it.
3031 */
3032 bytesNeeded += dataLen - sizeof(LPSTR);
3033 }
3034 break;
3035 case 0: /* otherName */
3036 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3037 SetLastError(CRYPT_E_ASN1_BADTAG);
3038 ret = FALSE;
3039 break;
3040 case 3: /* x400Address, unimplemented */
3041 case 5: /* ediPartyName, unimplemented */
3042 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3043 SetLastError(CRYPT_E_ASN1_BADTAG);
3044 ret = FALSE;
3045 break;
3046 default:
3047 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3048 SetLastError(CRYPT_E_ASN1_CORRUPT);
3049 ret = FALSE;
3050 }
3051 if (ret)
3052 {
3053 if (pcbDecoded)
3054 *pcbDecoded = 1 + lenBytes + dataLen;
3055 if (!entry)
3056 *pcbStructInfo = bytesNeeded;
3057 else if (*pcbStructInfo < bytesNeeded)
3058 {
3059 *pcbStructInfo = bytesNeeded;
3060 SetLastError(ERROR_MORE_DATA);
3061 ret = FALSE;
3062 }
3063 else
3064 {
3065 *pcbStructInfo = bytesNeeded;
3066 /* MS used values one greater than the asn1 ones.. sigh */
3067 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3068 switch (pbEncoded[0] & ASN_TYPE_MASK)
3069 {
3070 case 1: /* rfc822Name */
3071 case 2: /* dNSName */
3072 case 6: /* uniformResourceIdentifier */
3073 {
3074 DWORD i;
3075
3076 for (i = 0; i < dataLen; i++)
3077 entry->u.pwszURL[i] =
3078 (WCHAR)pbEncoded[1 + lenBytes + i];
3079 entry->u.pwszURL[i] = 0;
3080 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3081 debugstr_w(entry->u.pwszURL));
3082 break;
3083 }
3084 case 4: /* directoryName */
3085 /* The data are memory-equivalent with the IPAddress case,
3086 * fall-through
3087 */
3088 case 7: /* iPAddress */
3089 /* The next data pointer is in the pwszURL spot, that is,
3090 * the first 4 bytes. Need to move it to the next spot.
3091 */
3092 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3093 entry->u.IPAddress.cbData = dataLen;
3094 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3095 dataLen);
3096 break;
3097 case 8: /* registeredID */
3098 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3099 &entry->u.pszRegisteredID, &dataLen, NULL);
3100 break;
3101 }
3102 }
3103 }
3104 }
3105 return ret;
3106 }
3107
3108 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3110 DWORD *pcbDecoded)
3111 {
3112 BOOL ret;
3113 struct AsnArrayDescriptor arrayDesc = { 0,
3114 offsetof(CERT_ALT_NAME_INFO, cAltEntry),