1 /* 2 * Copyright 2005-2009 Juan Lang 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 * 18 * This file implements ASN.1 DER decoding of a limited set of types. 19 * It isn't a full ASN.1 implementation. Microsoft implements BER 20 * encoding of many of the basic types in msasn1.dll, but that interface isn't 21 * implemented, so I implement them here. 22 * 23 * References: 24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski 25 * (available online, look for a PDF copy as the HTML versions tend to have 26 * translation errors.) 27 * 28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html 29 * 30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject" 31 */ 32 33 #include "config.h" 34 #include "wine/port.h" 35 36 #include <assert.h> 37 #include <stdarg.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 41 #define NONAMELESSUNION 42 43 #include "windef.h" 44 #include "winbase.h" 45 #include "wincrypt.h" 46 #include "winnls.h" 47 #include "snmp.h" 48 #include "wine/debug.h" 49 #include "wine/exception.h" 50 #include "crypt32_private.h" 51 52 /* This is a bit arbitrary, but to set some limit: */ 53 #define MAX_ENCODED_LEN 0x02000000 54 55 #define ASN_FLAGS_MASK 0xe0 56 #define ASN_TYPE_MASK 0x1f 57 58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn); 59 WINE_DECLARE_DEBUG_CHANNEL(crypt); 60 61 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *, 62 DWORD, DWORD, void *, DWORD *); 63 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *, 64 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *); 65 66 /* Internal decoders don't do memory allocation or exception handling, and 67 * they report how many bytes they decoded. 68 */ 69 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded, 70 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 71 72 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded, 73 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 74 DWORD *pcbDecoded); 75 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded, 76 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 77 DWORD *pcbDecoded); 78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time. 79 */ 80 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, 81 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 82 /* Assumes algo->Parameters.pbData is set ahead of time. */ 83 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded, 84 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 85 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded, 86 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */ 88 static BOOL CRYPT_AsnDecodeOctets(const BYTE *pbEncoded, 89 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 90 DWORD *pcbDecoded); 91 /* Doesn't check the tag, assumes the caller does so */ 92 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded, 93 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 94 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded, 95 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData 97 * member has been initialized, doesn't do exception handling, and doesn't do 98 * memory allocation. Also doesn't check tag, assumes the caller has checked 99 * it. 100 */ 101 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded, 102 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 103 DWORD *pcbDecoded); 104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */ 105 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded, 106 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 107 DWORD *pcbDecoded); 108 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, 109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 110 DWORD *pcbDecoded); 111 112 /* Gets the number of length bytes from the given (leading) length byte */ 113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f)) 114 115 /* Helper function to get the encoded length of the data starting at pbEncoded, 116 * where pbEncoded[0] is the tag. If the data are too short to contain a 117 * length or if the length is too large for cbEncoded, sets an appropriate 118 * error code and returns FALSE. If the encoded length is unknown due to 119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH. 120 */ 121 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded, 122 DWORD *len) 123 { 124 BOOL ret; 125 126 if (cbEncoded <= 1) 127 { 128 SetLastError(CRYPT_E_ASN1_CORRUPT); 129 ret = FALSE; 130 } 131 else if (pbEncoded[1] <= 0x7f) 132 { 133 if (pbEncoded[1] + 1 > cbEncoded) 134 { 135 SetLastError(CRYPT_E_ASN1_EOD); 136 ret = FALSE; 137 } 138 else 139 { 140 *len = pbEncoded[1]; 141 ret = TRUE; 142 } 143 } 144 else if (pbEncoded[1] == 0x80) 145 { 146 *len = CMSG_INDEFINITE_LENGTH; 147 ret = TRUE; 148 } 149 else 150 { 151 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]); 152 153 if (lenLen > sizeof(DWORD) + 1) 154 { 155 SetLastError(CRYPT_E_ASN1_LARGE); 156 ret = FALSE; 157 } 158 else if (lenLen + 2 > cbEncoded) 159 { 160 SetLastError(CRYPT_E_ASN1_CORRUPT); 161 ret = FALSE; 162 } 163 else 164 { 165 DWORD out = 0; 166 167 pbEncoded += 2; 168 while (--lenLen) 169 { 170 out <<= 8; 171 out |= *pbEncoded++; 172 } 173 if (out + lenLen + 1 > cbEncoded) 174 { 175 SetLastError(CRYPT_E_ASN1_EOD); 176 ret = FALSE; 177 } 178 else 179 { 180 *len = out; 181 ret = TRUE; 182 } 183 } 184 } 185 return ret; 186 } 187 188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */ 189 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len) 190 { 191 BOOL ret; 192 193 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) && 194 *len == CMSG_INDEFINITE_LENGTH) 195 { 196 SetLastError(CRYPT_E_ASN1_CORRUPT); 197 ret = FALSE; 198 } 199 return ret; 200 } 201 202 /* Helper function to check *pcbStructInfo, set it to the required size, and 203 * optionally to allocate memory. Assumes pvStructInfo is not NULL. 204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a 205 * pointer to the newly allocated memory. 206 */ 207 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags, 208 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, 209 DWORD bytesNeeded) 210 { 211 BOOL ret = TRUE; 212 213 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 214 { 215 if (pDecodePara && pDecodePara->pfnAlloc) 216 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded); 217 else 218 *(BYTE **)pvStructInfo = LocalAlloc(LPTR, bytesNeeded); 219 if (!*(BYTE **)pvStructInfo) 220 ret = FALSE; 221 else 222 *pcbStructInfo = bytesNeeded; 223 } 224 else if (*pcbStructInfo < bytesNeeded) 225 { 226 *pcbStructInfo = bytesNeeded; 227 SetLastError(ERROR_MORE_DATA); 228 ret = FALSE; 229 } 230 else 231 *pcbStructInfo = bytesNeeded; 232 return ret; 233 } 234 235 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA *pDecodePara, LPVOID pv) 236 { 237 if (pDecodePara && pDecodePara->pfnFree) 238 pDecodePara->pfnFree(pv); 239 else 240 LocalFree(pv); 241 } 242 243 /* Helper function to check *pcbStructInfo and set it to the required size. 244 * Assumes pvStructInfo is not NULL. 245 */ 246 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded) 247 { 248 BOOL ret; 249 250 if (*pcbStructInfo < bytesNeeded) 251 { 252 *pcbStructInfo = bytesNeeded; 253 SetLastError(ERROR_MORE_DATA); 254 ret = FALSE; 255 } 256 else 257 { 258 *pcbStructInfo = bytesNeeded; 259 ret = TRUE; 260 } 261 return ret; 262 } 263 264 /* tag: 265 * The expected tag of the item. If tag is 0, decodeFunc is called 266 * regardless of the tag value seen. 267 * offset: 268 * A sequence is decoded into a struct. The offset member is the 269 * offset of this item within that struct. 270 * decodeFunc: 271 * The decoder function to use. If this is NULL, then the member isn't 272 * decoded, but minSize space is reserved for it. 273 * minSize: 274 * The minimum amount of space occupied after decoding. You must set this. 275 * optional: 276 * If true, and the tag doesn't match the expected tag for this item, 277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is 278 * filled with 0 for this member. 279 * hasPointer, pointerOffset: 280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to 281 * the offset within the struct of the data pointer (or to the 282 * first data pointer, if more than one exist). 283 * size: 284 * Used by CRYPT_AsnDecodeSequence, not for your use. 285 */ 286 struct AsnDecodeSequenceItem 287 { 288 BYTE tag; 289 DWORD offset; 290 InternalDecodeFunc decodeFunc; 291 DWORD minSize; 292 BOOL optional; 293 BOOL hasPointer; 294 DWORD pointerOffset; 295 DWORD size; 296 }; 297 298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member)) 299 #define MEMBERSIZE(s, member, nextmember) \ 300 (offsetof(s, nextmember) - offsetof(s, member)) 301 302 /* Decodes the items in a sequence, where the items are described in items, 303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into 304 * pvStructInfo. nextData is a pointer to the memory location at which the 305 * first decoded item with a dynamic pointer should point. 306 * Upon decoding, *cbDecoded is the total number of bytes decoded. 307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set. 308 */ 309 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], 310 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 311 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded) 312 { 313 BOOL ret; 314 DWORD i, decoded = 0; 315 const BYTE *ptr = pbEncoded; 316 317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded, 318 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded); 319 320 for (i = 0, ret = TRUE; ret && i < cItem; i++) 321 { 322 if (cbEncoded - (ptr - pbEncoded) != 0) 323 { 324 DWORD itemLen; 325 326 if ((ret = CRYPT_GetLengthIndefinite(ptr, 327 cbEncoded - (ptr - pbEncoded), &itemLen))) 328 { 329 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]); 330 331 if (ptr[0] == items[i].tag || !items[i].tag) 332 { 333 DWORD itemEncodedLen; 334 335 if (itemLen == CMSG_INDEFINITE_LENGTH) 336 itemEncodedLen = cbEncoded - (ptr - pbEncoded); 337 else 338 itemEncodedLen = 1 + itemLenBytes + itemLen; 339 if (nextData && pvStructInfo && items[i].hasPointer) 340 { 341 TRACE("Setting next pointer to %p\n", 342 nextData); 343 *(BYTE **)((BYTE *)pvStructInfo + 344 items[i].pointerOffset) = nextData; 345 } 346 if (items[i].decodeFunc) 347 { 348 DWORD itemDecoded; 349 350 if (pvStructInfo) 351 TRACE("decoding item %d\n", i); 352 else 353 TRACE("sizing item %d\n", i); 354 ret = items[i].decodeFunc(ptr, itemEncodedLen, 355 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, 356 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset 357 : NULL, &items[i].size, &itemDecoded); 358 if (ret) 359 { 360 if (items[i].size < items[i].minSize) 361 items[i].size = items[i].minSize; 362 else if (items[i].size > items[i].minSize) 363 { 364 /* Account for alignment padding */ 365 items[i].size = ALIGN_DWORD_PTR(items[i].size); 366 } 367 TRACE("item %d size: %d\n", i, items[i].size); 368 if (nextData && items[i].hasPointer && 369 items[i].size > items[i].minSize) 370 nextData += items[i].size - items[i].minSize; 371 if (itemDecoded > itemEncodedLen) 372 { 373 WARN("decoded length %d exceeds encoded %d\n", 374 itemDecoded, itemEncodedLen); 375 SetLastError(CRYPT_E_ASN1_CORRUPT); 376 ret = FALSE; 377 } 378 else 379 { 380 ptr += itemDecoded; 381 decoded += itemDecoded; 382 TRACE("item %d: decoded %d bytes\n", i, 383 itemDecoded); 384 } 385 } 386 else if (items[i].optional && 387 GetLastError() == CRYPT_E_ASN1_BADTAG) 388 { 389 TRACE("skipping optional item %d\n", i); 390 items[i].size = items[i].minSize; 391 SetLastError(NOERROR); 392 ret = TRUE; 393 } 394 else 395 TRACE("item %d failed: %08x\n", i, 396 GetLastError()); 397 } 398 else if (itemLen == CMSG_INDEFINITE_LENGTH) 399 { 400 ERR("can't use indefinite length encoding without a decoder\n"); 401 SetLastError(CRYPT_E_ASN1_CORRUPT); 402 ret = FALSE; 403 } 404 else 405 { 406 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen); 407 ptr += itemEncodedLen; 408 decoded += itemEncodedLen; 409 items[i].size = items[i].minSize; 410 } 411 } 412 else if (items[i].optional) 413 { 414 TRACE("skipping optional item %d\n", i); 415 items[i].size = items[i].minSize; 416 } 417 else 418 { 419 TRACE("item %d: tag %02x doesn't match expected %02x\n", 420 i, ptr[0], items[i].tag); 421 SetLastError(CRYPT_E_ASN1_BADTAG); 422 ret = FALSE; 423 } 424 } 425 } 426 else if (items[i].optional) 427 { 428 TRACE("missing optional item %d, skipping\n", i); 429 items[i].size = items[i].minSize; 430 } 431 else 432 { 433 TRACE("not enough bytes for item %d, failing\n", i); 434 SetLastError(CRYPT_E_ASN1_CORRUPT); 435 ret = FALSE; 436 } 437 } 438 if (cbDecoded) 439 *cbDecoded = decoded; 440 TRACE("returning %d\n", ret); 441 return ret; 442 } 443 444 /* This decodes an arbitrary sequence into a contiguous block of memory 445 * (basically, a struct.) Each element being decoded is described by a struct 446 * AsnDecodeSequenceItem, see above. 447 * startingPointer is an optional pointer to the first place where dynamic 448 * data will be stored. If you know the starting offset, you may pass it 449 * here. Otherwise, pass NULL, and one will be inferred from the items. 450 */ 451 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], 452 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, 454 DWORD *pcbDecoded, void *startingPointer) 455 { 456 BOOL ret; 457 458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded, 459 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, 460 startingPointer); 461 462 if (!cbEncoded) 463 { 464 SetLastError(CRYPT_E_ASN1_EOD); 465 return FALSE; 466 } 467 if (pbEncoded[0] == ASN_SEQUENCE) 468 { 469 DWORD dataLen; 470 471 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) 472 { 473 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded; 474 const BYTE *ptr = pbEncoded + 1 + lenBytes; 475 BOOL indefinite = FALSE; 476 477 cbEncoded -= 1 + lenBytes; 478 if (dataLen == CMSG_INDEFINITE_LENGTH) 479 { 480 dataLen = cbEncoded; 481 indefinite = TRUE; 482 lenBytes += 2; 483 } 484 else if (cbEncoded < dataLen) 485 { 486 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen, 487 cbEncoded); 488 SetLastError(CRYPT_E_ASN1_CORRUPT); 489 ret = FALSE; 490 } 491 if (ret) 492 { 493 ret = CRYPT_AsnDecodeSequenceItems(items, cItem, 494 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded); 495 if (ret && dataLen == CMSG_INDEFINITE_LENGTH) 496 { 497 if (cbDecoded > cbEncoded - 2) 498 { 499 /* Not enough space for 0 TLV */ 500 SetLastError(CRYPT_E_ASN1_CORRUPT); 501 ret = FALSE; 502 } 503 else if (*(ptr + cbDecoded) != 0 || 504 *(ptr + cbDecoded + 1) != 0) 505 { 506 TRACE("expected 0 TLV\n"); 507 SetLastError(CRYPT_E_ASN1_CORRUPT); 508 ret = FALSE; 509 } 510 else 511 cbDecoded += 2; 512 } 513 } 514 if (ret && !indefinite && cbDecoded != dataLen) 515 { 516 TRACE("expected %d decoded, got %d, failing\n", dataLen, 517 cbDecoded); 518 SetLastError(CRYPT_E_ASN1_CORRUPT); 519 ret = FALSE; 520 } 521 if (ret) 522 { 523 DWORD i, bytesNeeded = 0, structSize = 0; 524 525 for (i = 0; i < cItem; i++) 526 { 527 if (items[i].size > items[i].minSize) 528 bytesNeeded += items[i].size - items[i].minSize; 529 structSize = max( structSize, items[i].offset + items[i].minSize ); 530 } 531 bytesNeeded += structSize; 532 if (pcbDecoded) 533 *pcbDecoded = 1 + lenBytes + cbDecoded; 534 if (!pvStructInfo) 535 *pcbStructInfo = bytesNeeded; 536 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, 537 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) 538 { 539 BYTE *nextData; 540 541 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 542 pvStructInfo = *(BYTE **)pvStructInfo; 543 if (startingPointer) 544 nextData = startingPointer; 545 else 546 nextData = (BYTE *)pvStructInfo + structSize; 547 memset(pvStructInfo, 0, structSize); 548 ret = CRYPT_AsnDecodeSequenceItems(items, cItem, 549 ptr, dataLen, dwFlags, pvStructInfo, nextData, 550 &cbDecoded); 551 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 552 CRYPT_FreeSpace(pDecodePara, pvStructInfo); 553 } 554 } 555 } 556 } 557 else 558 { 559 SetLastError(CRYPT_E_ASN1_BADTAG); 560 ret = FALSE; 561 } 562 TRACE("returning %d (%08x)\n", ret, GetLastError()); 563 return ret; 564 } 565 566 /* tag: 567 * The expected tag of the entire encoded array (usually a variant 568 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called 569 * regardless of the tag seen. 570 * countOffset: 571 * The offset within the outer structure at which the count exists. 572 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0, 573 * while CRYPT_ATTRIBUTE has countOffset == 574 * offsetof(CRYPT_ATTRIBUTE, cValue). 575 * arrayOffset: 576 * The offset within the outer structure at which the array pointer exists. 577 * For example, CRYPT_ATTRIBUTES has arrayOffset == 578 * offsetof(CRYPT_ATTRIBUTES, rgAttr). 579 * minArraySize: 580 * The minimum size of the decoded array. On WIN32, this is always 8: 581 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to 582 * alignment. 583 * decodeFunc: 584 * used to decode each item in the array 585 * itemSize: 586 * is the minimum size of each decoded item 587 * hasPointer: 588 * indicates whether each item has a dynamic pointer 589 * pointerOffset: 590 * indicates the offset within itemSize at which the pointer exists 591 */ 592 struct AsnArrayDescriptor 593 { 594 BYTE tag; 595 DWORD countOffset; 596 DWORD arrayOffset; 597 DWORD minArraySize; 598 InternalDecodeFunc decodeFunc; 599 DWORD itemSize; 600 BOOL hasPointer; 601 DWORD pointerOffset; 602 }; 603 604 struct AsnArrayItemSize 605 { 606 DWORD encodedLen; 607 DWORD size; 608 }; 609 610 /* Decodes an array of like types into a structure described by a struct 611 * AsnArrayDescriptor. 612 */ 613 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, 614 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 615 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, 616 DWORD *pcbDecoded) 617 { 618 BOOL ret = TRUE; 619 620 TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded, 621 cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 622 623 if (!cbEncoded) 624 { 625 SetLastError(CRYPT_E_ASN1_EOD); 626 ret = FALSE; 627 } 628 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag) 629 { 630 DWORD dataLen; 631 632 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) 633 { 634 DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded; 635 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 636 /* There can be arbitrarily many items, but there is often only one. 637 */ 638 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize; 639 640 decoded = 1 + lenBytes; 641 if (dataLen) 642 { 643 const BYTE *ptr; 644 BOOL doneDecoding = FALSE; 645 646 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; ) 647 { 648 if (dataLen == CMSG_INDEFINITE_LENGTH) 649 { 650 if (ptr[0] == 0) 651 { 652 doneDecoding = TRUE; 653 if (ptr[1] != 0) 654 { 655 SetLastError(CRYPT_E_ASN1_CORRUPT); 656 ret = FALSE; 657 } 658 else 659 decoded += 2; 660 } 661 } 662 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen) 663 doneDecoding = TRUE; 664 if (!doneDecoding) 665 { 666 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0; 667 668 /* Each item decoded may not tolerate extraneous bytes, 669 * so get the length of the next element if known. 670 */ 671 if ((ret = CRYPT_GetLengthIndefinite(ptr, 672 cbEncoded - (ptr - pbEncoded), &itemDataLen))) 673 { 674 if (itemDataLen == CMSG_INDEFINITE_LENGTH) 675 itemEncoded = cbEncoded - (ptr - pbEncoded); 676 else 677 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) + 678 itemDataLen; 679 } 680 if (ret) 681 ret = arrayDesc->decodeFunc(ptr, itemEncoded, 682 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size, 683 &itemDecoded); 684 if (ret) 685 { 686 cItems++; 687 if (itemSizes != &itemSize) 688 itemSizes = CryptMemRealloc(itemSizes, 689 cItems * sizeof(struct AsnArrayItemSize)); 690 else if (cItems > 1) 691 { 692 itemSizes = 693 CryptMemAlloc( 694 cItems * sizeof(struct AsnArrayItemSize)); 695 if (itemSizes) 696 *itemSizes = itemSize; 697 } 698 if (itemSizes) 699 { 700 decoded += itemDecoded; 701 itemSizes[cItems - 1].encodedLen = itemEncoded; 702 itemSizes[cItems - 1].size = size; 703 bytesNeeded += size; 704 ptr += itemEncoded; 705 } 706 else 707 ret = FALSE; 708 } 709 } 710 } 711 } 712 if (ret) 713 { 714 if (pcbDecoded) 715 *pcbDecoded = decoded; 716 if (!pvStructInfo) 717 *pcbStructInfo = bytesNeeded; 718 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 719 pvStructInfo, pcbStructInfo, bytesNeeded))) 720 { 721 DWORD i, *pcItems; 722 BYTE *nextData; 723 const BYTE *ptr; 724 void *rgItems; 725 726 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 727 pvStructInfo = *(void **)pvStructInfo; 728 pcItems = pvStructInfo; 729 *pcItems = cItems; 730 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 731 { 732 rgItems = (BYTE *)pvStructInfo + 733 arrayDesc->minArraySize; 734 *(void **)((BYTE *)pcItems - 735 arrayDesc->countOffset + arrayDesc->arrayOffset) = 736 rgItems; 737 } 738 else 739 rgItems = *(void **)((BYTE *)pcItems - 740 arrayDesc->countOffset + arrayDesc->arrayOffset); 741 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize; 742 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret && 743 i < cItems && ptr - pbEncoded - 1 - lenBytes < 744 dataLen; i++) 745 { 746 DWORD itemDecoded; 747 748 if (arrayDesc->hasPointer) 749 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize 750 + arrayDesc->pointerOffset) = nextData; 751 ret = arrayDesc->decodeFunc(ptr, 752 itemSizes[i].encodedLen, 753 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, 754 (BYTE *)rgItems + i * arrayDesc->itemSize, 755 &itemSizes[i].size, &itemDecoded); 756 if (ret) 757 { 758 nextData += itemSizes[i].size - arrayDesc->itemSize; 759 ptr += itemDecoded; 760 } 761 } 762 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 763 CRYPT_FreeSpace(pDecodePara, pvStructInfo); 764 } 765 } 766 if (itemSizes != &itemSize) 767 CryptMemFree(itemSizes); 768 } 769 } 770 else 771 { 772 SetLastError(CRYPT_E_ASN1_BADTAG); 773 ret = FALSE; 774 } 775 return ret; 776 } 777 778 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by 779 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set 780 * to CRYPT_E_ASN1_CORRUPT. 781 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData 782 * set! 783 */ 784 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded, 785 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 786 { 787 BOOL ret; 788 DWORD dataLen; 789 790 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 791 { 792 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 793 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB); 794 795 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 796 bytesNeeded += 1 + lenBytes + dataLen; 797 798 if (pcbDecoded) 799 *pcbDecoded = 1 + lenBytes + dataLen; 800 if (!pvStructInfo) 801 *pcbStructInfo = bytesNeeded; 802 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded))) 803 { 804 CRYPT_DER_BLOB *blob; 805 806 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 807 pvStructInfo = *(BYTE **)pvStructInfo; 808 blob = pvStructInfo; 809 blob->cbData = 1 + lenBytes + dataLen; 810 if (blob->cbData) 811 { 812 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 813 blob->pbData = (BYTE *)pbEncoded; 814 else 815 { 816 assert(blob->pbData); 817 memcpy(blob->pbData, pbEncoded, blob->cbData); 818 } 819 } 820 else 821 { 822 SetLastError(CRYPT_E_ASN1_CORRUPT); 823 ret = FALSE; 824 } 825 } 826 } 827 return ret; 828 } 829 830 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */ 831 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded, 832 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 833 DWORD *pcbDecoded) 834 { 835 BOOL ret; 836 837 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags, 838 pvStructInfo, *pcbStructInfo, pcbDecoded); 839 840 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in- 841 * place. 842 */ 843 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded, 844 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo, 845 pcbDecoded); 846 if (ret && pvStructInfo) 847 { 848 CRYPT_BIT_BLOB *blob = pvStructInfo; 849 850 if (blob->cbData) 851 { 852 DWORD i; 853 BYTE temp; 854 855 for (i = 0; i < blob->cbData / 2; i++) 856 { 857 temp = blob->pbData[i]; 858 blob->pbData[i] = blob->pbData[blob->cbData - i - 1]; 859 blob->pbData[blob->cbData - i - 1] = temp; 860 } 861 } 862 } 863 TRACE("returning %d (%08x)\n", ret, GetLastError()); 864 return ret; 865 } 866 867 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType, 868 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 869 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 870 { 871 BOOL ret = TRUE; 872 873 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 874 pDecodePara, pvStructInfo, *pcbStructInfo); 875 876 __TRY 877 { 878 struct AsnDecodeSequenceItem items[] = { 879 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned), 880 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE, 881 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 }, 882 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO, 883 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId, 884 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, 885 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 }, 886 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature), 887 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 888 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 }, 889 }; 890 891 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG) 892 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal; 893 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 894 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 895 pcbStructInfo, NULL, NULL); 896 } 897 __EXCEPT_PAGE_FAULT 898 { 899 SetLastError(STATUS_ACCESS_VIOLATION); 900 ret = FALSE; 901 } 902 __ENDTRY 903 904 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 905 return ret; 906 } 907 908 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded, 909 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 910 { 911 BOOL ret; 912 DWORD dataLen; 913 914 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 915 { 916 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 917 918 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen, 919 dwFlags, pvStructInfo, pcbStructInfo, NULL); 920 if (pcbDecoded) 921 *pcbDecoded = 1 + lenBytes + dataLen; 922 } 923 return ret; 924 } 925 926 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded, 927 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 928 { 929 BOOL ret; 930 931 struct AsnDecodeSequenceItem items[] = { 932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore), 933 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 }, 934 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter), 935 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 }, 936 }; 937 938 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 939 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 940 pcbDecoded, NULL); 941 return ret; 942 } 943 944 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded, 945 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 946 DWORD *pcbDecoded) 947 { 948 BOOL ret = TRUE; 949 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 950 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension), 951 FINALMEMBERSIZE(CERT_INFO, cExtension), 952 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 953 offsetof(CERT_EXTENSION, pszObjId) }; 954 955 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 956 pvStructInfo, *pcbStructInfo, pcbDecoded); 957 958 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 959 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 960 return ret; 961 } 962 963 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded, 964 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 965 DWORD *pcbDecoded) 966 { 967 BOOL ret; 968 DWORD dataLen; 969 970 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 971 { 972 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 973 974 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes, 975 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); 976 if (ret && pcbDecoded) 977 *pcbDecoded = 1 + lenBytes + dataLen; 978 } 979 return ret; 980 } 981 982 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType, 983 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 984 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 985 { 986 BOOL ret = TRUE; 987 struct AsnDecodeSequenceItem items[] = { 988 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion), 989 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 }, 990 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber), 991 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, 992 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 }, 993 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm), 994 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 995 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 }, 996 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob, 997 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO, 998 Issuer.pbData) }, 999 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore), 1000 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE, 1001 FALSE, 0 }, 1002 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob, 1003 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO, 1004 Subject.pbData) }, 1005 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo), 1006 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO), 1007 FALSE, TRUE, offsetof(CERT_INFO, 1008 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 }, 1009 { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId), 1010 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, 1011 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 }, 1012 { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId), 1013 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, 1014 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 }, 1015 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension), 1016 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension), 1017 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 }, 1018 }; 1019 1020 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1021 pDecodePara, pvStructInfo, *pcbStructInfo); 1022 1023 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 1024 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, 1025 NULL, NULL); 1026 if (ret && pvStructInfo) 1027 { 1028 CERT_INFO *info; 1029 1030 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 1031 info = *(CERT_INFO **)pvStructInfo; 1032 else 1033 info = pvStructInfo; 1034 if (!info->SerialNumber.cbData || !info->Issuer.cbData || 1035 !info->Subject.cbData) 1036 { 1037 SetLastError(CRYPT_E_ASN1_CORRUPT); 1038 /* Don't need to deallocate, because it should have failed on the 1039 * first pass (and no memory was allocated.) 1040 */ 1041 ret = FALSE; 1042 } 1043 } 1044 1045 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 1046 return ret; 1047 } 1048 1049 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType, 1050 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 1051 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 1052 { 1053 BOOL ret = FALSE; 1054 1055 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1056 pDecodePara, pvStructInfo, *pcbStructInfo); 1057 1058 __TRY 1059 { 1060 DWORD size = 0; 1061 1062 /* Unless told not to, first try to decode it as a signed cert. */ 1063 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG)) 1064 { 1065 PCERT_SIGNED_CONTENT_INFO signedCert = NULL; 1066 1067 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType, 1068 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, 1069 &signedCert, &size); 1070 if (ret) 1071 { 1072 size = 0; 1073 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType, 1074 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData, 1075 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara, 1076 pvStructInfo, pcbStructInfo); 1077 LocalFree(signedCert); 1078 } 1079 } 1080 /* Failing that, try it as an unsigned cert */ 1081 if (!ret) 1082 { 1083 size = 0; 1084 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType, 1085 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags, 1086 pDecodePara, pvStructInfo, pcbStructInfo); 1087 } 1088 } 1089 __EXCEPT_PAGE_FAULT 1090 { 1091 SetLastError(STATUS_ACCESS_VIOLATION); 1092 } 1093 __ENDTRY 1094 1095 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 1096 return ret; 1097 } 1098 1099 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded, 1100 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 1101 DWORD *pcbDecoded) 1102 { 1103 BOOL ret = TRUE; 1104 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 1105 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension), 1106 FINALMEMBERSIZE(CRL_ENTRY, cExtension), 1107 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 1108 offsetof(CERT_EXTENSION, pszObjId) }; 1109 1110 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 1111 pvStructInfo, *pcbStructInfo, pcbDecoded); 1112 1113 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 1114 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 1115 return ret; 1116 } 1117 1118 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded, 1119 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1120 { 1121 BOOL ret; 1122 struct AsnDecodeSequenceItem items[] = { 1123 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber), 1124 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE, 1125 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 }, 1126 { 0, offsetof(CRL_ENTRY, RevocationDate), 1127 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 }, 1128 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension), 1129 CRYPT_AsnDecodeCRLEntryExtensions, 1130 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE, 1131 offsetof(CRL_ENTRY, rgExtension), 0 }, 1132 }; 1133 PCRL_ENTRY entry = pvStructInfo; 1134 1135 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, 1136 *pcbStructInfo); 1137 1138 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 1139 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded, 1140 entry ? entry->SerialNumber.pbData : NULL); 1141 if (ret && entry && !entry->SerialNumber.cbData) 1142 { 1143 WARN("empty CRL entry serial number\n"); 1144 SetLastError(CRYPT_E_ASN1_CORRUPT); 1145 ret = FALSE; 1146 } 1147 return ret; 1148 } 1149 1150 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO 1151 * whose rgCRLEntry member has been set prior to calling. 1152 */ 1153 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded, 1154 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1155 { 1156 BOOL ret; 1157 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 1158 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry), 1159 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension), 1160 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE, 1161 offsetof(CRL_ENTRY, SerialNumber.pbData) }; 1162 1163 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 1164 pvStructInfo, *pcbStructInfo, pcbDecoded); 1165 1166 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 1167 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 1168 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 1169 return ret; 1170 } 1171 1172 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded, 1173 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 1174 DWORD *pcbDecoded) 1175 { 1176 BOOL ret = TRUE; 1177 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 1178 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension), 1179 FINALMEMBERSIZE(CRL_INFO, cExtension), 1180 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 1181 offsetof(CERT_EXTENSION, pszObjId) }; 1182 1183 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 1184 pvStructInfo, *pcbStructInfo, pcbDecoded); 1185 1186 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 1187 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 1188 return ret; 1189 } 1190 1191 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded, 1192 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 1193 DWORD *pcbDecoded) 1194 { 1195 BOOL ret; 1196 DWORD dataLen; 1197 1198 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 1199 { 1200 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 1201 1202 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes, 1203 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); 1204 if (ret && pcbDecoded) 1205 *pcbDecoded = 1 + lenBytes + dataLen; 1206 } 1207 return ret; 1208 } 1209 1210 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType, 1211 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 1212 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 1213 { 1214 struct AsnDecodeSequenceItem items[] = { 1215 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion), 1216 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, 1217 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm), 1218 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 1219 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 }, 1220 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob, 1221 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO, 1222 Issuer.pbData) }, 1223 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal, 1224 sizeof(FILETIME), FALSE, FALSE, 0 }, 1225 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal, 1226 sizeof(FILETIME), TRUE, FALSE, 0 }, 1227 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry), 1228 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension), 1229 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 }, 1230 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension), 1231 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension), 1232 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 }, 1233 }; 1234 BOOL ret = TRUE; 1235 1236 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1237 pDecodePara, pvStructInfo, *pcbStructInfo); 1238 1239 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags, 1240 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); 1241 1242 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 1243 return ret; 1244 } 1245 1246 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType, 1247 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 1248 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 1249 { 1250 BOOL ret = FALSE; 1251 1252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1253 pDecodePara, pvStructInfo, *pcbStructInfo); 1254 1255 __TRY 1256 { 1257 DWORD size = 0; 1258 1259 /* Unless told not to, first try to decode it as a signed crl. */ 1260 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG)) 1261 { 1262 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL; 1263 1264 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType, 1265 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, 1266 &signedCrl, &size); 1267 if (ret) 1268 { 1269 size = 0; 1270 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType, 1271 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData, 1272 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara, 1273 pvStructInfo, pcbStructInfo); 1274 LocalFree(signedCrl); 1275 } 1276 } 1277 /* Failing that, try it as an unsigned crl */ 1278 if (!ret) 1279 { 1280 size = 0; 1281 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType, 1282 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded, 1283 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); 1284 } 1285 } 1286 __EXCEPT_PAGE_FAULT 1287 { 1288 SetLastError(STATUS_ACCESS_VIOLATION); 1289 } 1290 __ENDTRY 1291 1292 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 1293 return ret; 1294 } 1295 1296 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded, 1297 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1298 { 1299 BOOL ret = TRUE; 1300 DWORD dataLen; 1301 1302 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1303 pvStructInfo, *pcbStructInfo); 1304 1305 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 1306 { 1307 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 1308 DWORD bytesNeeded = sizeof(LPSTR); 1309 1310 if (dataLen) 1311 { 1312 const BYTE *ptr; 1313 char str[32]; 1314 1315 snprintf(str, sizeof(str), "%d.%d", 1316 pbEncoded[1 + lenBytes] / 40, 1317 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40) 1318 * 40); 1319 bytesNeeded += strlen(str) + 1; 1320 for (ptr = pbEncoded + 2 + lenBytes; ret && 1321 ptr - pbEncoded - 1 - lenBytes < dataLen; ) 1322 { 1323 int val = 0; 1324 1325 while (ptr - pbEncoded - 1 - lenBytes < dataLen && 1326 (*ptr & 0x80)) 1327 { 1328 val <<= 7; 1329 val |= *ptr & 0x7f; 1330 ptr++; 1331 } 1332 if (ptr - pbEncoded - 1 - lenBytes >= dataLen || 1333 (*ptr & 0x80)) 1334 { 1335 SetLastError(CRYPT_E_ASN1_CORRUPT); 1336 ret = FALSE; 1337 } 1338 else 1339 { 1340 val <<= 7; 1341 val |= *ptr++; 1342 snprintf(str, sizeof(str), ".%d", val); 1343 bytesNeeded += strlen(str); 1344 } 1345 } 1346 } 1347 if (pcbDecoded) 1348 *pcbDecoded = 1 + lenBytes + dataLen; 1349 if (!pvStructInfo) 1350 *pcbStructInfo = bytesNeeded; 1351 else if (*pcbStructInfo < bytesNeeded) 1352 { 1353 *pcbStructInfo = bytesNeeded; 1354 SetLastError(ERROR_MORE_DATA); 1355 ret = FALSE; 1356 } 1357 else 1358 { 1359 if (dataLen) 1360 { 1361 const BYTE *ptr; 1362 LPSTR pszObjId = *(LPSTR *)pvStructInfo; 1363 1364 *pszObjId = 0; 1365 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40, 1366 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 1367 40) * 40); 1368 pszObjId += strlen(pszObjId); 1369 for (ptr = pbEncoded + 2 + lenBytes; ret && 1370 ptr - pbEncoded - 1 - lenBytes < dataLen; ) 1371 { 1372 int val = 0; 1373 1374 while (ptr - pbEncoded - 1 - lenBytes < dataLen && 1375 (*ptr & 0x80)) 1376 { 1377 val <<= 7; 1378 val |= *ptr & 0x7f; 1379 ptr++; 1380 } 1381 val <<= 7; 1382 val |= *ptr++; 1383 sprintf(pszObjId, ".%d", val); 1384 pszObjId += strlen(pszObjId); 1385 } 1386 } 1387 else 1388 *(LPSTR *)pvStructInfo = NULL; 1389 *pcbStructInfo = bytesNeeded; 1390 } 1391 } 1392 return ret; 1393 } 1394 1395 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded, 1396 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1397 { 1398 BOOL ret; 1399 1400 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1401 pvStructInfo, *pcbStructInfo); 1402 1403 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER) 1404 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags, 1405 pvStructInfo, pcbStructInfo, pcbDecoded); 1406 else 1407 { 1408 SetLastError(CRYPT_E_ASN1_BADTAG); 1409 ret = FALSE; 1410 } 1411 return ret; 1412 } 1413 1414 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, 1415 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1416 { 1417 struct AsnDecodeSequenceItem items[] = { 1418 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId), 1419 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 1420 offsetof(CERT_EXTENSION, pszObjId), 0 }, 1421 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool, 1422 sizeof(BOOL), TRUE, FALSE, 0, 0 }, 1423 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value), 1424 CRYPT_AsnDecodeOctets, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE, 1425 offsetof(CERT_EXTENSION, Value.pbData) }, 1426 }; 1427 BOOL ret = TRUE; 1428 PCERT_EXTENSION ext = pvStructInfo; 1429 1430 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext, 1431 *pcbStructInfo); 1432 1433 if (ext) 1434 TRACE("ext->pszObjId is %p\n", ext->pszObjId); 1435 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 1436 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo, 1437 pcbDecoded, ext ? ext->pszObjId : NULL); 1438 if (ext) 1439 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId, 1440 debugstr_a(ext->pszObjId)); 1441 TRACE("returning %d (%08x)\n", ret, GetLastError()); 1442 return ret; 1443 } 1444 1445 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType, 1446 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 1447 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 1448 { 1449 BOOL ret = TRUE; 1450 1451 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1452 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 1453 1454 __TRY 1455 { 1456 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 1457 offsetof(CERT_EXTENSIONS, cExtension), 1458 offsetof(CERT_EXTENSIONS, rgExtension), 1459 sizeof(CERT_EXTENSIONS), 1460 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 1461 offsetof(CERT_EXTENSION, pszObjId) }; 1462 CERT_EXTENSIONS *exts = pvStructInfo; 1463 1464 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 1465 exts->rgExtension = (CERT_EXTENSION *)(exts + 1); 1466 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 1467 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 1468 } 1469 __EXCEPT_PAGE_FAULT 1470 { 1471 SetLastError(STATUS_ACCESS_VIOLATION); 1472 ret = FALSE; 1473 } 1474 __ENDTRY 1475 return ret; 1476 } 1477 1478 /* Warning: this assumes the address of value->Value.pbData is already set, in 1479 * order to avoid overwriting memory. (In some cases, it may change it, if it 1480 * doesn't copy anything to memory.) Be sure to set it correctly! 1481 */ 1482 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded, 1483 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 1484 DWORD *pcbDecoded) 1485 { 1486 BOOL ret = TRUE; 1487 DWORD dataLen; 1488 CERT_NAME_VALUE *value = pvStructInfo; 1489 1490 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 1491 { 1492 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 1493 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType; 1494 1495 switch (pbEncoded[0]) 1496 { 1497 case ASN_OCTETSTRING: 1498 valueType = CERT_RDN_OCTET_STRING; 1499 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1500 bytesNeeded += dataLen; 1501 break; 1502 case ASN_NUMERICSTRING: 1503 valueType = CERT_RDN_NUMERIC_STRING; 1504 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1505 bytesNeeded += dataLen; 1506 break; 1507 case ASN_PRINTABLESTRING: 1508 valueType = CERT_RDN_PRINTABLE_STRING; 1509 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1510 bytesNeeded += dataLen; 1511 break; 1512 case ASN_IA5STRING: 1513 valueType = CERT_RDN_IA5_STRING; 1514 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1515 bytesNeeded += dataLen; 1516 break; 1517 case ASN_T61STRING: 1518 valueType = CERT_RDN_T61_STRING; 1519 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1520 bytesNeeded += dataLen; 1521 break; 1522 case ASN_VIDEOTEXSTRING: 1523 valueType = CERT_RDN_VIDEOTEX_STRING; 1524 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1525 bytesNeeded += dataLen; 1526 break; 1527 case ASN_GRAPHICSTRING: 1528 valueType = CERT_RDN_GRAPHIC_STRING; 1529 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1530 bytesNeeded += dataLen; 1531 break; 1532 case ASN_VISIBLESTRING: 1533 valueType = CERT_RDN_VISIBLE_STRING; 1534 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1535 bytesNeeded += dataLen; 1536 break; 1537 case ASN_GENERALSTRING: 1538 valueType = CERT_RDN_GENERAL_STRING; 1539 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1540 bytesNeeded += dataLen; 1541 break; 1542 case ASN_UNIVERSALSTRING: 1543 FIXME("ASN_UNIVERSALSTRING: unimplemented\n"); 1544 SetLastError(CRYPT_E_ASN1_BADTAG); 1545 return FALSE; 1546 case ASN_BMPSTRING: 1547 valueType = CERT_RDN_BMP_STRING; 1548 bytesNeeded += dataLen; 1549 break; 1550 case ASN_UTF8STRING: 1551 valueType = CERT_RDN_UTF8_STRING; 1552 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0, 1553 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * sizeof(WCHAR); 1554 break; 1555 default: 1556 SetLastError(CRYPT_E_ASN1_BADTAG); 1557 return FALSE; 1558 } 1559 1560 if (pcbDecoded) 1561 *pcbDecoded = 1 + lenBytes + dataLen; 1562 if (!value) 1563 *pcbStructInfo = bytesNeeded; 1564 else if (*pcbStructInfo < bytesNeeded) 1565 { 1566 *pcbStructInfo = bytesNeeded; 1567 SetLastError(ERROR_MORE_DATA); 1568 ret = FALSE; 1569 } 1570 else 1571 { 1572 *pcbStructInfo = bytesNeeded; 1573 value->dwValueType = valueType; 1574 if (dataLen) 1575 { 1576 DWORD i; 1577 1578 assert(value->Value.pbData); 1579 switch (pbEncoded[0]) 1580 { 1581 case ASN_OCTETSTRING: 1582 case ASN_NUMERICSTRING: 1583 case ASN_PRINTABLESTRING: 1584 case ASN_IA5STRING: 1585 case ASN_T61STRING: 1586 case ASN_VIDEOTEXSTRING: 1587 case ASN_GRAPHICSTRING: 1588 case ASN_VISIBLESTRING: 1589 case ASN_GENERALSTRING: 1590 value->Value.cbData = dataLen; 1591 if (dataLen) 1592 { 1593 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 1594 memcpy(value->Value.pbData, 1595 pbEncoded + 1 + lenBytes, dataLen); 1596 else 1597 value->Value.pbData = (LPBYTE)pbEncoded + 1 + 1598 lenBytes; 1599 } 1600 break; 1601 case ASN_BMPSTRING: 1602 { 1603 LPWSTR str = (LPWSTR)value->Value.pbData; 1604 1605 value->Value.cbData = dataLen; 1606 for (i = 0; i < dataLen / 2; i++) 1607 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | 1608 pbEncoded[1 + lenBytes + 2 * i + 1]; 1609 break; 1610 } 1611 case ASN_UTF8STRING: 1612 { 1613 LPWSTR str = (LPWSTR)value->Value.pbData; 1614 1615 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, 1616 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 1617 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; 1618 break; 1619 } 1620 } 1621 } 1622 else 1623 { 1624 value->Value.cbData = 0; 1625 value->Value.pbData = NULL; 1626 } 1627 } 1628 } 1629 return ret; 1630 } 1631 1632 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType, 1633 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 1634 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 1635 { 1636 BOOL ret = TRUE; 1637 1638 __TRY 1639 { 1640 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded, 1641 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); 1642 if (ret && pvStructInfo) 1643 { 1644 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, 1645 pcbStructInfo, *pcbStructInfo); 1646 if (ret) 1647 { 1648 CERT_NAME_VALUE *value; 1649 1650 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 1651 pvStructInfo = *(BYTE **)pvStructInfo; 1652 value = pvStructInfo; 1653 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE)); 1654 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded, 1655 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 1656 pcbStructInfo, NULL); 1657 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 1658 CRYPT_FreeSpace(pDecodePara, value); 1659 } 1660 } 1661 } 1662 __EXCEPT_PAGE_FAULT 1663 { 1664 SetLastError(STATUS_ACCESS_VIOLATION); 1665 ret = FALSE; 1666 } 1667 __ENDTRY 1668 return ret; 1669 } 1670 1671 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded, 1672 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 1673 DWORD *pcbDecoded) 1674 { 1675 BOOL ret = TRUE; 1676 DWORD dataLen; 1677 CERT_NAME_VALUE *value = pvStructInfo; 1678 1679 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 1680 { 1681 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 1682 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType; 1683 1684 switch (pbEncoded[0]) 1685 { 1686 case ASN_NUMERICSTRING: 1687 valueType = CERT_RDN_NUMERIC_STRING; 1688 if (dataLen) 1689 bytesNeeded += (dataLen + 1) * 2; 1690 break; 1691 case ASN_PRINTABLESTRING: 1692 valueType = CERT_RDN_PRINTABLE_STRING; 1693 if (dataLen) 1694 bytesNeeded += (dataLen + 1) * 2; 1695 break; 1696 case ASN_IA5STRING: 1697 valueType = CERT_RDN_IA5_STRING; 1698 if (dataLen) 1699 bytesNeeded += (dataLen + 1) * 2; 1700 break; 1701 case ASN_T61STRING: 1702 valueType = CERT_RDN_T61_STRING; 1703 if (dataLen) 1704 bytesNeeded += (dataLen + 1) * 2; 1705 break; 1706 case ASN_VIDEOTEXSTRING: 1707 valueType = CERT_RDN_VIDEOTEX_STRING; 1708 if (dataLen) 1709 bytesNeeded += (dataLen + 1) * 2; 1710 break; 1711 case ASN_GRAPHICSTRING: 1712 valueType = CERT_RDN_GRAPHIC_STRING; 1713 if (dataLen) 1714 bytesNeeded += (dataLen + 1) * 2; 1715 break; 1716 case ASN_VISIBLESTRING: 1717 valueType = CERT_RDN_VISIBLE_STRING; 1718 if (dataLen) 1719 bytesNeeded += (dataLen + 1) * 2; 1720 break; 1721 case ASN_GENERALSTRING: 1722 valueType = CERT_RDN_GENERAL_STRING; 1723 if (dataLen) 1724 bytesNeeded += (dataLen + 1) * 2; 1725 break; 1726 case ASN_UNIVERSALSTRING: 1727 valueType = CERT_RDN_UNIVERSAL_STRING; 1728 if (dataLen) 1729 bytesNeeded += dataLen / 2 + sizeof(WCHAR); 1730 break; 1731 case ASN_BMPSTRING: 1732 valueType = CERT_RDN_BMP_STRING; 1733 if (dataLen) 1734 bytesNeeded += dataLen + sizeof(WCHAR); 1735 break; 1736 case ASN_UTF8STRING: 1737 valueType = CERT_RDN_UTF8_STRING; 1738 if (dataLen) 1739 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0, 1740 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2; 1741 break; 1742 default: 1743 SetLastError(CRYPT_E_ASN1_BADTAG); 1744 return FALSE; 1745 } 1746 1747 if (pcbDecoded) 1748 *pcbDecoded = 1 + lenBytes + dataLen; 1749 if (!value) 1750 *pcbStructInfo = bytesNeeded; 1751 else if (*pcbStructInfo < bytesNeeded) 1752 { 1753 *pcbStructInfo = bytesNeeded; 1754 SetLastError(ERROR_MORE_DATA); 1755 ret = FALSE; 1756 } 1757 else 1758 { 1759 *pcbStructInfo = bytesNeeded; 1760 value->dwValueType = valueType; 1761 if (dataLen) 1762 { 1763 DWORD i; 1764 LPWSTR str = (LPWSTR)value->Value.pbData; 1765 1766 assert(value->Value.pbData); 1767 switch (pbEncoded[0]) 1768 { 1769 case ASN_NUMERICSTRING: 1770 case ASN_PRINTABLESTRING: 1771 case ASN_IA5STRING: 1772 case ASN_T61STRING: 1773 case ASN_VIDEOTEXSTRING: 1774 case ASN_GRAPHICSTRING: 1775 case ASN_VISIBLESTRING: 1776 case ASN_GENERALSTRING: 1777 value->Value.cbData = dataLen * 2; 1778 for (i = 0; i < dataLen; i++) 1779 str[i] = pbEncoded[1 + lenBytes + i]; 1780 str[i] = 0; 1781 break; 1782 case ASN_UNIVERSALSTRING: 1783 value->Value.cbData = dataLen / 2; 1784 for (i = 0; i < dataLen / 4; i++) 1785 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8) 1786 | pbEncoded[1 + lenBytes + 2 * i + 3]; 1787 str[i] = 0; 1788 break; 1789 case ASN_BMPSTRING: 1790 value->Value.cbData = dataLen; 1791 for (i = 0; i < dataLen / 2; i++) 1792 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | 1793 pbEncoded[1 + lenBytes + 2 * i + 1]; 1794 str[i] = 0; 1795 break; 1796 case ASN_UTF8STRING: 1797 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, 1798 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 1799 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR); 1800 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0; 1801 value->Value.cbData += sizeof(WCHAR); 1802 break; 1803 } 1804 } 1805 else 1806 { 1807 value->Value.cbData = 0; 1808 value->Value.pbData = NULL; 1809 } 1810 } 1811 } 1812 return ret; 1813 } 1814 1815 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType, 1816 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 1817 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 1818 { 1819 BOOL ret = TRUE; 1820 1821 __TRY 1822 { 1823 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded, 1824 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); 1825 if (ret && pvStructInfo) 1826 { 1827 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, 1828 pcbStructInfo, *pcbStructInfo); 1829 if (ret) 1830 { 1831 CERT_NAME_VALUE *value; 1832 1833 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 1834 pvStructInfo = *(BYTE **)pvStructInfo; 1835 value = pvStructInfo; 1836 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE)); 1837 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, 1838 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 1839 pcbStructInfo, NULL); 1840 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 1841 CRYPT_FreeSpace(pDecodePara, value); 1842 } 1843 } 1844 } 1845 __EXCEPT_PAGE_FAULT 1846 { 1847 SetLastError(STATUS_ACCESS_VIOLATION); 1848 ret = FALSE; 1849 } 1850 __ENDTRY 1851 return ret; 1852 } 1853 1854 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded, 1855 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1856 { 1857 BOOL ret; 1858 struct AsnDecodeSequenceItem items[] = { 1859 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId), 1860 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 1861 offsetof(CERT_RDN_ATTR, pszObjId), 0 }, 1862 { 0, offsetof(CERT_RDN_ATTR, dwValueType), 1863 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE), 1864 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 }, 1865 }; 1866 CERT_RDN_ATTR *attr = pvStructInfo; 1867 1868 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1869 pvStructInfo, *pcbStructInfo); 1870 1871 if (attr) 1872 TRACE("attr->pszObjId is %p\n", attr->pszObjId); 1873 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 1874 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded, 1875 attr ? attr->pszObjId : NULL); 1876 if (attr) 1877 { 1878 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, 1879 debugstr_a(attr->pszObjId)); 1880 TRACE("attr->dwValueType is %d\n", attr->dwValueType); 1881 } 1882 TRACE("returning %d (%08x)\n", ret, GetLastError()); 1883 return ret; 1884 } 1885 1886 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded, 1887 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1888 { 1889 BOOL ret = TRUE; 1890 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 1891 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr), 1892 sizeof(CERT_RDN), 1893 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE, 1894 offsetof(CERT_RDN_ATTR, pszObjId) }; 1895 1896 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 1897 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 1898 return ret; 1899 } 1900 1901 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType, 1902 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 1903 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 1904 { 1905 BOOL ret = TRUE; 1906 1907 __TRY 1908 { 1909 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 1910 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN), 1911 sizeof(CERT_NAME_INFO), 1912 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE, 1913 offsetof(CERT_RDN, rgRDNAttr) }; 1914 DWORD bytesNeeded = 0; 1915 1916 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 1917 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded, 1918 NULL); 1919 if (ret) 1920 { 1921 if (!pvStructInfo) 1922 *pcbStructInfo = bytesNeeded; 1923 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 1924 pvStructInfo, pcbStructInfo, bytesNeeded))) 1925 { 1926 CERT_NAME_INFO *info; 1927 1928 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 1929 pvStructInfo = *(BYTE **)pvStructInfo; 1930 info = pvStructInfo; 1931 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo + 1932 sizeof(CERT_NAME_INFO)); 1933 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 1934 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo, 1935 &bytesNeeded, NULL); 1936 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 1937 CRYPT_FreeSpace(pDecodePara, info); 1938 } 1939 } 1940 } 1941 __EXCEPT_PAGE_FAULT 1942 { 1943 SetLastError(STATUS_ACCESS_VIOLATION); 1944 ret = FALSE; 1945 } 1946 __ENDTRY 1947 return ret; 1948 } 1949 1950 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded, 1951 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 1952 DWORD *pcbDecoded) 1953 { 1954 BOOL ret; 1955 struct AsnDecodeSequenceItem items[] = { 1956 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId), 1957 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 1958 offsetof(CERT_RDN_ATTR, pszObjId), 0 }, 1959 { 0, offsetof(CERT_RDN_ATTR, dwValueType), 1960 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE), 1961 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 }, 1962 }; 1963 CERT_RDN_ATTR *attr = pvStructInfo; 1964 1965 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 1966 pvStructInfo, *pcbStructInfo); 1967 1968 if (attr) 1969 TRACE("attr->pszObjId is %p\n", attr->pszObjId); 1970 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 1971 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded, 1972 attr ? attr->pszObjId : NULL); 1973 if (attr) 1974 { 1975 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, 1976 debugstr_a(attr->pszObjId)); 1977 TRACE("attr->dwValueType is %d\n", attr->dwValueType); 1978 } 1979 TRACE("returning %d (%08x)\n", ret, GetLastError()); 1980 return ret; 1981 } 1982 1983 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded, 1984 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 1985 { 1986 BOOL ret = TRUE; 1987 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 1988 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr), 1989 sizeof(CERT_RDN), 1990 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE, 1991 offsetof(CERT_RDN_ATTR, pszObjId) }; 1992 1993 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 1994 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 1995 return ret; 1996 } 1997 1998 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType, 1999 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 2000 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 2001 { 2002 BOOL ret = TRUE; 2003 2004 __TRY 2005 { 2006 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 2007 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN), 2008 sizeof(CERT_NAME_INFO), 2009 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE, 2010 offsetof(CERT_RDN, rgRDNAttr) }; 2011 DWORD bytesNeeded = 0; 2012 2013 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2014 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded, 2015 NULL); 2016 if (ret) 2017 { 2018 if (!pvStructInfo) 2019 *pcbStructInfo = bytesNeeded; 2020 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 2021 pvStructInfo, pcbStructInfo, bytesNeeded))) 2022 { 2023 CERT_NAME_INFO *info; 2024 2025 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 2026 pvStructInfo = *(BYTE **)pvStructInfo; 2027 info = pvStructInfo; 2028 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo + 2029 sizeof(CERT_NAME_INFO)); 2030 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2031 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo, 2032 &bytesNeeded, NULL); 2033 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 2034 CRYPT_FreeSpace(pDecodePara, info); 2035 } 2036 } 2037 } 2038 __EXCEPT_PAGE_FAULT 2039 { 2040 SetLastError(STATUS_ACCESS_VIOLATION); 2041 ret = FALSE; 2042 } 2043 __ENDTRY 2044 return ret; 2045 } 2046 2047 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded, 2048 DWORD *pcbDecoded) 2049 { 2050 BOOL ret = TRUE, done = FALSE; 2051 DWORD indefiniteNestingLevels = 0, decoded = 0; 2052 2053 TRACE("(%p, %d)\n", pbEncoded, cbEncoded); 2054 2055 do { 2056 DWORD dataLen; 2057 2058 if (!cbEncoded) 2059 done = TRUE; 2060 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, 2061 &dataLen))) 2062 { 2063 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 2064 2065 if (dataLen == CMSG_INDEFINITE_LENGTH) 2066 { 2067 indefiniteNestingLevels++; 2068 pbEncoded += 1 + lenBytes; 2069 cbEncoded -= 1 + lenBytes; 2070 decoded += 1 + lenBytes; 2071 TRACE("indefiniteNestingLevels = %d\n", 2072 indefiniteNestingLevels); 2073 } 2074 else 2075 { 2076 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 && 2077 indefiniteNestingLevels) 2078 { 2079 indefiniteNestingLevels--; 2080 TRACE("indefiniteNestingLevels = %d\n", 2081 indefiniteNestingLevels); 2082 } 2083 pbEncoded += 1 + lenBytes + dataLen; 2084 cbEncoded -= 1 + lenBytes + dataLen; 2085 decoded += 1 + lenBytes + dataLen; 2086 if (!indefiniteNestingLevels) 2087 done = TRUE; 2088 } 2089 } 2090 } while (ret && !done); 2091 /* If we haven't found all 0 TLVs, we haven't found the end */ 2092 if (ret && indefiniteNestingLevels) 2093 { 2094 SetLastError(CRYPT_E_ASN1_EOD); 2095 ret = FALSE; 2096 } 2097 if (ret) 2098 *pcbDecoded = decoded; 2099 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0); 2100 return ret; 2101 } 2102 2103 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded, 2104 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2105 DWORD *pcbDecoded) 2106 { 2107 BOOL ret = TRUE; 2108 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0; 2109 2110 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2111 pvStructInfo, *pcbStructInfo); 2112 2113 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen))) 2114 { 2115 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 2116 bytesNeeded += encodedLen; 2117 if (!pvStructInfo) 2118 *pcbStructInfo = bytesNeeded; 2119 else if (*pcbStructInfo < bytesNeeded) 2120 { 2121 SetLastError(ERROR_MORE_DATA); 2122 *pcbStructInfo = bytesNeeded; 2123 ret = FALSE; 2124 } 2125 else 2126 { 2127 PCRYPT_OBJID_BLOB blob = pvStructInfo; 2128 2129 *pcbStructInfo = bytesNeeded; 2130 blob->cbData = encodedLen; 2131 if (encodedLen) 2132 { 2133 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 2134 blob->pbData = (LPBYTE)pbEncoded; 2135 else 2136 { 2137 assert(blob->pbData); 2138 memcpy(blob->pbData, pbEncoded, blob->cbData); 2139 } 2140 } 2141 else 2142 blob->pbData = NULL; 2143 } 2144 if (pcbDecoded) 2145 *pcbDecoded = encodedLen; 2146 } 2147 return ret; 2148 } 2149 2150 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded, 2151 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 2152 { 2153 BOOL ret; 2154 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 2155 offsetof(CTL_USAGE, cUsageIdentifier), 2156 offsetof(CTL_USAGE, rgpszUsageIdentifier), 2157 sizeof(CTL_USAGE), 2158 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 }; 2159 2160 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 2161 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 2162 return ret; 2163 } 2164 2165 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded, 2166 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2167 DWORD *pcbDecoded) 2168 { 2169 struct AsnArrayDescriptor arrayDesc = { 0, 2170 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute), 2171 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), 2172 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE, 2173 offsetof(CRYPT_ATTRIBUTE, pszObjId) }; 2174 BOOL ret; 2175 2176 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2177 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 2178 return ret; 2179 } 2180 2181 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded, 2182 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 2183 { 2184 struct AsnDecodeSequenceItem items[] = { 2185 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier), 2186 CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE, 2187 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 }, 2188 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute), 2189 CRYPT_AsnDecodeCTLEntryAttributes, 2190 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE, 2191 offsetof(CTL_ENTRY, rgAttribute), 0 }, 2192 }; 2193 BOOL ret = TRUE; 2194 CTL_ENTRY *entry = pvStructInfo; 2195 2196 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, 2197 *pcbStructInfo); 2198 2199 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2200 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, 2201 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL); 2202 return ret; 2203 } 2204 2205 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded, 2206 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 2207 { 2208 BOOL ret; 2209 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 2210 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry), 2211 FINALMEMBERSIZE(CTL_INFO, cExtension), 2212 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE, 2213 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) }; 2214 2215 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 2216 pvStructInfo, *pcbStructInfo, pcbDecoded); 2217 2218 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2219 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 2220 return ret; 2221 } 2222 2223 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded, 2224 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2225 DWORD *pcbDecoded) 2226 { 2227 BOOL ret = TRUE; 2228 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 2229 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension), 2230 FINALMEMBERSIZE(CTL_INFO, cExtension), 2231 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 2232 offsetof(CERT_EXTENSION, pszObjId) }; 2233 2234 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 2235 pvStructInfo, *pcbStructInfo, pcbDecoded); 2236 2237 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2238 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 2239 return ret; 2240 } 2241 2242 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded, 2243 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2244 DWORD *pcbDecoded) 2245 { 2246 BOOL ret; 2247 DWORD dataLen; 2248 2249 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 2250 { 2251 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 2252 2253 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes, 2254 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); 2255 if (ret && pcbDecoded) 2256 *pcbDecoded = 1 + lenBytes + dataLen; 2257 } 2258 return ret; 2259 } 2260 2261 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType, 2262 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 2263 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 2264 { 2265 BOOL ret = FALSE; 2266 2267 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2268 pDecodePara, pvStructInfo, *pcbStructInfo); 2269 2270 __TRY 2271 { 2272 struct AsnDecodeSequenceItem items[] = { 2273 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion), 2274 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, 2275 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage), 2276 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE, 2277 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 }, 2278 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier), 2279 CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB), TRUE, 2280 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 }, 2281 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber), 2282 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), 2283 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 }, 2284 { 0, offsetof(CTL_INFO, ThisUpdate), 2285 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 2286 0 }, 2287 { 0, offsetof(CTL_INFO, NextUpdate), 2288 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE, 2289 0 }, 2290 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm), 2291 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 2292 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 }, 2293 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry), 2294 CRYPT_AsnDecodeCTLEntries, 2295 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension), 2296 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 }, 2297 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension), 2298 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension), 2299 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 }, 2300 }; 2301 2302 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2303 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 2304 pcbStructInfo, NULL, NULL); 2305 } 2306 __EXCEPT_PAGE_FAULT 2307 { 2308 SetLastError(STATUS_ACCESS_VIOLATION); 2309 } 2310 __ENDTRY 2311 return ret; 2312 } 2313 2314 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded, 2315 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2316 DWORD *pcbDecoded) 2317 { 2318 BOOL ret; 2319 struct AsnDecodeSequenceItem items[] = { 2320 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 2321 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 2322 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 }, 2323 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters), 2324 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 2325 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 }, 2326 }; 2327 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo; 2328 2329 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2330 pvStructInfo, *pcbStructInfo); 2331 2332 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2333 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 2334 pcbDecoded, capability ? capability->pszObjId : NULL); 2335 TRACE("returning %d\n", ret); 2336 return ret; 2337 } 2338 2339 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType, 2340 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 2341 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 2342 { 2343 BOOL ret = FALSE; 2344 2345 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2346 pDecodePara, pvStructInfo, *pcbStructInfo); 2347 2348 __TRY 2349 { 2350 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 2351 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability), 2352 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability), 2353 sizeof(CRYPT_SMIME_CAPABILITIES), 2354 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE, 2355 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) }; 2356 CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo; 2357 2358 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 2359 capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1); 2360 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2361 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 2362 } 2363 __EXCEPT_PAGE_FAULT 2364 { 2365 SetLastError(STATUS_ACCESS_VIOLATION); 2366 } 2367 __ENDTRY 2368 TRACE("returning %d\n", ret); 2369 return ret; 2370 } 2371 2372 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded, 2373 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2374 DWORD *pcbDecoded) 2375 { 2376 BOOL ret = TRUE; 2377 DWORD dataLen; 2378 LPSTR *pStr = pvStructInfo; 2379 2380 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 2381 { 2382 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 2383 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char); 2384 2385 if (pbEncoded[0] != ASN_IA5STRING) 2386 { 2387 SetLastError(CRYPT_E_ASN1_CORRUPT); 2388 ret = FALSE; 2389 } 2390 else 2391 { 2392 bytesNeeded += dataLen; 2393 if (pcbDecoded) 2394 *pcbDecoded = 1 + lenBytes + dataLen; 2395 if (!pvStructInfo) 2396 *pcbStructInfo = bytesNeeded; 2397 else if (*pcbStructInfo < bytesNeeded) 2398 { 2399 *pcbStructInfo = bytesNeeded; 2400 SetLastError(ERROR_MORE_DATA); 2401 ret = FALSE; 2402 } 2403 else 2404 { 2405 *pcbStructInfo = bytesNeeded; 2406 if (dataLen) 2407 { 2408 LPSTR str = *pStr; 2409 2410 assert(str); 2411 memcpy(str, pbEncoded + 1 + lenBytes, dataLen); 2412 str[dataLen] = 0; 2413 } 2414 else 2415 *pStr = NULL; 2416 } 2417 } 2418 } 2419 return ret; 2420 } 2421 2422 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded, 2423 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2424 DWORD *pcbDecoded) 2425 { 2426 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 2427 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), 2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers), 2429 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), 2430 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 }; 2431 BOOL ret; 2432 2433 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags, 2434 pvStructInfo, pvStructInfo ? *pcbDecoded : 0); 2435 2436 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2437 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 2438 TRACE("returning %d\n", ret); 2439 return ret; 2440 } 2441 2442 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded, 2443 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2444 DWORD *pcbDecoded) 2445 { 2446 BOOL ret; 2447 struct AsnDecodeSequenceItem items[] = { 2448 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, 2449 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE, 2450 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 }, 2451 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, 2452 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers, 2453 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), 2454 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, 2455 rgNoticeNumbers), 0 }, 2456 }; 2457 DWORD bytesNeeded = 0; 2458 2459 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2460 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 2461 2462 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2463 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded, 2464 NULL); 2465 if (ret) 2466 { 2467 /* The caller is expecting a pointer to a 2468 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas 2469 * CRYPT_AsnDecodeSequence is decoding a 2470 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes 2471 * needed, and decode again if the requisite space is available. 2472 */ 2473 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE); 2474 if (!pvStructInfo) 2475 *pcbStructInfo = bytesNeeded; 2476 else if (*pcbStructInfo < bytesNeeded) 2477 { 2478 *pcbStructInfo = bytesNeeded; 2479 SetLastError(ERROR_MORE_DATA); 2480 ret = FALSE; 2481 } 2482 else 2483 { 2484 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef; 2485 2486 *pcbStructInfo = bytesNeeded; 2487 /* The pointer (pvStructInfo) passed in points to the first dynamic 2488 * pointer, so use it as the pointer to the 2489 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the 2490 * appropriate offset for the first dynamic pointer within the 2491 * notice reference by pointing to the first memory location past 2492 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. 2493 */ 2494 noticeRef = 2495 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo; 2496 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef + 2497 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE)); 2498 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags, 2499 NULL, noticeRef, &bytesNeeded, pcbDecoded, noticeRef->pszOrganization); 2500 } 2501 } 2502 TRACE("returning %d\n", ret); 2503 return ret; 2504 } 2505 2506 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded, 2507 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2508 DWORD *pcbDecoded) 2509 { 2510 BOOL ret = TRUE; 2511 DWORD dataLen; 2512 2513 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 2514 { 2515 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 2516 DWORD bytesNeeded = sizeof(LPWSTR); 2517 2518 switch (pbEncoded[0]) 2519 { 2520 case ASN_NUMERICSTRING: 2521 if (dataLen) 2522 bytesNeeded += (dataLen + 1) * 2; 2523 break; 2524 case ASN_PRINTABLESTRING: 2525 if (dataLen) 2526 bytesNeeded += (dataLen + 1) * 2; 2527 break; 2528 case ASN_IA5STRING: 2529 if (dataLen) 2530 bytesNeeded += (dataLen + 1) * 2; 2531 break; 2532 case ASN_T61STRING: 2533 if (dataLen) 2534 bytesNeeded += (dataLen + 1) * 2; 2535 break; 2536 case ASN_VIDEOTEXSTRING: 2537 if (dataLen) 2538 bytesNeeded += (dataLen + 1) * 2; 2539 break; 2540 case ASN_GRAPHICSTRING: 2541 if (dataLen) 2542 bytesNeeded += (dataLen + 1) * 2; 2543 break; 2544 case ASN_VISIBLESTRING: 2545 if (dataLen) 2546 bytesNeeded += (dataLen + 1) * 2; 2547 break; 2548 case ASN_GENERALSTRING: 2549 if (dataLen) 2550 bytesNeeded += (dataLen + 1) * 2; 2551 break; 2552 case ASN_UNIVERSALSTRING: 2553 if (dataLen) 2554 bytesNeeded += dataLen / 2 + sizeof(WCHAR); 2555 break; 2556 case ASN_BMPSTRING: 2557 if (dataLen) 2558 bytesNeeded += dataLen + sizeof(WCHAR); 2559 break; 2560 case ASN_UTF8STRING: 2561 if (dataLen) 2562 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0, 2563 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2; 2564 break; 2565 default: 2566 SetLastError(CRYPT_E_ASN1_BADTAG); 2567 return FALSE; 2568 } 2569 2570 if (pcbDecoded) 2571 *pcbDecoded = 1 + lenBytes + dataLen; 2572 if (!pvStructInfo) 2573 *pcbStructInfo = bytesNeeded; 2574 else if (*pcbStructInfo < bytesNeeded) 2575 { 2576 *pcbStructInfo = bytesNeeded; 2577 SetLastError(ERROR_MORE_DATA); 2578 ret = FALSE; 2579 } 2580 else 2581 { 2582 LPWSTR *pStr = pvStructInfo; 2583 2584 *pcbStructInfo = bytesNeeded; 2585 if (dataLen) 2586 { 2587 DWORD i; 2588 LPWSTR str = *(LPWSTR *)pStr; 2589 2590 assert(str); 2591 switch (pbEncoded[0]) 2592 { 2593 case ASN_NUMERICSTRING: 2594 case ASN_PRINTABLESTRING: 2595 case ASN_IA5STRING: 2596 case ASN_T61STRING: 2597 case ASN_VIDEOTEXSTRING: 2598 case ASN_GRAPHICSTRING: 2599 case ASN_VISIBLESTRING: 2600 case ASN_GENERALSTRING: 2601 for (i = 0; i < dataLen; i++) 2602 str[i] = pbEncoded[1 + lenBytes + i]; 2603 str[i] = 0; 2604 break; 2605 case ASN_UNIVERSALSTRING: 2606 for (i = 0; i < dataLen / 4; i++) 2607 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8) 2608 | pbEncoded[1 + lenBytes + 2 * i + 3]; 2609 str[i] = 0; 2610 break; 2611 case ASN_BMPSTRING: 2612 for (i = 0; i < dataLen / 2; i++) 2613 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | 2614 pbEncoded[1 + lenBytes + 2 * i + 1]; 2615 str[i] = 0; 2616 break; 2617 case ASN_UTF8STRING: 2618 { 2619 int len = MultiByteToWideChar(CP_UTF8, 0, 2620 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 2621 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; 2622 str[len] = 0; 2623 break; 2624 } 2625 } 2626 } 2627 else 2628 *pStr = NULL; 2629 } 2630 } 2631 return ret; 2632 } 2633 2634 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal( 2635 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, 2636 DWORD *pcbStructInfo, DWORD *pcbDecoded) 2637 { 2638 BOOL ret; 2639 struct AsnDecodeSequenceItem items[] = { 2640 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, 2641 pNoticeReference), CRYPT_AsnDecodeNoticeReference, 2642 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE, 2643 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 }, 2644 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 2645 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE, 2646 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 }, 2647 }; 2648 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo; 2649 2650 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2651 pvStructInfo, *pcbStructInfo); 2652 2653 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2654 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 2655 pcbDecoded, notice ? notice->pNoticeReference : NULL); 2656 TRACE("returning %d\n", ret); 2657 return ret; 2658 } 2659 2660 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice( 2661 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, 2662 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, 2663 void *pvStructInfo, DWORD *pcbStructInfo) 2664 { 2665 BOOL ret = FALSE; 2666 2667 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2668 pDecodePara, pvStructInfo, *pcbStructInfo); 2669 2670 __TRY 2671 { 2672 DWORD bytesNeeded = 0; 2673 2674 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded, 2675 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, 2676 NULL); 2677 if (ret) 2678 { 2679 if (!pvStructInfo) 2680 *pcbStructInfo = bytesNeeded; 2681 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 2682 pvStructInfo, pcbStructInfo, bytesNeeded))) 2683 { 2684 PCERT_POLICY_QUALIFIER_USER_NOTICE notice; 2685 2686 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 2687 pvStructInfo = *(BYTE **)pvStructInfo; 2688 notice = pvStructInfo; 2689 notice->pNoticeReference = 2690 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE) 2691 ((BYTE *)pvStructInfo + 2692 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE)); 2693 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal( 2694 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, 2695 pvStructInfo, &bytesNeeded, NULL); 2696 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 2697 CRYPT_FreeSpace(pDecodePara, notice); 2698 } 2699 } 2700 } 2701 __EXCEPT_PAGE_FAULT 2702 { 2703 SetLastError(STATUS_ACCESS_VIOLATION); 2704 } 2705 __ENDTRY 2706 TRACE("returning %d\n", ret); 2707 return ret; 2708 } 2709 2710 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded, 2711 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2712 DWORD *pcbDecoded) 2713 { 2714 BOOL ret; 2715 struct AsnArrayDescriptor arrayDesc = { 0, 2716 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue), 2717 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), 2718 CRYPT_AsnDecodeCopyBytes, 2719 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; 2720 2721 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 2722 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); 2723 2724 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2725 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 2726 return ret; 2727 } 2728 2729 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, 2730 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2731 DWORD *pcbDecoded) 2732 { 2733 BOOL ret; 2734 struct AsnDecodeSequenceItem items[] = { 2735 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId), 2736 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 2737 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 }, 2738 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue), 2739 CRYPT_AsnDecodePKCSAttributeValue, 2740 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE, 2741 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 }, 2742 }; 2743 PCRYPT_ATTRIBUTE attr = pvStructInfo; 2744 2745 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2746 pvStructInfo, *pcbStructInfo); 2747 2748 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2749 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 2750 pcbDecoded, attr ? attr->pszObjId : NULL); 2751 TRACE("returning %d\n", ret); 2752 return ret; 2753 } 2754 2755 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType, 2756 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 2757 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 2758 { 2759 BOOL ret = FALSE; 2760 2761 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2762 pDecodePara, pvStructInfo, *pcbStructInfo); 2763 2764 __TRY 2765 { 2766 DWORD bytesNeeded = 0; 2767 2768 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded, 2769 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); 2770 if (ret) 2771 { 2772 if (!pvStructInfo) 2773 *pcbStructInfo = bytesNeeded; 2774 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 2775 pvStructInfo, pcbStructInfo, bytesNeeded))) 2776 { 2777 PCRYPT_ATTRIBUTE attr; 2778 2779 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 2780 pvStructInfo = *(BYTE **)pvStructInfo; 2781 attr = pvStructInfo; 2782 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo + 2783 sizeof(CRYPT_ATTRIBUTE)); 2784 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded, 2785 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded, 2786 NULL); 2787 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 2788 CRYPT_FreeSpace(pDecodePara, attr); 2789 } 2790 } 2791 } 2792 __EXCEPT_PAGE_FAULT 2793 { 2794 SetLastError(STATUS_ACCESS_VIOLATION); 2795 } 2796 __ENDTRY 2797 TRACE("returning %d\n", ret); 2798 return ret; 2799 } 2800 2801 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded, 2802 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2803 DWORD *pcbDecoded) 2804 { 2805 struct AsnArrayDescriptor arrayDesc = { 0, 2806 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr), 2807 sizeof(CRYPT_ATTRIBUTES), 2808 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE, 2809 offsetof(CRYPT_ATTRIBUTE, pszObjId) }; 2810 BOOL ret; 2811 2812 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 2813 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 2814 return ret; 2815 } 2816 2817 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType, 2818 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 2819 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 2820 { 2821 BOOL ret = FALSE; 2822 2823 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2824 pDecodePara, pvStructInfo, *pcbStructInfo); 2825 2826 __TRY 2827 { 2828 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 2829 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr), 2830 sizeof(CRYPT_ATTRIBUTES), 2831 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), 2832 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) }; 2833 CRYPT_ATTRIBUTES *attrs = pvStructInfo; 2834 2835 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 2836 attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1); 2837 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 2838 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 2839 } 2840 __EXCEPT_PAGE_FAULT 2841 { 2842 SetLastError(STATUS_ACCESS_VIOLATION); 2843 } 2844 __ENDTRY 2845 TRACE("returning %d\n", ret); 2846 return ret; 2847 } 2848 2849 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded, 2850 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 2851 { 2852 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo; 2853 BOOL ret = TRUE; 2854 struct AsnDecodeSequenceItem items[] = { 2855 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 2856 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 2857 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 }, 2858 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters), 2859 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 2860 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 }, 2861 }; 2862 2863 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 2864 pvStructInfo, *pcbStructInfo, pcbDecoded); 2865 2866 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2867 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 2868 pcbDecoded, algo ? algo->pszObjId : NULL); 2869 if (ret && pvStructInfo) 2870 { 2871 TRACE("pszObjId is %p (%s)\n", algo->pszObjId, 2872 debugstr_a(algo->pszObjId)); 2873 } 2874 return ret; 2875 } 2876 2877 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded, 2878 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 2879 DWORD *pcbDecoded) 2880 { 2881 BOOL ret = TRUE; 2882 struct AsnDecodeSequenceItem items[] = { 2883 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm), 2884 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 2885 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO, 2886 Algorithm.pszObjId) }, 2887 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey), 2888 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 2889 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) }, 2890 }; 2891 PCERT_PUBLIC_KEY_INFO info = pvStructInfo; 2892 2893 ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), 2894 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 2895 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL); 2896 return ret; 2897 } 2898 2899 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType, 2900 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 2901 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 2902 { 2903 BOOL ret = TRUE; 2904 2905 __TRY 2906 { 2907 DWORD bytesNeeded = 0; 2908 2909 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded, 2910 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL))) 2911 { 2912 if (!pvStructInfo) 2913 *pcbStructInfo = bytesNeeded; 2914 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 2915 pvStructInfo, pcbStructInfo, bytesNeeded))) 2916 { 2917 PCERT_PUBLIC_KEY_INFO info; 2918 2919 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 2920 pvStructInfo = *(BYTE **)pvStructInfo; 2921 info = pvStructInfo; 2922 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo + 2923 sizeof(CERT_PUBLIC_KEY_INFO); 2924 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded, 2925 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 2926 &bytesNeeded, NULL); 2927 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 2928 CRYPT_FreeSpace(pDecodePara, info); 2929 } 2930 } 2931 } 2932 __EXCEPT_PAGE_FAULT 2933 { 2934 SetLastError(STATUS_ACCESS_VIOLATION); 2935 ret = FALSE; 2936 } 2937 __ENDTRY 2938 return ret; 2939 } 2940 2941 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded, 2942 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 2943 { 2944 BOOL ret; 2945 2946 if (cbEncoded < 3) 2947 { 2948 SetLastError(CRYPT_E_ASN1_CORRUPT); 2949 return FALSE; 2950 } 2951 if (GET_LEN_BYTES(pbEncoded[1]) > 1) 2952 { 2953 SetLastError(CRYPT_E_ASN1_CORRUPT); 2954 return FALSE; 2955 } 2956 if (pbEncoded[1] > 1) 2957 { 2958 SetLastError(CRYPT_E_ASN1_CORRUPT); 2959 return FALSE; 2960 } 2961 if (pcbDecoded) 2962 *pcbDecoded = 3; 2963 if (!pvStructInfo) 2964 { 2965 *pcbStructInfo = sizeof(BOOL); 2966 ret = TRUE; 2967 } 2968 else if (*pcbStructInfo < sizeof(BOOL)) 2969 { 2970 *pcbStructInfo = sizeof(BOOL); 2971 SetLastError(ERROR_MORE_DATA); 2972 ret = FALSE; 2973 } 2974 else 2975 { 2976 *pcbStructInfo = sizeof(BOOL); 2977 *(BOOL *)pvStructInfo = pbEncoded[2] != 0; 2978 ret = TRUE; 2979 } 2980 TRACE("returning %d (%08x)\n", ret, GetLastError()); 2981 return ret; 2982 } 2983 2984 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, 2985 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 2986 { 2987 PCERT_ALT_NAME_ENTRY entry = pvStructInfo; 2988 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY); 2989 BOOL ret; 2990 2991 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 2992 pvStructInfo, *pcbStructInfo); 2993 2994 if (cbEncoded < 2) 2995 { 2996 SetLastError(CRYPT_E_ASN1_CORRUPT); 2997 return FALSE; 2998 } 2999 lenBytes = GET_LEN_BYTES(pbEncoded[1]); 3000 if (1 + lenBytes > cbEncoded) 3001 { 3002 SetLastError(CRYPT_E_ASN1_CORRUPT); 3003 return FALSE; 3004 } 3005 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 3006 { 3007 switch (pbEncoded[0] & ASN_TYPE_MASK) 3008 { 3009 case 1: /* rfc822Name */ 3010 case 2: /* dNSName */ 3011 case 6: /* uniformResourceIdentifier */ 3012 if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen)) 3013 { 3014 SetLastError(CRYPT_E_ASN1_RULE); 3015 ret = FALSE; 3016 } 3017 else 3018 bytesNeeded += (dataLen + 1) * sizeof(WCHAR); 3019 break; 3020 case 4: /* directoryName */ 3021 case 7: /* iPAddress */ 3022 bytesNeeded += dataLen; 3023 break; 3024 case 8: /* registeredID */ 3025 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL, 3026 &dataLen, NULL); 3027 if (ret) 3028 { 3029 /* FIXME: ugly, shouldn't need to know internals of OID decode 3030 * function to use it. 3031 */ 3032 bytesNeeded += dataLen - sizeof(LPSTR); 3033 } 3034 break; 3035 case 0: /* otherName */ 3036 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK); 3037 SetLastError(CRYPT_E_ASN1_BADTAG); 3038 ret = FALSE; 3039 break; 3040 case 3: /* x400Address, unimplemented */ 3041 case 5: /* ediPartyName, unimplemented */ 3042 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK); 3043 SetLastError(CRYPT_E_ASN1_BADTAG); 3044 ret = FALSE; 3045 break; 3046 default: 3047 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK); 3048 SetLastError(CRYPT_E_ASN1_CORRUPT); 3049 ret = FALSE; 3050 } 3051 if (ret) 3052 { 3053 if (pcbDecoded) 3054 *pcbDecoded = 1 + lenBytes + dataLen; 3055 if (!entry) 3056 *pcbStructInfo = bytesNeeded; 3057 else if (*pcbStructInfo < bytesNeeded) 3058 { 3059 *pcbStructInfo = bytesNeeded; 3060 SetLastError(ERROR_MORE_DATA); 3061 ret = FALSE; 3062 } 3063 else 3064 { 3065 *pcbStructInfo = bytesNeeded; 3066 /* MS used values one greater than the asn1 ones.. sigh */ 3067 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1; 3068 switch (pbEncoded[0] & ASN_TYPE_MASK) 3069 { 3070 case 1: /* rfc822Name */ 3071 case 2: /* dNSName */ 3072 case 6: /* uniformResourceIdentifier */ 3073 { 3074 DWORD i; 3075 3076 for (i = 0; i < dataLen; i++) 3077 entry->u.pwszURL[i] = 3078 (WCHAR)pbEncoded[1 + lenBytes + i]; 3079 entry->u.pwszURL[i] = 0; 3080 TRACE("URL is %p (%s)\n", entry->u.pwszURL, 3081 debugstr_w(entry->u.pwszURL)); 3082 break; 3083 } 3084 case 4: /* directoryName */ 3085 /* The data are memory-equivalent with the IPAddress case, 3086 * fall-through 3087 */ 3088 case 7: /* iPAddress */ 3089 /* The next data pointer is in the pwszURL spot, that is, 3090 * the first 4 bytes. Need to move it to the next spot. 3091 */ 3092 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL; 3093 entry->u.IPAddress.cbData = dataLen; 3094 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes, 3095 dataLen); 3096 break; 3097 case 8: /* registeredID */ 3098 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, 3099 &entry->u.pszRegisteredID, &dataLen, NULL); 3100 break; 3101 } 3102 } 3103 } 3104 } 3105 return ret; 3106 } 3107 3108 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded, 3109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 3110 DWORD *pcbDecoded) 3111 { 3112 BOOL ret; 3113 struct AsnArrayDescriptor arrayDesc = { 0, 3114 offsetof(CERT_ALT_NAME_INFO, cAltEntry), 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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. */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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