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