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