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