1/* 2 * The contents of this file are subject to the Mozilla Public 3 * License Version 1.1 (the "License"); you may not use this file 4 * except in compliance with the License. You may obtain a copy of 5 * the License at http://www.mozilla.org/MPL/ 6 * 7 * Software distributed under the License is distributed on an "AS 8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 9 * implied. See the License for the specific language governing 10 * rights and limitations under the License. 11 * 12 * The Original Code is the Netscape security libraries. 13 * 14 * The Initial Developer of the Original Code is Netscape 15 * Communications Corporation. Portions created by Netscape are 16 * Copyright (C) 1994-2000 Netscape Communications Corporation. All 17 * Rights Reserved. 18 * 19 * Contributor(s): 20 * 21 * Alternatively, the contents of this file may be used under the 22 * terms of the GNU General Public License Version 2 or later (the 23 * "GPL"), in which case the provisions of the GPL are applicable 24 * instead of those above. If you wish to allow use of your 25 * version of this file only under the terms of the GPL and not to 26 * allow others to use your version of this file under the MPL, 27 * indicate your decision by deleting the provisions above and 28 * replace them with the notice and other provisions required by 29 * the GPL. If you do not delete the provisions above, a recipient 30 * may use your version of this file under either the MPL or the 31 * GPL. 32 */ 33 34/* 35 * Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished 36 * Encoding Rules). 37 * 38 * $Id: secasn1d.c,v 1.16 2004/05/13 15:29:13 dmitch Exp $ 39 */ 40 41#include "secasn1.h" 42#include "secerr.h" 43#include "assert.h" 44 45#ifdef NDEBUG 46#define DEBUG_DECASN1 0 47#else 48#define DEBUG_DECASN1 1 49#endif 50 51#if DEBUG_DECASN1 52#include <stdio.h> 53#define dprintf(args...) printf(args) 54#else 55#define dprintf(args...) 56#endif /* DEBUG_DECASN1 */ 57 58typedef enum { 59 beforeIdentifier, 60 duringIdentifier, 61 afterIdentifier, 62 beforeLength, 63 duringLength, 64 afterLength, 65 beforeBitString, 66 duringBitString, 67 duringConstructedString, 68 duringGroup, 69 duringLeaf, 70 duringSaveEncoding, 71 duringSequence, 72 afterConstructedString, 73 afterGroup, 74 afterExplicit, 75 afterImplicit, 76 afterInline, 77 afterPointer, 78 afterSaveEncoding, 79 beforeEndOfContents, 80 duringEndOfContents, 81 afterEndOfContents, 82 beforeChoice, 83 duringChoice, 84 afterChoice, 85 notInUse 86} sec_asn1d_parse_place; 87 88#ifndef NDEBUG 89#define DEBUG_ASN1D_STATES 1 90/* tweakable by debugger, debug only */ 91int doDumpStates = 0; 92#else /* DEBUG_ASN1D_STATES 0 */ 93#endif /* DEBUG_ASN1D_STATES */ 94 95#if DEBUG_ASN1D_STATES 96static const char *place_names[] = { 97 "beforeIdentifier", 98 "duringIdentifier", 99 "afterIdentifier", 100 "beforeLength", 101 "duringLength", 102 "afterLength", 103 "beforeBitString", 104 "duringBitString", 105 "duringConstructedString", 106 "duringGroup", 107 "duringLeaf", 108 "duringSaveEncoding", 109 "duringSequence", 110 "afterConstructedString", 111 "afterGroup", 112 "afterExplicit", 113 "afterImplicit", 114 "afterInline", 115 "afterPointer", 116 "afterSaveEncoding", 117 "beforeEndOfContents", 118 "duringEndOfContents", 119 "afterEndOfContents", 120 "beforeChoice", 121 "duringChoice", 122 "afterChoice", 123 "notInUse" 124}; 125 126static const char * const class_names[] = { 127 "UNIVERSAL", 128 "APPLICATION", 129 "CONTEXT_SPECIFIC", 130 "PRIVATE" 131}; 132 133static const char * const method_names[] = { "PRIMITIVE", "CONSTRUCTED" }; 134 135static const char * const type_names[] = { 136 "END_OF_CONTENTS", 137 "BOOLEAN", 138 "INTEGER", 139 "BIT_STRING", 140 "OCTET_STRING", 141 "NULL", 142 "OBJECT_ID", 143 "OBJECT_DESCRIPTOR", 144 "(type 08)", 145 "REAL", 146 "ENUMERATED", 147 "EMBEDDED", 148 "UTF8_STRING", 149 "(type 0d)", 150 "(type 0e)", 151 "(type 0f)", 152 "SEQUENCE", 153 "SET", 154 "NUMERIC_STRING", 155 "PRINTABLE_STRING", 156 "T61_STRING", 157 "VIDEOTEXT_STRING", 158 "IA5_STRING", 159 "UTC_TIME", 160 "GENERALIZED_TIME", 161 "GRAPHIC_STRING", 162 "VISIBLE_STRING", 163 "GENERAL_STRING", 164 "UNIVERSAL_STRING", 165 "(type 1d)", 166 "BMP_STRING", 167 "HIGH_TAG_VALUE" 168}; 169 170static const char * const flag_names[] = { /* flags, right to left */ 171 "OPTIONAL", 172 "EXPLICIT", 173 "ANY", 174 "INLINE", 175 "POINTER", 176 "GROUP", 177 "DYNAMIC", 178 "SKIP", 179 "INNER", 180 "SAVE", 181 "", /* decoder ignores "MAY_STREAM", */ 182 "SKIP_REST", 183 "CHOICE", 184 "NO_STREAM", 185 "DEBUG_BREAK", 186 "unknown 08", 187 "unknown 10", 188 "unknown 20", 189 "unknown 40", 190 "unknown 80" 191}; 192 193static int /* bool */ 194formatKind(unsigned long kind, char * buf) 195{ 196 int i; 197 unsigned long k = kind & SEC_ASN1_TAGNUM_MASK; 198 unsigned long notag = kind & (SEC_ASN1_CHOICE | SEC_ASN1_POINTER | 199 SEC_ASN1_INLINE | SEC_ASN1_ANY | SEC_ASN1_SAVE); 200 201 buf[0] = 0; 202 if ((kind & SEC_ASN1_CLASS_MASK) != SEC_ASN1_UNIVERSAL) { 203 sprintf(buf, " %s", class_names[(kind & SEC_ASN1_CLASS_MASK) >> 6] ); 204 buf += strlen(buf); 205 } 206 if (kind & SEC_ASN1_METHOD_MASK) { 207 sprintf(buf, " %s", method_names[1]); 208 buf += strlen(buf); 209 } 210 if ((kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) { 211 if (k || !notag) { 212 sprintf(buf, " %s", type_names[k] ); 213 if ((k == SEC_ASN1_SET || k == SEC_ASN1_SEQUENCE) && 214 (kind & SEC_ASN1_GROUP)) { 215 buf += strlen(buf); 216 sprintf(buf, "_OF"); 217 } 218 } 219 } else { 220 sprintf(buf, " [%lu]", k); 221 } 222 buf += strlen(buf); 223 224 for (k = kind >> 8, i = 0; k; k >>= 1, ++i) { 225 if (k & 1) { 226 sprintf(buf, " %s", flag_names[i]); 227 buf += strlen(buf); 228 } 229 } 230 return notag != 0; 231} 232 233#endif /* DEBUG_ASN1D_STATES */ 234 235typedef enum { 236 allDone, 237 decodeError, 238 keepGoing, 239 needBytes 240} sec_asn1d_parse_status; 241 242struct subitem { 243 const void *data; 244 unsigned long len; /* only used for substrings */ 245 struct subitem *next; 246}; 247 248typedef struct sec_asn1d_state_struct { 249 SEC_ASN1DecoderContext *top; 250 const SecAsn1Template *theTemplate; 251 void *dest; 252 253 void *our_mark; /* free on completion */ 254 255 struct sec_asn1d_state_struct *parent; /* aka prev */ 256 struct sec_asn1d_state_struct *child; /* aka next */ 257 258 sec_asn1d_parse_place place; 259 260 /* 261 * XXX explain the next fields as clearly as possible... 262 */ 263 unsigned char found_tag_modifiers; 264 unsigned char expect_tag_modifiers; 265 unsigned long check_tag_mask; 266 unsigned long found_tag_number; 267 unsigned long expect_tag_number; 268 unsigned long underlying_kind; 269 270 unsigned long contents_length; 271 unsigned long pending; 272 unsigned long consumed; 273 274 int depth; 275 276 /* 277 * Bit strings have their length adjusted -- the first octet of the 278 * contents contains a value between 0 and 7 which says how many bits 279 * at the end of the octets are not actually part of the bit string; 280 * when parsing bit strings we put that value here because we need it 281 * later, for adjustment of the length (when the whole string is done). 282 */ 283 unsigned int bit_string_unused_bits; 284 285 /* 286 * The following are used for indefinite-length constructed strings. 287 */ 288 struct subitem *subitems_head; 289 struct subitem *subitems_tail; 290 291 PRPackedBool 292 allocate, /* when true, need to allocate the destination */ 293 endofcontents, /* this state ended up parsing end-of-contents octets */ 294 explicit, /* we are handling an explicit header */ 295 indefinite, /* the current item has indefinite-length encoding */ 296 missing, /* an optional field that was not present */ 297 optional, /* the template says this field may be omitted */ 298 substring; /* this is a substring of a constructed string */ 299} sec_asn1d_state; 300 301#define IS_HIGH_TAG_NUMBER(n) ((n) == SEC_ASN1_HIGH_TAG_NUMBER) 302#define LAST_TAG_NUMBER_BYTE(b) (((b) & 0x80) == 0) 303#define TAG_NUMBER_BITS 7 304#define TAG_NUMBER_MASK 0x7f 305 306#define LENGTH_IS_SHORT_FORM(b) (((b) & 0x80) == 0) 307#define LONG_FORM_LENGTH(b) ((b) & 0x7f) 308 309#define HIGH_BITS(field,cnt) ((field) >> ((sizeof(field) * 8) - (cnt))) 310 311 312/* 313 * An "outsider" will have an opaque pointer to this, created by calling 314 * SEC_ASN1DecoderStart(). It will be passed back in to all subsequent 315 * calls to SEC_ASN1DecoderUpdate(), and when done it is passed to 316 * SEC_ASN1DecoderFinish(). 317 */ 318struct sec_DecoderContext_struct { 319 PRArenaPool *our_pool; /* for our internal allocs */ 320 PRArenaPool *their_pool; /* for destination structure allocs */ 321#ifdef SEC_ASN1D_FREE_ON_ERROR /* 322 * XXX see comment below (by same 323 * ifdef) that explains why this 324 * does not work (need more smarts 325 * in order to free back to mark) 326 */ 327 /* 328 * XXX how to make their_mark work in the case where they do NOT 329 * give us a pool pointer? 330 */ 331 void *their_mark; /* free on error */ 332#endif 333 334 sec_asn1d_state *current; 335 sec_asn1d_parse_status status; 336 337 SEC_ASN1NotifyProc notify_proc; /* call before/after handling field */ 338 void *notify_arg; /* argument to notify_proc */ 339 PRBool during_notify; /* true during call to notify_proc */ 340 341 SEC_ASN1WriteProc filter_proc; /* pass field bytes to this */ 342 void *filter_arg; /* argument to that function */ 343 PRBool filter_only; /* do not allocate/store fields */ 344}; 345 346 347/* 348 * XXX this is a fairly generic function that may belong elsewhere 349 */ 350static void * 351sec_asn1d_alloc (PRArenaPool *poolp, unsigned long len) 352{ 353 void *thing; 354 355 if (poolp != NULL) { 356 /* 357 * Allocate from the pool. 358 */ 359 thing = PORT_ArenaAlloc (poolp, len); 360 } else { 361 /* 362 * Allocate generically. 363 */ 364 thing = PORT_Alloc (len); 365 } 366 367 return thing; 368} 369 370 371/* 372 * XXX this is a fairly generic function that may belong elsewhere 373 */ 374static void * 375sec_asn1d_zalloc (PRArenaPool *poolp, unsigned long len) 376{ 377 void *thing; 378 379 thing = sec_asn1d_alloc (poolp, len); 380 if (thing != NULL) 381 PORT_Memset (thing, 0, len); 382 return thing; 383} 384 385 386static sec_asn1d_state * 387sec_asn1d_push_state (SEC_ASN1DecoderContext *cx, 388 const SecAsn1Template *theTemplate, 389 void *dest, PRBool new_depth) 390{ 391 sec_asn1d_state *state, *new_state; 392 393 state = cx->current; 394 395 PORT_Assert (state == NULL || state->child == NULL); 396 397 if (state != NULL) { 398 PORT_Assert (state->our_mark == NULL); 399 state->our_mark = PORT_ArenaMark (cx->our_pool); 400 } 401 402 new_state = (sec_asn1d_state*)sec_asn1d_zalloc (cx->our_pool, 403 sizeof(*new_state)); 404 if (new_state == NULL) { 405 dprintf("decodeError: zalloc failure\n"); 406 goto loser; 407 } 408 409 new_state->top = cx; 410 new_state->parent = state; 411 new_state->theTemplate = theTemplate; 412 new_state->place = notInUse; 413 if (dest != NULL) 414 new_state->dest = (char *)dest + theTemplate->offset; 415 416 if (state != NULL) { 417 new_state->depth = state->depth; 418 if (new_depth) { 419 if (++new_state->depth > SEC_ASN1D_MAX_DEPTH) { 420 PORT_SetError (SEC_ERROR_BAD_DER); 421 goto loser; 422 } 423 } 424 state->child = new_state; 425 } 426 427 cx->current = new_state; 428 return new_state; 429 430loser: 431 cx->status = decodeError; 432 if (state != NULL) { 433 PORT_ArenaRelease(cx->our_pool, state->our_mark); 434 state->our_mark = NULL; 435 } 436 return NULL; 437} 438 439 440static void 441sec_asn1d_scrub_state (sec_asn1d_state *state) 442{ 443 /* 444 * Some default "scrubbing". 445 * XXX right set of initializations? 446 */ 447 state->place = beforeIdentifier; 448 state->endofcontents = PR_FALSE; 449 state->indefinite = PR_FALSE; 450 state->missing = PR_FALSE; 451 452 PORT_Assert (state->consumed == 0); 453} 454 455 456static sec_asn1d_state * 457sec_asn1d_get_enclosing_construct(sec_asn1d_state *state) 458{ 459 for (state = state->parent; state; state = state->parent) { 460 sec_asn1d_parse_place place = state->place; 461 if (place != afterImplicit && 462 place != afterPointer && 463 place != afterInline && 464 place != afterSaveEncoding && 465 place != duringSaveEncoding && 466 place != duringChoice) { 467 468 /* we've walked up the stack to a state that represents 469 ** the enclosing construct. 470 */ 471 break; 472 } 473 } 474 return state; 475} 476 477 478static PRBool 479sec_asn1d_parent_allows_EOC(sec_asn1d_state *state) 480{ 481 /* get state of enclosing construct. */ 482 state = sec_asn1d_get_enclosing_construct(state); 483 if (state) { 484 sec_asn1d_parse_place place = state->place; 485 /* Is it one of the types that permits an unexpected EOC? */ 486 int eoc_permitted = 487 (place == duringGroup || 488 place == duringConstructedString || 489 state->child->optional); 490 return (state->indefinite && eoc_permitted) ? PR_TRUE : PR_FALSE; 491 } 492 return PR_FALSE; 493} 494 495 496static void 497sec_asn1d_notify_before (SEC_ASN1DecoderContext *cx, void *dest, int depth) 498{ 499 if (cx->notify_proc == NULL) 500 return; 501 502 cx->during_notify = PR_TRUE; 503 (* cx->notify_proc) (cx->notify_arg, PR_TRUE, dest, depth); 504 cx->during_notify = PR_FALSE; 505} 506 507 508static void 509sec_asn1d_notify_after (SEC_ASN1DecoderContext *cx, void *dest, int depth) 510{ 511 if (cx->notify_proc == NULL) 512 return; 513 514 cx->during_notify = PR_TRUE; 515 (* cx->notify_proc) (cx->notify_arg, PR_FALSE, dest, depth); 516 cx->during_notify = PR_FALSE; 517} 518 519 520static sec_asn1d_state * 521sec_asn1d_init_state_based_on_template (sec_asn1d_state *state, 522 #ifdef __APPLE__ 523 const char *buf /* for SEC_ASN1GetSubtemplate() */ 524 #endif 525 ) 526{ 527 PRBool explicit, optional, universal; 528 unsigned char expect_tag_modifiers; 529 unsigned long encode_kind, under_kind; 530 unsigned long check_tag_mask, expect_tag_number; 531 #ifdef __APPLE__ 532 unsigned long dynamic; 533 #endif 534 535 536 /* XXX Check that both of these tests are really needed/appropriate. */ 537 if (state == NULL || state->top->status == decodeError) 538 return state; 539 540 encode_kind = state->theTemplate->kind; 541 542 if (encode_kind & SEC_ASN1_SAVE) { 543 /* 544 * This is a "magic" field that saves away all bytes, allowing 545 * the immediately following field to still be decoded from this 546 * same spot -- sort of a fork. 547 */ 548 /* check that there are no extraneous bits */ 549 PORT_Assert (encode_kind == SEC_ASN1_SAVE); 550 if (state->top->filter_only) { 551 /* 552 * If we are not storing, then we do not do the SAVE field 553 * at all. Just move ahead to the "real" field instead, 554 * doing the appropriate notify calls before and after. 555 */ 556 sec_asn1d_notify_after (state->top, state->dest, state->depth); 557 /* 558 * Since we are not storing, allow for our current dest value 559 * to be NULL. (This might not actually occur, but right now I 560 * cannot convince myself one way or the other.) If it is NULL, 561 * assume that our parent dest can help us out. 562 */ 563 if (state->dest == NULL) 564 state->dest = state->parent->dest; 565 else 566 state->dest = 567 (char *)state->dest - state->theTemplate->offset; 568 state->theTemplate++; 569 if (state->dest != NULL) 570 state->dest = 571 (char *)state->dest + state->theTemplate->offset; 572 sec_asn1d_notify_before (state->top, state->dest, state->depth); 573 encode_kind = state->theTemplate->kind; 574 PORT_Assert ((encode_kind & SEC_ASN1_SAVE) == 0); 575 } else { 576 sec_asn1d_scrub_state (state); 577 state->place = duringSaveEncoding; 578 state = sec_asn1d_push_state (state->top, kSecAsn1AnyTemplate, 579 state->dest, PR_FALSE); 580 if (state != NULL) 581 state = sec_asn1d_init_state_based_on_template (state, 582 buf /* __APPLE__ */); 583 return state; 584 } 585 } 586 587 588 universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) 589 ? PR_TRUE : PR_FALSE; 590 591 explicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE; 592 encode_kind &= ~SEC_ASN1_EXPLICIT; 593 594 optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE; 595 encode_kind &= ~SEC_ASN1_OPTIONAL; 596 597 #ifdef __APPLE__ 598 dynamic = (encode_kind & SEC_ASN1_DYNAMIC) ? PR_TRUE : PR_FALSE; 599 encode_kind &= ~SEC_ASN1_DYNAMIC; 600 #endif 601 602 PORT_Assert (!(explicit && universal)); /* bad templates */ 603 604 encode_kind &= ~SEC_ASN1_DYNAMIC; 605 encode_kind &= ~SEC_ASN1_MAY_STREAM; 606 607 if( encode_kind & SEC_ASN1_CHOICE ) { 608#if 0 /* XXX remove? */ 609 sec_asn1d_state *child = sec_asn1d_push_state(state->top, state->theTemplate, state->dest, PR_FALSE); 610 if( (sec_asn1d_state *)NULL == child ) { 611 return (sec_asn1d_state *)NULL; 612 } 613 614 child->allocate = state->allocate; 615 child->place = beforeChoice; 616 return child; 617#else 618 state->place = beforeChoice; 619 return state; 620#endif 621 } 622 623 if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || (!universal 624 && !explicit)) { 625 const SecAsn1Template *subt; 626 void *dest; 627 PRBool child_allocate; 628 void *subDest; 629 630 PORT_Assert ((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0); 631 632 sec_asn1d_scrub_state (state); 633 child_allocate = PR_FALSE; 634 635 if (encode_kind & SEC_ASN1_POINTER) { 636 /* 637 * A POINTER means we need to allocate the destination for 638 * this field. But, since it may also be an optional field, 639 * we defer the allocation until later; we just record that 640 * it needs to be done. 641 * 642 * There are two possible scenarios here -- one is just a 643 * plain POINTER (kind of like INLINE, except with allocation) 644 * and the other is an implicitly-tagged POINTER. We don't 645 * need to do anything special here for the two cases, but 646 * since the template definition can be tricky, we do check 647 * that there are no extraneous bits set in encode_kind. 648 * 649 * XXX The same conditions which assert should set an error. 650 */ 651 if (universal) { 652 /* 653 * "universal" means this entry is a standalone POINTER; 654 * there should be no other bits set in encode_kind. 655 */ 656 PORT_Assert (encode_kind == SEC_ASN1_POINTER); 657 } else { 658 /* 659 * If we get here we have an implicitly-tagged field 660 * that needs to be put into a POINTER. The subtemplate 661 * will determine how to decode the field, but encode_kind 662 * describes the (implicit) tag we are looking for. 663 * The non-tag bits of encode_kind will be ignored by 664 * the code below; none of them should be set, however, 665 * except for the POINTER bit itself -- so check that. 666 */ 667 PORT_Assert ((encode_kind & ~SEC_ASN1_TAG_MASK) 668 == SEC_ASN1_POINTER); 669 } 670 if (!state->top->filter_only) 671 child_allocate = PR_TRUE; 672 dest = NULL; 673 state->place = afterPointer; 674 } else { 675 dest = state->dest; 676 if (encode_kind & SEC_ASN1_INLINE) { 677 /* check that there are no extraneous bits */ 678 /* FIXME - why are optional and inline mutually 679 * exclusive? Delete this assert and see what happens... 680 PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional); 681 */ 682 state->place = afterInline; 683 } else { 684 state->place = afterImplicit; 685 } 686 } 687 688 state->optional = optional; 689 690 subDest = state->dest; 691 #if defined(__APPLE__) 692 /* 693 * We might be starting the processing of a group or a 694 * set, in which case state->dest is NULL. Get parent's dest, 695 * or grandparent's, etc... just for the use by 696 * SEC_ASN1GetSubtemplate (specifically, by dynamic 697 * choosers) 698 */ 699 sec_asn1d_state *tempState = state; 700 while(subDest == NULL) { 701 sec_asn1d_state *parent = tempState->parent; 702 if(parent == NULL) { 703 /* Oh well. Not going to work for this template. */ 704 break; 705 } 706 subDest = parent->dest; 707 tempState = parent; 708 } 709 #endif /* __APPLE__ */ 710 subt = SEC_ASN1GetSubtemplate (state->theTemplate, subDest, 711 PR_FALSE, buf /* __APPLE__ */); 712 state = sec_asn1d_push_state (state->top, subt, dest, PR_FALSE); 713 if (state == NULL) 714 return NULL; 715 716 state->allocate = child_allocate; 717 718 if (universal 719 #ifdef __APPLE__ 720 /* Dynamic: restart with new template */ 721 || dynamic 722 #endif 723 ) { 724 state = sec_asn1d_init_state_based_on_template (state, 725 buf /* __APPLE__ */); 726 if (state != NULL) { 727 /* 728 * If this field is optional, we need to record that on 729 * the pushed child so it won't fail if the field isn't 730 * found. I can't think of a way that this new state 731 * could already have optional set (which we would wipe 732 * out below if our local optional is not set) -- but 733 * just to be sure, assert that it isn't set. 734 */ 735 PORT_Assert (!state->optional); 736 state->optional = optional; 737 } 738 return state; 739 } 740 741 under_kind = state->theTemplate->kind; 742 under_kind &= ~SEC_ASN1_MAY_STREAM; 743 } else if (explicit) { 744 /* 745 * For explicit, we only need to match the encoding tag next, 746 * then we will push another state to handle the entire inner 747 * part. In this case, there is no underlying kind which plays 748 * any part in the determination of the outer, explicit tag. 749 * So we just set under_kind to 0, which is not a valid tag, 750 * and the rest of the tag matching stuff should be okay. 751 */ 752 under_kind = 0; 753 } else { 754 /* 755 * Nothing special; the underlying kind and the given encoding 756 * information are the same. 757 */ 758 under_kind = encode_kind; 759 } 760 761 /* XXX is this the right set of bits to test here? */ 762 PORT_Assert ((under_kind & (SEC_ASN1_EXPLICIT 763 | SEC_ASN1_MAY_STREAM 764 | SEC_ASN1_INLINE | SEC_ASN1_POINTER)) == 0); 765 766 if (encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) { 767 PORT_Assert (encode_kind == under_kind); 768 if (encode_kind & SEC_ASN1_SKIP) { 769 PORT_Assert (!optional); 770 PORT_Assert (encode_kind == SEC_ASN1_SKIP); 771 state->dest = NULL; 772 } 773 check_tag_mask = 0; 774 expect_tag_modifiers = 0; 775 expect_tag_number = 0; 776 } else { 777 check_tag_mask = SEC_ASN1_TAG_MASK; 778 expect_tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK 779 & ~SEC_ASN1_TAGNUM_MASK; 780 /* 781 * XXX This assumes only single-octet identifiers. To handle 782 * the HIGH TAG form we would need to do some more work, especially 783 * in how to specify them in the template, because right now we 784 * do not provide a way to specify more *tag* bits in encode_kind. 785 */ 786 expect_tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK; 787 788 switch (under_kind & SEC_ASN1_TAGNUM_MASK) { 789 case SEC_ASN1_SET: 790 /* 791 * XXX A plain old SET (as opposed to a SET OF) is not 792 * implemented. 793 * If it ever is, remove this assert... 794 */ 795 PORT_Assert ((under_kind & SEC_ASN1_GROUP) != 0); 796 /* fallthru */ 797 case SEC_ASN1_SEQUENCE: 798 expect_tag_modifiers |= SEC_ASN1_CONSTRUCTED; 799 break; 800 case SEC_ASN1_BIT_STRING: 801 case SEC_ASN1_BMP_STRING: 802 case SEC_ASN1_GENERALIZED_TIME: 803 case SEC_ASN1_IA5_STRING: 804 case SEC_ASN1_OCTET_STRING: 805 case SEC_ASN1_PRINTABLE_STRING: 806 case SEC_ASN1_T61_STRING: 807 case SEC_ASN1_UNIVERSAL_STRING: 808 case SEC_ASN1_UTC_TIME: 809 case SEC_ASN1_UTF8_STRING: 810 case SEC_ASN1_VISIBLE_STRING: 811 check_tag_mask &= ~SEC_ASN1_CONSTRUCTED; 812 break; 813 } 814 } 815 816 state->check_tag_mask = check_tag_mask; 817 state->expect_tag_modifiers = expect_tag_modifiers; 818 state->expect_tag_number = expect_tag_number; 819 state->underlying_kind = under_kind; 820 state->explicit = explicit; 821 state->optional = optional; 822 sec_asn1d_scrub_state (state); 823 824 return state; 825} 826 827 828static unsigned long 829sec_asn1d_parse_identifier (sec_asn1d_state *state, 830 const char *buf, unsigned long len) 831{ 832 unsigned char byte; 833 unsigned char tag_number; 834 835 PORT_Assert (state->place == beforeIdentifier); 836 837 if (len == 0) { 838 state->top->status = needBytes; 839 return 0; 840 } 841 842 byte = (unsigned char) *buf; 843#ifdef DEBUG_ASN1D_STATES 844 if (doDumpStates > 0) { 845 char kindBuf[256]; 846 formatKind(byte, kindBuf); 847 printf("Found tag %02x %s\n", byte, kindBuf); 848 } 849#endif 850 tag_number = byte & SEC_ASN1_TAGNUM_MASK; 851 852 if (IS_HIGH_TAG_NUMBER (tag_number)) { 853 state->place = duringIdentifier; 854 state->found_tag_number = 0; 855 /* 856 * Actually, we have no idea how many bytes are pending, but we 857 * do know that it is at least 1. That is all we know; we have 858 * to look at each byte to know if there is another, etc. 859 */ 860 state->pending = 1; 861 } else { 862 if (byte == 0 && sec_asn1d_parent_allows_EOC(state)) { 863 /* 864 * Our parent has indefinite-length encoding, and the 865 * entire tag found is 0, so it seems that we have hit the 866 * end-of-contents octets. To handle this, we just change 867 * our state to that which expects to get the bytes of the 868 * end-of-contents octets and let that code re-read this byte 869 * so that our categorization of field types is correct. 870 * After that, our parent will then deal with everything else. 871 */ 872 state->place = duringEndOfContents; 873 state->pending = 2; 874 state->found_tag_number = 0; 875 state->found_tag_modifiers = 0; 876 /* 877 * We might be an optional field that is, as we now find out, 878 * missing. Give our parent a clue that this happened. 879 */ 880 if (state->optional) 881 state->missing = PR_TRUE; 882 return 0; 883 } 884 state->place = afterIdentifier; 885 state->found_tag_number = tag_number; 886 } 887 state->found_tag_modifiers = byte & ~SEC_ASN1_TAGNUM_MASK; 888 889 return 1; 890} 891 892 893static unsigned long 894sec_asn1d_parse_more_identifier (sec_asn1d_state *state, 895 const char *buf, unsigned long len) 896{ 897 unsigned char byte; 898 int count; 899 900 PORT_Assert (state->pending == 1); 901 PORT_Assert (state->place == duringIdentifier); 902 903 if (len == 0) { 904 state->top->status = needBytes; 905 return 0; 906 } 907 908 count = 0; 909 910 while (len && state->pending) { 911 if (HIGH_BITS (state->found_tag_number, TAG_NUMBER_BITS) != 0) { 912 /* 913 * The given high tag number overflows our container; 914 * just give up. This is not likely to *ever* happen. 915 */ 916 PORT_SetError (SEC_ERROR_BAD_DER); 917 state->top->status = decodeError; 918 dprintf("decodeError: parse_more_id high bits oflow\n"); 919 return 0; 920 } 921 922 state->found_tag_number <<= TAG_NUMBER_BITS; 923 924 byte = (unsigned char) buf[count++]; 925 state->found_tag_number |= (byte & TAG_NUMBER_MASK); 926 927 len--; 928 if (LAST_TAG_NUMBER_BYTE (byte)) 929 state->pending = 0; 930 } 931 932 if (state->pending == 0) 933 state->place = afterIdentifier; 934 935 return count; 936} 937 938 939static void 940sec_asn1d_confirm_identifier (sec_asn1d_state *state) 941{ 942 PRBool match; 943 944 PORT_Assert (state->place == afterIdentifier); 945 946 match = (PRBool)(((state->found_tag_modifiers & state->check_tag_mask) 947 == state->expect_tag_modifiers) 948 && ((state->found_tag_number & state->check_tag_mask) 949 == state->expect_tag_number)); 950 if (match) { 951 state->place = beforeLength; 952 } else { 953 if (state->optional) { 954 state->missing = PR_TRUE; 955 state->place = afterEndOfContents; 956 } else { 957 PORT_SetError (SEC_ERROR_BAD_DER); 958 state->top->status = decodeError; 959 //dprintf("decodeError: sec_asn1d_confirm_identifier\n"); 960 } 961 } 962} 963 964 965static unsigned long 966sec_asn1d_parse_length (sec_asn1d_state *state, 967 const char *buf, unsigned long len) 968{ 969 unsigned char byte; 970 971 PORT_Assert (state->place == beforeLength); 972 973 if (len == 0) { 974 state->top->status = needBytes; 975 return 0; 976 } 977 978 /* 979 * The default/likely outcome. It may get adjusted below. 980 */ 981 state->place = afterLength; 982 983 byte = (unsigned char) *buf; 984 985 if (LENGTH_IS_SHORT_FORM (byte)) { 986 state->contents_length = byte; 987 } else { 988 state->contents_length = 0; 989 state->pending = LONG_FORM_LENGTH (byte); 990 if (state->pending == 0) { 991 state->indefinite = PR_TRUE; 992 } else { 993 state->place = duringLength; 994 } 995 } 996 997 /* If we're parsing an ANY, SKIP, or SAVE template, and 998 ** the object being saved is definite length encoded and constructed, 999 ** there's no point in decoding that construct's members. 1000 ** So, just forget it's constructed and treat it as primitive. 1001 ** (SAVE appears as an ANY at this point) 1002 */ 1003 if (!state->indefinite && 1004 (state->underlying_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP))) { 1005 state->found_tag_modifiers &= ~SEC_ASN1_CONSTRUCTED; 1006 } 1007 1008 return 1; 1009} 1010 1011 1012static unsigned long 1013sec_asn1d_parse_more_length (sec_asn1d_state *state, 1014 const char *buf, unsigned long len) 1015{ 1016 int count; 1017 1018 PORT_Assert (state->pending > 0); 1019 PORT_Assert (state->place == duringLength); 1020 1021 if (len == 0) { 1022 state->top->status = needBytes; 1023 return 0; 1024 } 1025 1026 count = 0; 1027 1028 while (len && state->pending) { 1029 if (HIGH_BITS (state->contents_length, 9) != 0) { 1030 /* 1031 * The given full content length overflows our container; 1032 * just give up. 1033 */ 1034 PORT_SetError (SEC_ERROR_BAD_DER); 1035 state->top->status = decodeError; 1036 dprintf("decodeError: sec_asn1d_parse_more_length\n"); 1037 return 0; 1038 } 1039 1040 state->contents_length <<= 8; 1041 state->contents_length |= (unsigned char) buf[count++]; 1042 1043 len--; 1044 state->pending--; 1045 } 1046 1047 if (state->pending == 0) 1048 state->place = afterLength; 1049 1050 return count; 1051} 1052 1053 1054static void 1055sec_asn1d_prepare_for_contents (sec_asn1d_state *state, 1056 #ifdef __APPLE__ 1057 const char *buf /* needed for SEC_ASN1GetSubtemplate */ 1058 #endif 1059 ) 1060{ 1061 SecAsn1Item *item; 1062 PRArenaPool *poolp; 1063 unsigned long alloc_len; 1064 1065#ifdef DEBUG_ASN1D_STATES 1066 if (doDumpStates > 0) { 1067 printf("Found Length %lu %s\n", state->contents_length, 1068 state->indefinite ? "indefinite" : ""); 1069 } 1070#endif 1071 1072 /* 1073 * XXX I cannot decide if this allocation should exclude the case 1074 * where state->endofcontents is true -- figure it out! 1075 */ 1076 if (state->allocate) { 1077 void *dest; 1078 1079 PORT_Assert (state->dest == NULL); 1080 /* 1081 * We are handling a POINTER or a member of a GROUP, and need to 1082 * allocate for the data structure. 1083 */ 1084 dest = sec_asn1d_zalloc (state->top->their_pool, 1085 state->theTemplate->size); 1086 if (dest == NULL) { 1087 dprintf("decodeError: sec_asn1d_prepare_for_contents zalloc\n"); 1088 state->top->status = decodeError; 1089 return; 1090 } 1091 /* FIXME _ we're losing the dest pointer after this! */ 1092 state->dest = (char *)dest + state->theTemplate->offset; 1093 1094 /* 1095 * For a member of a GROUP, our parent will later put the 1096 * pointer wherever it belongs. But for a POINTER, we need 1097 * to record the destination now, in case notify or filter 1098 * procs need access to it -- they cannot find it otherwise, 1099 * until it is too late (for one-pass processing). 1100 */ 1101 if (state->parent->place == afterPointer) { 1102 void **placep; 1103 1104 placep = state->parent->dest; 1105 *placep = dest; 1106 } 1107 } 1108 1109 /* 1110 * Remember, length may be indefinite here! In that case, 1111 * both contents_length and pending will be zero. 1112 */ 1113 state->pending = state->contents_length; 1114 1115 /* If this item has definite length encoding, and 1116 ** is enclosed by a definite length constructed type, 1117 ** make sure it isn't longer than the remaining space in that 1118 ** constructed type. 1119 */ 1120 if (state->contents_length > 0) { 1121 sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(state); 1122 if (parent && !parent->indefinite && 1123 state->consumed + state->contents_length > parent->pending) { 1124 PORT_SetError (SEC_ERROR_BAD_DER); 1125 state->top->status = decodeError; 1126 return; 1127 } 1128 } 1129 1130 /* 1131 * An EXPLICIT is nothing but an outer header, which we have 1132 * already parsed and accepted. Now we need to do the inner 1133 * header and its contents. 1134 */ 1135 if (state->explicit) { 1136 state->place = afterExplicit; 1137 state = sec_asn1d_push_state (state->top, 1138 SEC_ASN1GetSubtemplate(state->theTemplate, 1139 state->dest, 1140 PR_FALSE, 1141 buf /* __APPLE__ */), 1142 state->dest, PR_TRUE); 1143 if (state != NULL) 1144 state = sec_asn1d_init_state_based_on_template (state, 1145 buf /* __APPLE__ */); 1146 return; 1147 } 1148 1149 /* 1150 * For GROUP (SET OF, SEQUENCE OF), even if we know the length here 1151 * we cannot tell how many items we will end up with ... so push a 1152 * state that can keep track of "children" (the individual members 1153 * of the group; we will allocate as we go and put them all together 1154 * at the end. 1155 */ 1156 if (state->underlying_kind & SEC_ASN1_GROUP) { 1157 /* XXX If this assertion holds (should be able to confirm it via 1158 * inspection, too) then move this code into the switch statement 1159 * below under cases SET_OF and SEQUENCE_OF; it will be cleaner. 1160 */ 1161 PORT_Assert (state->underlying_kind == SEC_ASN1_SET_OF 1162 || state->underlying_kind == SEC_ASN1_SEQUENCE_OF 1163 || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC) 1164 || state->underlying_kind == (SEC_ASN1_SET_OF|SEC_ASN1_DYNAMIC) 1165 ); 1166 if (state->contents_length != 0 || state->indefinite) { 1167 const SecAsn1Template *subt; 1168 1169 state->place = duringGroup; 1170 subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->dest, 1171 PR_FALSE, buf /* __APPLE__ */); 1172 state = sec_asn1d_push_state (state->top, subt, NULL, PR_TRUE); 1173 if (state != NULL) { 1174 if (!state->top->filter_only) 1175 state->allocate = PR_TRUE; /* XXX propogate this? */ 1176 /* 1177 * Do the "before" field notification for next in group. 1178 */ 1179 sec_asn1d_notify_before (state->top, state->dest, state->depth); 1180 state = sec_asn1d_init_state_based_on_template (state, 1181 buf /* __APPLE__ */); 1182 } 1183 } else { 1184 /* 1185 * A group of zero; we are done. 1186 * Set state to afterGroup and let that code plant the NULL. 1187 */ 1188 state->place = afterGroup; 1189 } 1190 return; 1191 } 1192 1193 switch (state->underlying_kind) { 1194 case SEC_ASN1_SEQUENCE: 1195 /* 1196 * We need to push a child to handle the individual fields. 1197 */ 1198 state->place = duringSequence; 1199 state = sec_asn1d_push_state (state->top, state->theTemplate + 1, 1200 state->dest, PR_TRUE); 1201 if (state != NULL) { 1202 /* 1203 * Do the "before" field notification. 1204 */ 1205 sec_asn1d_notify_before (state->top, state->dest, state->depth); 1206 state = sec_asn1d_init_state_based_on_template (state, 1207 buf /* __APPLE__ */); 1208 } 1209 break; 1210 1211 case SEC_ASN1_SET: /* XXX SET is not really implemented */ 1212 /* 1213 * XXX A plain SET requires special handling; scanning of a 1214 * template to see where a field should go (because by definition, 1215 * they are not in any particular order, and you have to look at 1216 * each tag to disambiguate what the field is). We may never 1217 * implement this because in practice, it seems to be unused. 1218 */ 1219 dprintf("decodeError: prepare for contents SEC_ASN1_SET\n"); 1220 PORT_Assert(0); 1221 PORT_SetError (SEC_ERROR_BAD_DER); /* XXX */ 1222 state->top->status = decodeError; 1223 break; 1224 1225 case SEC_ASN1_NULL: 1226 /* 1227 * The NULL type, by definition, is "nothing", content length of zero. 1228 * An indefinite-length encoding is not alloweed. 1229 */ 1230 if (state->contents_length || state->indefinite) { 1231 dprintf("decodeError: prepare for contents indefinite NULL\n"); 1232 PORT_SetError (SEC_ERROR_BAD_DER); 1233 state->top->status = decodeError; 1234 break; 1235 } 1236 if (state->dest != NULL) { 1237 item = (SecAsn1Item *)(state->dest); 1238 item->Data = NULL; 1239 item->Length = 0; 1240 } 1241 state->place = afterEndOfContents; 1242 break; 1243 1244 case SEC_ASN1_BMP_STRING: 1245 /* Error if length is not divisable by 2 */ 1246 if (state->contents_length % 2) { 1247 dprintf("decodeError: prepare for contents odd length BMP_STRING\n"); 1248 PORT_SetError (SEC_ERROR_BAD_DER); 1249 state->top->status = decodeError; 1250 break; 1251 } 1252 /* otherwise, handle as other string types */ 1253 goto regular_string_type; 1254 1255 case SEC_ASN1_UNIVERSAL_STRING: 1256 /* Error if length is not divisable by 4 */ 1257 if (state->contents_length % 4) { 1258 dprintf("decodeError: prepare for contents odd length UNIV_STRING\n"); 1259 PORT_SetError (SEC_ERROR_BAD_DER); 1260 state->top->status = decodeError; 1261 break; 1262 } 1263 /* otherwise, handle as other string types */ 1264 goto regular_string_type; 1265 1266 case SEC_ASN1_SKIP: 1267 case SEC_ASN1_ANY: 1268 case SEC_ASN1_ANY_CONTENTS: 1269 /* 1270 * These are not (necessarily) strings, but they need nearly 1271 * identical handling (especially when we need to deal with 1272 * constructed sub-pieces), so we pretend they are. 1273 */ 1274 /* fallthru */ 1275regular_string_type: 1276 case SEC_ASN1_BIT_STRING: 1277 case SEC_ASN1_IA5_STRING: 1278 case SEC_ASN1_OCTET_STRING: 1279 case SEC_ASN1_PRINTABLE_STRING: 1280 case SEC_ASN1_T61_STRING: 1281 case SEC_ASN1_UTC_TIME: 1282 case SEC_ASN1_UTF8_STRING: 1283 case SEC_ASN1_VISIBLE_STRING: 1284 /* 1285 * We are allocating for a primitive or a constructed string. 1286 * If it is a constructed string, it may also be indefinite-length. 1287 * If it is primitive, the length can (legally) be zero. 1288 * Our first order of business is to allocate the memory for 1289 * the string, if we can (if we know the length). 1290 */ 1291 item = (SecAsn1Item *)(state->dest); 1292 1293 /* 1294 * If the item is a definite-length constructed string, then 1295 * the contents_length is actually larger than what we need 1296 * (because it also counts each intermediate header which we 1297 * will be throwing away as we go), but it is a perfectly good 1298 * upper bound that we just allocate anyway, and then concat 1299 * as we go; we end up wasting a few extra bytes but save a 1300 * whole other copy. 1301 */ 1302 alloc_len = state->contents_length; 1303 poolp = NULL; /* quiet compiler warnings about unused... */ 1304 1305 if (item == NULL || state->top->filter_only) { 1306 if (item != NULL) { 1307 item->Data = NULL; 1308 item->Length = 0; 1309 } 1310 alloc_len = 0; 1311 } else if (state->substring) { 1312 /* 1313 * If we are a substring of a constructed string, then we may 1314 * not have to allocate anything (because our parent, the 1315 * actual constructed string, did it for us). If we are a 1316 * substring and we *do* have to allocate, that means our 1317 * parent is an indefinite-length, so we allocate from our pool; 1318 * later our parent will copy our string into the aggregated 1319 * whole and free our pool allocation. 1320 */ 1321 if (item->Data == NULL) { 1322 PORT_Assert (item->Length == 0); 1323 poolp = state->top->our_pool; 1324 } else { 1325 alloc_len = 0; 1326 } 1327 } else { 1328 item->Length = 0; 1329 item->Data = NULL; 1330 poolp = state->top->their_pool; 1331 } 1332 1333 if (alloc_len || ((! state->indefinite) 1334 && (state->subitems_head != NULL))) { 1335 struct subitem *subitem; 1336 unsigned long len; 1337 1338 PORT_Assert (item != NULL && item->Length == 0 && item->Data == NULL); 1339 /* 1340 * Check for and handle an ANY which has stashed aside the 1341 * header (identifier and length) bytes for us to include 1342 * in the saved contents. 1343 */ 1344 if (state->subitems_head != NULL) { 1345 PORT_Assert (state->underlying_kind == SEC_ASN1_ANY); 1346 for (subitem = state->subitems_head; 1347 subitem != NULL; subitem = subitem->next) 1348 alloc_len += subitem->len; 1349 } 1350 1351 item->Data = (unsigned char*)sec_asn1d_zalloc (poolp, alloc_len); 1352 if (item->Data == NULL) { 1353 dprintf("decodeError: prepare for contents zalloc\n"); 1354 state->top->status = decodeError; 1355 break; 1356 } 1357 1358 len = 0; 1359 for (subitem = state->subitems_head; 1360 subitem != NULL; subitem = subitem->next) { 1361 PORT_Memcpy (item->Data + len, subitem->data, subitem->len); 1362 len += subitem->len; 1363 } 1364 item->Length = len; 1365 1366 /* 1367 * Because we use arenas and have a mark set, we later free 1368 * everything we have allocated, so this does *not* present 1369 * a memory leak (it is just temporarily left dangling). 1370 */ 1371 state->subitems_head = state->subitems_tail = NULL; 1372 } 1373 1374 if (state->contents_length == 0 && (! state->indefinite)) { 1375 /* 1376 * A zero-length simple or constructed string; we are done. 1377 */ 1378 state->place = afterEndOfContents; 1379 } else if (state->found_tag_modifiers & SEC_ASN1_CONSTRUCTED) { 1380 const SecAsn1Template *sub; 1381 1382 switch (state->underlying_kind) { 1383 case SEC_ASN1_ANY: 1384 case SEC_ASN1_ANY_CONTENTS: 1385 sub = kSecAsn1AnyTemplate; 1386 break; 1387 case SEC_ASN1_BIT_STRING: 1388 sub = kSecAsn1BitStringTemplate; 1389 break; 1390 case SEC_ASN1_BMP_STRING: 1391 sub = kSecAsn1BMPStringTemplate; 1392 break; 1393 case SEC_ASN1_GENERALIZED_TIME: 1394 sub = kSecAsn1GeneralizedTimeTemplate; 1395 break; 1396 case SEC_ASN1_IA5_STRING: 1397 sub = kSecAsn1IA5StringTemplate; 1398 break; 1399 case SEC_ASN1_OCTET_STRING: 1400 sub = kSecAsn1OctetStringTemplate; 1401 break; 1402 case SEC_ASN1_PRINTABLE_STRING: 1403 sub = kSecAsn1PrintableStringTemplate; 1404 break; 1405 case SEC_ASN1_T61_STRING: 1406 sub = kSecAsn1T61StringTemplate; 1407 break; 1408 case SEC_ASN1_UNIVERSAL_STRING: 1409 sub = kSecAsn1UniversalStringTemplate; 1410 break; 1411 case SEC_ASN1_UTC_TIME: 1412 sub = kSecAsn1UTCTimeTemplate; 1413 break; 1414 case SEC_ASN1_UTF8_STRING: 1415 sub = kSecAsn1UTF8StringTemplate; 1416 break; 1417 case SEC_ASN1_VISIBLE_STRING: 1418 sub = kSecAsn1VisibleStringTemplate; 1419 break; 1420 case SEC_ASN1_SKIP: 1421 sub = kSecAsn1SkipTemplate; 1422 break; 1423 default: /* redundant given outer switch cases, but */ 1424 PORT_Assert(0); /* the compiler does not seem to know that, */ 1425 sub = NULL; /* so just do enough to quiet it. */ 1426 break; 1427 } 1428 1429 state->place = duringConstructedString; 1430 state = sec_asn1d_push_state (state->top, sub, item, PR_TRUE); 1431 if (state != NULL) { 1432 state->substring = PR_TRUE; /* XXX propogate? */ 1433 state = sec_asn1d_init_state_based_on_template (state, 1434 buf /* __APPLE__ */); 1435 } 1436 } else if (state->indefinite) { 1437 /* 1438 * An indefinite-length string *must* be constructed! 1439 */ 1440 dprintf("decodeError: prepare for contents indefinite not construncted\n"); 1441 PORT_SetError (SEC_ERROR_BAD_DER); 1442 state->top->status = decodeError; 1443 } else { 1444 /* 1445 * A non-zero-length simple string. 1446 */ 1447 if (state->underlying_kind == SEC_ASN1_BIT_STRING) 1448 state->place = beforeBitString; 1449 else 1450 state->place = duringLeaf; 1451 } 1452 break; 1453 1454 default: 1455 /* 1456 * We are allocating for a simple leaf item. 1457 */ 1458 if (state->contents_length) { 1459 if (state->dest != NULL) { 1460 item = (SecAsn1Item *)(state->dest); 1461 item->Length = 0; 1462 if (state->top->filter_only) { 1463 item->Data = NULL; 1464 } else { 1465 item->Data = (unsigned char*) 1466 sec_asn1d_zalloc (state->top->their_pool, 1467 state->contents_length); 1468 if (item->Data == NULL) { 1469 dprintf("decodeError: prepare for contents zalloc\n"); 1470 state->top->status = decodeError; 1471 return; 1472 } 1473 } 1474 } 1475 state->place = duringLeaf; 1476 } else { 1477 /* 1478 * An indefinite-length or zero-length item is not allowed. 1479 * (All legal cases of such were handled above.) 1480 */ 1481 dprintf("decodeError: prepare for contents indefinite zero len \n"); 1482 PORT_SetError (SEC_ERROR_BAD_DER); 1483 state->top->status = decodeError; 1484 } 1485 } 1486} 1487 1488 1489static void 1490sec_asn1d_free_child (sec_asn1d_state *state, PRBool error) 1491{ 1492 if (state->child != NULL) { 1493 PORT_Assert (error || state->child->consumed == 0); 1494 PORT_Assert (state->our_mark != NULL); 1495 PORT_ArenaRelease (state->top->our_pool, state->our_mark); 1496 if (error && state->top->their_pool == NULL) { 1497 /* 1498 * XXX We need to free anything allocated. 1499 * At this point, we failed in the middle of decoding. But we 1500 * can't free the data we previously allocated with PR_Malloc 1501 * unless we keep track of every pointer. So instead we have a 1502 * memory leak when decoding fails half-way, unless an arena is 1503 * used. See bug 95311 . 1504 */ 1505 } 1506 state->child = NULL; 1507 state->our_mark = NULL; 1508 } else { 1509 /* 1510 * It is important that we do not leave a mark unreleased/unmarked. 1511 * But I do not think we should ever have one set in this case, only 1512 * if we had a child (handled above). So check for that. If this 1513 * assertion should ever get hit, then we probably need to add code 1514 * here to release back to our_mark (and then set our_mark to NULL). 1515 */ 1516 PORT_Assert (state->our_mark == NULL); 1517 } 1518 state->place = beforeEndOfContents; 1519} 1520 1521 1522/* We have just saved an entire encoded ASN.1 object (type) for a SAVE 1523** template, and now in the next template, we are going to decode that 1524** saved data by calling SEC_ASN1DecoderUpdate recursively. 1525** If that recursive call fails with needBytes, it is a fatal error, 1526** because the encoded object should have been complete. 1527** If that recursive call fails with decodeError, it will have already 1528** cleaned up the state stack, so we must bail out quickly. 1529** 1530** These checks of the status returned by the recursive call are now 1531** done in the caller of this function, immediately after it returns. 1532*/ 1533static void 1534sec_asn1d_reuse_encoding (sec_asn1d_state *state) 1535{ 1536 sec_asn1d_state *child; 1537 unsigned long consumed; 1538 SecAsn1Item *item; 1539 void *dest; 1540 1541 1542 child = state->child; 1543 PORT_Assert (child != NULL); 1544 1545 consumed = child->consumed; 1546 child->consumed = 0; 1547 1548 item = (SecAsn1Item *)(state->dest); 1549 PORT_Assert (item != NULL); 1550 1551 PORT_Assert (item->Length == consumed); 1552 1553 /* 1554 * Free any grandchild. 1555 */ 1556 sec_asn1d_free_child (child, PR_FALSE); 1557 1558 /* 1559 * Notify after the SAVE field. 1560 */ 1561 sec_asn1d_notify_after (state->top, state->dest, state->depth); 1562 1563 /* 1564 * Adjust to get new dest and move forward. 1565 */ 1566 dest = (char *)state->dest - state->theTemplate->offset; 1567 state->theTemplate++; 1568 child->dest = (char *)dest + state->theTemplate->offset; 1569 child->theTemplate = state->theTemplate; 1570 1571 /* 1572 * Notify before the "real" field. 1573 */ 1574 PORT_Assert (state->depth == child->depth); 1575 sec_asn1d_notify_before (state->top, child->dest, child->depth); 1576 1577 /* 1578 * This will tell DecoderUpdate to return when it is done. 1579 */ 1580 state->place = afterSaveEncoding; 1581 1582 /* 1583 * We already have a child; "push" it by making it current. 1584 */ 1585 state->top->current = child; 1586 1587 /* 1588 * And initialize it so it is ready to parse. 1589 */ 1590 (void) sec_asn1d_init_state_based_on_template(child, 1591 (char *) item->Data /* __APPLE__ */); 1592 1593 /* 1594 * Now parse that out of our data. 1595 */ 1596 if (SEC_ASN1DecoderUpdate (state->top, 1597 (char *) item->Data, item->Length) != SECSuccess) 1598 return; 1599 if (state->top->status == needBytes) { 1600 return; 1601 } 1602 1603 PORT_Assert (state->top->current == state); 1604 PORT_Assert (state->child == child); 1605 1606 /* 1607 * That should have consumed what we consumed before. 1608 */ 1609 PORT_Assert (consumed == child->consumed); 1610 child->consumed = 0; 1611 1612 /* 1613 * Done. 1614 */ 1615 state->consumed += consumed; 1616 child->place = notInUse; 1617 state->place = afterEndOfContents; 1618} 1619 1620 1621static unsigned long 1622sec_asn1d_parse_leaf (sec_asn1d_state *state, 1623 const char *buf, unsigned long len) 1624{ 1625 SecAsn1Item *item; 1626 unsigned long bufLen; 1627 1628 if (len == 0) { 1629 state->top->status = needBytes; 1630 return 0; 1631 } 1632 1633 if (state->pending < len) 1634 len = state->pending; 1635 1636 bufLen = len; 1637 1638 item = (SecAsn1Item *)(state->dest); 1639 if (item != NULL && item->Data != NULL) { 1640 /* Strip leading zeroes when target is unsigned integer */ 1641 if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */ 1642 item->Length == 0 && /* MSB */ 1643 #ifdef __APPLE__ 1644 !(state->underlying_kind & SEC_ASN1_SIGNED_INT)) 1645 #else 1646 item->type == siUnsignedInteger) /* unsigned */ 1647 #endif 1648 { 1649 while (len > 1 && buf[0] == 0) { /* leading 0 */ 1650 buf++; 1651 len--; 1652 } 1653 } 1654 PORT_Memcpy (item->Data + item->Length, buf, len); 1655 item->Length += len; 1656 } 1657 state->pending -= bufLen; 1658 if (state->pending == 0) 1659 state->place = beforeEndOfContents; 1660 1661 return bufLen; 1662} 1663 1664 1665static unsigned long 1666sec_asn1d_parse_bit_string (sec_asn1d_state *state, 1667 const char *buf, unsigned long len) 1668{ 1669 unsigned char byte; 1670 1671 /*PORT_Assert (state->pending > 0); */ 1672 PORT_Assert (state->place == beforeBitString); 1673 1674 if ((state->pending == 0) || (state->contents_length == 1)) { 1675 if (state->dest != NULL) { 1676 SecAsn1Item *item = (SecAsn1Item *)(state->dest); 1677 item->Data = NULL; 1678 item->Length = 0; 1679 state->place = beforeEndOfContents; 1680 } 1681 if(state->contents_length == 1) { 1682 /* skip over (unused) remainder byte */ 1683 return 1; 1684 } 1685 else { 1686 return 0; 1687 } 1688 } 1689 1690 if (len == 0) { 1691 state->top->status = needBytes; 1692 return 0; 1693 } 1694 1695 byte = (unsigned char) *buf; 1696 if (byte > 7) { 1697 dprintf("decodeError: parse_bit_string remainder oflow\n"); 1698 PORT_SetError (SEC_ERROR_BAD_DER); 1699 state->top->status = decodeError; 1700 return 0; 1701 } 1702 1703 state->bit_string_unused_bits = byte; 1704 state->place = duringBitString; 1705 state->pending -= 1; 1706 1707 return 1; 1708} 1709 1710 1711static unsigned long 1712sec_asn1d_parse_more_bit_string (sec_asn1d_state *state, 1713 const char *buf, unsigned long len) 1714{ 1715 PORT_Assert (state->place == duringBitString); 1716 if (state->pending == 0) { 1717 /* An empty bit string with some unused bits is invalid. */ 1718 if (state->bit_string_unused_bits) { 1719 PORT_SetError (SEC_ERROR_BAD_DER); 1720 state->top->status = decodeError; 1721 } else { 1722 /* An empty bit string with no unused bits is OK. */ 1723 state->place = beforeEndOfContents; 1724 } 1725 return 0; 1726 } 1727 1728 len = sec_asn1d_parse_leaf (state, buf, len); 1729 if (state->place == beforeEndOfContents && state->dest != NULL) { 1730 SecAsn1Item *item; 1731 1732 item = (SecAsn1Item *)(state->dest); 1733 if (item->Length) 1734 item->Length = (item->Length << 3) - state->bit_string_unused_bits; 1735 } 1736 1737 return len; 1738} 1739 1740 1741/* 1742 * XXX All callers should be looking at return value to detect 1743 * out-of-memory errors (and stop!). 1744 */ 1745static struct subitem * 1746sec_asn1d_add_to_subitems (sec_asn1d_state *state, 1747 const void *data, unsigned long len, 1748 PRBool copy_data) 1749{ 1750 struct subitem *thing; 1751 1752 thing = (struct subitem*)sec_asn1d_zalloc (state->top->our_pool, 1753 sizeof (struct subitem)); 1754 if (thing == NULL) { 1755 dprintf("decodeError: zalloc\n"); 1756 state->top->status = decodeError; 1757 return NULL; 1758 } 1759 1760 if (copy_data) { 1761 void *copy; 1762 copy = sec_asn1d_alloc (state->top->our_pool, len); 1763 if (copy == NULL) { 1764 dprintf("decodeError: alloc\n"); 1765 state->top->status = decodeError; 1766 return NULL; 1767 } 1768 PORT_Memcpy (copy, data, len); 1769 thing->data = copy; 1770 } else { 1771 thing->data = data; 1772 } 1773 thing->len = len; 1774 thing->next = NULL; 1775 1776 if (state->subitems_head == NULL) { 1777 PORT_Assert (state->subitems_tail == NULL); 1778 state->subitems_head = state->subitems_tail = thing; 1779 } else { 1780 state->subitems_tail->next = thing; 1781 state->subitems_tail = thing; 1782 } 1783 1784 return thing; 1785} 1786 1787 1788static void 1789sec_asn1d_record_any_header (sec_asn1d_state *state, 1790 const char *buf, 1791 unsigned long len) 1792{ 1793 SecAsn1Item *item; 1794 1795 item = (SecAsn1Item *)(state->dest); 1796 if (item != NULL && item->Data != NULL) { 1797 PORT_Assert (state->substring); 1798 PORT_Memcpy (item->Data + item->Length, buf, len); 1799 item->Length += len; 1800 } else { 1801 sec_asn1d_add_to_subitems (state, buf, len, PR_TRUE); 1802 } 1803} 1804 1805 1806/* 1807 * We are moving along through the substrings of a constructed string, 1808 * and have just finished parsing one -- we need to save our child data 1809 * (if the child was not already writing directly into the destination) 1810 * and then move forward by one. 1811 * 1812 * We also have to detect when we are done: 1813 * - a definite-length encoding stops when our pending value hits 0 1814 * - an indefinite-length encoding stops when our child is empty 1815 * (which means it was the end-of-contents octets) 1816 */ 1817static void 1818sec_asn1d_next_substring (sec_asn1d_state *state) 1819{ 1820 sec_asn1d_state *child; 1821 SecAsn1Item *item; 1822 unsigned long child_consumed; 1823 PRBool done; 1824 1825 PORT_Assert (state->place == duringConstructedString); 1826 PORT_Assert (state->child != NULL); 1827 1828 child = state->child; 1829 1830 child_consumed = child->consumed; 1831 child->consumed = 0; 1832 state->consumed += child_consumed; 1833 1834 done = PR_FALSE; 1835 1836 if (state->pending) { 1837 PORT_Assert (!state->indefinite); 1838 if( child_consumed > state->pending ) { 1839 dprintf("decodeError: next_substring consumed > pend\n"); 1840 PORT_SetError (SEC_ERROR_BAD_DER); 1841 state->top->status = decodeError; 1842 return; 1843 } 1844 1845 state->pending -= child_consumed; 1846 if (state->pending == 0) 1847 done = PR_TRUE; 1848 } else { 1849 PORT_Assert (state->indefinite); 1850 1851 item = (SecAsn1Item *)(child->dest); 1852 if (item != NULL && item->Data != NULL) { 1853 /* 1854 * Save the string away for later concatenation. 1855 */ 1856 PORT_Assert (item->Data != NULL); 1857 sec_asn1d_add_to_subitems (state, item->Data, item->Length, PR_FALSE); 1858 /* 1859 * Clear the child item for the next round. 1860 */ 1861 item->Data = NULL; 1862 item->Length = 0; 1863 } 1864 1865 /* 1866 * If our child was just our end-of-contents octets, we are done. 1867 */ 1868 if (child->endofcontents) 1869 done = PR_TRUE; 1870 } 1871 1872 /* 1873 * Stop or do the next one. 1874 */ 1875 if (done) { 1876 child->place = notInUse; 1877 state->place = afterConstructedString; 1878 } else { 1879 sec_asn1d_scrub_state (child); 1880 state->top->current = child; 1881 } 1882} 1883 1884 1885/* 1886 * We are doing a SET OF or SEQUENCE OF, and have just finished an item. 1887 */ 1888static void 1889sec_asn1d_next_in_group (sec_asn1d_state *state, 1890 const char *buf /* __APPLE__ */) 1891{ 1892 sec_asn1d_state *child; 1893 unsigned long child_consumed; 1894 1895 PORT_Assert (state->place == duringGroup); 1896 PORT_Assert (state->child != NULL); 1897 1898 child = state->child; 1899 1900 child_consumed = child->consumed; 1901 child->consumed = 0; 1902 state->consumed += child_consumed; 1903 1904 /* 1905 * If our child was just our end-of-contents octets, we are done. 1906 */ 1907 #ifdef __APPLE__ 1908 /* 1909 * Without the check for !child->indefinite, this path could 1910 * be taken erroneously if the child is indefinite! 1911 */ 1912 if(child->endofcontents && !child->indefinite) { 1913 #else 1914 if (child->endofcontents) { 1915 #endif /* __APPLE__ */ 1916 /* XXX I removed the PORT_Assert (child->dest == NULL) because there 1917 * was a bug in that a template that was a sequence of which also had 1918 * a child of a sequence of, in an indefinite group was not working 1919 * properly. This fix seems to work, (added the if statement below), 1920 * and nothing appears broken, but I am putting this note here just 1921 * in case. */ 1922 /* 1923 * XXX No matter how many times I read that comment, 1924 * I cannot figure out what case he was fixing. I believe what he 1925 * did was deliberate, so I am loathe to touch it. I need to 1926 * understand how it could ever be that child->dest != NULL but 1927 * child->endofcontents is true, and why it is important to check 1928 * that state->subitems_head is NULL. This really needs to be 1929 * figured out, as I am not sure if the following code should be 1930 * compensating for "offset", as is done a little farther below 1931 * in the more normal case. 1932 */ 1933 PORT_Assert (state->indefinite); 1934 PORT_Assert (state->pending == 0); 1935 if(child->dest && !state->subitems_head) { 1936 sec_asn1d_add_to_subitems (state, child->dest, 0, PR_FALSE); 1937 child->dest = NULL; 1938 } 1939 1940 child->place = notInUse; 1941 state->place = afterGroup; 1942 return; 1943 } 1944 1945 /* 1946 * Do the "after" field notification for next in group. 1947 */ 1948 sec_asn1d_notify_after (state->top, child->dest, child->depth); 1949 1950 /* 1951 * Save it away (unless we are not storing). 1952 */ 1953 if (child->dest != NULL) { 1954 void *dest; 1955 1956 dest = child->dest; 1957 dest = (char *)dest - child->theTemplate->offset; 1958 sec_asn1d_add_to_subitems (state, dest, 0, PR_FALSE); 1959 child->dest = NULL; 1960 } 1961 1962 /* 1963 * Account for those bytes; see if we are done. 1964 */ 1965 if (state->pending) { 1966 PORT_Assert (!state->indefinite); 1967 if( child_consumed > state->pending ) { 1968 dprintf("decodeError: next_in_group consumed > pend\n"); 1969 PORT_SetError (SEC_ERROR_BAD_DER); 1970 state->top->status = decodeError; 1971 return; 1972 } 1973 1974 state->pending -= child_consumed; 1975 if (state->pending == 0) { 1976 child->place = notInUse; 1977 state->place = afterGroup; 1978 return; 1979 } 1980 } 1981 1982 /* 1983 * Do the "before" field notification for next item in group. 1984 */ 1985 sec_asn1d_notify_before (state->top, child->dest, child->depth); 1986 1987 /* 1988 * Now we do the next one. 1989 */ 1990 sec_asn1d_scrub_state (child); 1991 1992 /* Initialize child state from the template */ 1993 sec_asn1d_init_state_based_on_template(child, buf /* __APPLE__ */); 1994 1995 state->top->current = child; 1996} 1997 1998 1999/* 2000 * We are moving along through a sequence; move forward by one, 2001 * (detecting end-of-sequence when it happens). 2002 * XXX The handling of "missing" is ugly. Fix it. 2003 */ 2004static void 2005sec_asn1d_next_in_sequence (sec_asn1d_state *state, 2006 const char *buf /* __APPLE__ */) 2007{ 2008 sec_asn1d_state *child; 2009 unsigned long child_consumed; 2010 PRBool child_missing; 2011 2012 PORT_Assert (state->place == duringSequence); 2013 PORT_Assert (state->child != NULL); 2014 2015 child = state->child; 2016 2017 /* 2018 * Do the "after" field notification. 2019 */ 2020 sec_asn1d_notify_after (state->top, child->dest, child->depth); 2021 2022 child_missing = (PRBool) child->missing; 2023 child_consumed = child->consumed; 2024 child->consumed = 0; 2025 2026 /* 2027 * Take care of accounting. 2028 */ 2029 if (child_missing) { 2030 PORT_Assert (child->optional); 2031 } else { 2032 state->consumed += child_consumed; 2033 /* 2034 * Free any grandchild. 2035 */ 2036 sec_asn1d_free_child (child, PR_FALSE); 2037 if (state->pending) { 2038 PORT_Assert (!state->indefinite); 2039 if( child_consumed > state->pending ) { 2040 dprintf("decodeError: next_in_seq consumed > pend\n"); 2041 PORT_SetError (SEC_ERROR_BAD_DER); 2042 state->top->status = decodeError; 2043 return; 2044 } 2045 state->pending -= child_consumed; 2046 if (state->pending == 0) { 2047 child->theTemplate++; 2048 while (child->theTemplate->kind != 0) { 2049 if ((child->theTemplate->kind & SEC_ASN1_OPTIONAL) == 0) { 2050 dprintf("decodeError: next_in_seq child not opt\n"); 2051 PORT_SetError (SEC_ERROR_BAD_DER); 2052 state->top->status = decodeError; 2053 return; 2054 } 2055 child->theTemplate++; 2056 } 2057 child->place = notInUse; 2058 state->place = afterEndOfContents; 2059 return; 2060 } 2061 } 2062 } 2063 2064 /* 2065 * Move forward. 2066 */ 2067 child->theTemplate++; 2068 if (child->theTemplate->kind == 0) { 2069 /* 2070 * We are done with this sequence. 2071 */ 2072 child->place = notInUse; 2073 if (state->pending) { 2074 dprintf("decodeError: next_in_seq notInUse still pending\n"); 2075 PORT_SetError (SEC_ERROR_BAD_DER); 2076 state->top->status = decodeError; 2077 } else if (child_missing) { 2078 /* 2079 * We got to the end, but have a child that started parsing 2080 * and ended up "missing". The only legitimate reason for 2081 * this is that we had one or more optional fields at the 2082 * end of our sequence, and we were encoded indefinite-length, 2083 * so when we went looking for those optional fields we 2084 * found our end-of-contents octets instead. 2085 * (Yes, this is ugly; dunno a better way to handle it.) 2086 * So, first confirm the situation, and then mark that we 2087 * are done. 2088 */ 2089 if (state->indefinite && child->endofcontents) { 2090 PORT_Assert (child_consumed == 2); 2091 if( child_consumed != 2 ) { 2092 dprintf("decodeError: next_in_seq indef len != 2\n"); 2093 PORT_SetError (SEC_ERROR_BAD_DER); 2094 state->top->status = decodeError; 2095 } else { 2096 state->consumed += child_consumed; 2097 state->place = afterEndOfContents; 2098 } 2099 } else { 2100 dprintf("decodeError: next_in_seq !indef, child missing\n"); 2101 PORT_SetError (SEC_ERROR_BAD_DER); 2102 state->top->status = decodeError; 2103 } 2104 } else { 2105 /* 2106 * We have to finish out, maybe reading end-of-contents octets; 2107 * let the normal logic do the right thing. 2108 */ 2109 state->place = beforeEndOfContents; 2110 } 2111 } else { 2112 unsigned char child_found_tag_modifiers = 0; 2113 unsigned long child_found_tag_number = 0; 2114 2115 /* 2116 * Reset state and push. 2117 */ 2118 if (state->dest != NULL) 2119 child->dest = (char *)state->dest + child->theTemplate->offset; 2120 2121 /* 2122 * Do the "before" field notification. 2123 */ 2124 sec_asn1d_notify_before (state->top, child->dest, child->depth); 2125 2126 if (child_missing) { /* if previous child was missing, copy the tag data we already have */ 2127 child_found_tag_modifiers = child->found_tag_modifiers; 2128 child_found_tag_number = child->found_tag_number; 2129 } 2130 state->top->current = child; 2131 child = sec_asn1d_init_state_based_on_template (child, 2132 buf /* __APPLE__ */); 2133 if (child_missing) { 2134 child->place = afterIdentifier; 2135 child->found_tag_modifiers = child_found_tag_modifiers; 2136 child->found_tag_number = child_found_tag_number; 2137 child->consumed = child_consumed; 2138 if (child->underlying_kind == SEC_ASN1_ANY 2139 && !child->top->filter_only) { 2140 /* 2141 * If the new field is an ANY, and we are storing, then 2142 * we need to save the tag out. We would have done this 2143 * already in the normal case, but since we were looking 2144 * for an optional field, and we did not find it, we only 2145 * now realize we need to save the tag. 2146 */ 2147 unsigned char identifier; 2148 2149 /* 2150 * Check that we did not end up with a high tag; for that 2151 * we need to re-encode the tag into multiple bytes in order 2152 * to store it back to look like what we parsed originally. 2153 * In practice this does not happen, but for completeness 2154 * sake it should probably be made to work at some point. 2155 */ 2156 PORT_Assert (child_found_tag_number < SEC_ASN1_HIGH_TAG_NUMBER); 2157 identifier = (unsigned char)(child_found_tag_modifiers | child_found_tag_number); 2158 sec_asn1d_record_any_header (child, (char *) &identifier, 1); 2159 } 2160 } 2161 } 2162} 2163 2164 2165static void 2166sec_asn1d_concat_substrings (sec_asn1d_state *state) 2167{ 2168 PORT_Assert (state->place == afterConstructedString); 2169 2170 if (state->subitems_head != NULL) { 2171 struct subitem *substring; 2172 unsigned long alloc_len, item_len; 2173 unsigned char *where; 2174 SecAsn1Item *item; 2175 PRBool is_bit_string; 2176 2177 item_len = 0; 2178 is_bit_string = (state->underlying_kind == SEC_ASN1_BIT_STRING) 2179 ? PR_TRUE : PR_FALSE; 2180 2181 substring = state->subitems_head; 2182 while (substring != NULL) { 2183 /* 2184 * All bit-string substrings except the last one should be 2185 * a clean multiple of 8 bits. 2186 */ 2187 if (is_bit_string && (substring->next == NULL) 2188 && (substring->len & 0x7)) { 2189 dprintf("decodeError: sec_asn1d_concat_substrings align\n"); 2190 PORT_SetError (SEC_ERROR_BAD_DER); 2191 state->top->status = decodeError; 2192 return; 2193 } 2194 item_len += substring->len; 2195 substring = substring->next; 2196 } 2197 2198 if (is_bit_string) { 2199#ifdef XP_WIN16 /* win16 compiler gets an internal error otherwise */ 2200 alloc_len = (((long)item_len + 7) / 8); 2201#else 2202 alloc_len = ((item_len + 7) >> 3); 2203#endif 2204 } else { 2205 /* 2206 * Add 2 for the end-of-contents octets of an indefinite-length 2207 * ANY that is *not* also an INNER. Because we zero-allocate 2208 * below, all we need to do is increase the length here. 2209 */ 2210 if (state->underlying_kind == SEC_ASN1_ANY && state->indefinite) 2211 item_len += 2; 2212 alloc_len = item_len; 2213 } 2214 2215 item = (SecAsn1Item *)(state->dest); 2216 PORT_Assert (item != NULL); 2217 PORT_Assert (item->Data == NULL); 2218 item->Data = (unsigned char*)sec_asn1d_zalloc (state->top->their_pool, 2219 alloc_len); 2220 if (item->Data == NULL) { 2221 dprintf("decodeError: zalloc\n"); 2222 state->top->status = decodeError; 2223 return; 2224 } 2225 item->Length = item_len; 2226 2227 where = item->Data; 2228 substring = state->subitems_head; 2229 while (substring != NULL) { 2230 if (is_bit_string) 2231 item_len = (substring->len + 7) >> 3; 2232 else 2233 item_len = substring->len; 2234 PORT_Memcpy (where, substring->data, item_len); 2235 where += item_len; 2236 substring = substring->next; 2237 } 2238 2239 /* 2240 * Because we use arenas and have a mark set, we later free 2241 * everything we have allocated, so this does *not* present 2242 * a memory leak (it is just temporarily left dangling). 2243 */ 2244 state->subitems_head = state->subitems_tail = NULL; 2245 } 2246 2247 state->place = afterEndOfContents; 2248} 2249 2250 2251static void 2252sec_asn1d_concat_group (sec_asn1d_state *state) 2253{ 2254 const void ***placep; 2255 2256 PORT_Assert (state->place == afterGroup); 2257 2258 placep = (const void***)state->dest; 2259 PORT_Assert(state->subitems_head == NULL || placep != NULL); 2260 if (placep != NULL) { 2261 struct subitem *item; 2262 const void **group; 2263 int count; 2264 2265 count = 0; 2266 item = state->subitems_head; 2267 while (item != NULL) { 2268 PORT_Assert (item->next != NULL || item == state->subitems_tail); 2269 count++; 2270 item = item->next; 2271 } 2272 2273 group = (const void**)sec_asn1d_zalloc (state->top->their_pool, 2274 (count + 1) * (sizeof(void *))); 2275 if (group == NULL) { 2276 dprintf("decodeError: zalloc\n"); 2277 state->top->status = decodeError; 2278 return; 2279 } 2280 2281 *placep = group; 2282 2283 item = state->subitems_head; 2284 while (item != NULL) { 2285 *group++ = item->data; 2286 item = item->next; 2287 } 2288 *group = NULL; 2289 2290 /* 2291 * Because we use arenas and have a mark set, we later free 2292 * everything we have allocated, so this does *not* present 2293 * a memory leak (it is just temporarily left dangling). 2294 */ 2295 state->subitems_head = state->subitems_tail = NULL; 2296 } 2297 2298 state->place = afterEndOfContents; 2299} 2300 2301/* 2302 * For those states that push a child to handle a subtemplate, 2303 * "absorb" that child (transfer necessary information). 2304 */ 2305static void 2306sec_asn1d_absorb_child (sec_asn1d_state *state) 2307{ 2308 /* 2309 * There is absolutely supposed to be a child there. 2310 */ 2311 PORT_Assert (state->child != NULL); 2312 2313 /* 2314 * Inherit the missing status of our child, and do the ugly 2315 * backing-up if necessary. 2316 */ 2317 state->missing = state->child->missing; 2318 if (state->missing) { 2319 state->found_tag_number = state->child->found_tag_number; 2320 state->found_tag_modifiers = state->child->found_tag_modifiers; 2321 state->endofcontents = state->child->endofcontents; 2322 } 2323 2324 /* 2325 * Add in number of bytes consumed by child. 2326 * (Only EXPLICIT should have already consumed bytes itself.) 2327 */ 2328 PORT_Assert (state->place == afterExplicit || state->consumed == 0); 2329 state->consumed += state->child->consumed; 2330 2331 /* 2332 * Subtract from bytes pending; this only applies to a definite-length 2333 * EXPLICIT field. 2334 */ 2335 if (state->pending) { 2336 PORT_Assert (!state->indefinite); 2337 PORT_Assert (state->place == afterExplicit); 2338 2339 /* 2340 * If we had a definite-length explicit, then what the child 2341 * consumed should be what was left pending. 2342 */ 2343 if (state->pending != state->child->consumed) { 2344 if (state->pending < state->child->consumed) { 2345 dprintf("decodeError: absorb_child pending < consumed\n"); 2346 PORT_SetError (SEC_ERROR_BAD_DER); 2347 state->top->status = decodeError; 2348 return; 2349 } 2350 /* 2351 * Okay, this is a hack. It *should* be an error whether 2352 * pending is too big or too small, but it turns out that 2353 * we had a bug in our *old* DER encoder that ended up 2354 * counting an explicit header twice in the case where 2355 * the underlying type was an ANY. So, because we cannot 2356 * prevent receiving these (our own certificate server can 2357 * send them to us), we need to be lenient and accept them. 2358 * To do so, we need to pretend as if we read all of the 2359 * bytes that the header said we would find, even though 2360 * we actually came up short. 2361 */ 2362 state->consumed += (state->pending - state->child->consumed); 2363 } 2364 state->pending = 0; 2365 } 2366 2367 /* 2368 * Indicate that we are done with child. 2369 */ 2370 state->child->consumed = 0; 2371 2372 /* 2373 * And move on to final state. 2374 * (Technically everybody could move to afterEndOfContents except 2375 * for an indefinite-length EXPLICIT; for simplicity though we assert 2376 * that but let the end-of-contents code do the real determination.) 2377 */ 2378 PORT_Assert (state->place == afterExplicit || (! state->indefinite)); 2379 state->place = beforeEndOfContents; 2380} 2381 2382 2383static void 2384sec_asn1d_prepare_for_end_of_contents (sec_asn1d_state *state) 2385{ 2386 PORT_Assert (state->place == beforeEndOfContents); 2387 2388 if (state->indefinite) { 2389 state->place = duringEndOfContents; 2390 state->pending = 2; 2391 } else { 2392 state->place = afterEndOfContents; 2393 } 2394} 2395 2396 2397static unsigned long 2398sec_asn1d_parse_end_of_contents (sec_asn1d_state *state, 2399 const char *buf, unsigned long len) 2400{ 2401 unsigned int i; 2402 2403 PORT_Assert (state->pending <= 2); 2404 PORT_Assert (state->place == duringEndOfContents); 2405 2406 if (len == 0) { 2407 state->top->status = needBytes; 2408 return 0; 2409 } 2410 2411 if (state->pending < len) 2412 len = state->pending; 2413 2414 for (i = 0; i < len; i++) { 2415 if (buf[i] != 0) { 2416 /* 2417 * We expect to find only zeros; if not, just give up. 2418 */ 2419 dprintf("decodeError: end of contents non zero\n"); 2420 PORT_SetError (SEC_ERROR_BAD_DER); 2421 state->top->status = decodeError; 2422 return 0; 2423 } 2424 } 2425 2426 state->pending -= len; 2427 2428 if (state->pending == 0) { 2429 state->place = afterEndOfContents; 2430 state->endofcontents = PR_TRUE; 2431 } 2432 2433 return len; 2434} 2435 2436 2437static void 2438sec_asn1d_pop_state (sec_asn1d_state *state) 2439{ 2440#if 0 /* XXX I think this should always be handled explicitly by parent? */ 2441 /* 2442 * Account for our child. 2443 */ 2444 if (state->child != NULL) { 2445 state->consumed += state->child->consumed; 2446 if (state->pending) { 2447 PORT_Assert (!state->indefinite); 2448 if( state->child->consumed > state->pending ) { 2449 dprintf("decodeError: pop_state pending < consumed\n"); 2450 PORT_SetError (SEC_ERROR_BAD_DER); 2451 state->top->status = decodeError; 2452 } else { 2453 state->pending -= state->child->consumed; 2454 } 2455 } 2456 state->child->consumed = 0; 2457 } 2458#endif /* XXX */ 2459 2460 /* 2461 * Free our child. 2462 */ 2463 sec_asn1d_free_child (state, PR_FALSE); 2464 2465 /* 2466 * Just make my parent be the current state. It will then clean 2467 * up after me and free me (or reuse me). 2468 */ 2469 state->top->current = state->parent; 2470} 2471 2472static sec_asn1d_state * 2473sec_asn1d_before_choice (sec_asn1d_state *state, const char *buf /* __APPLE__ */) 2474{ 2475 sec_asn1d_state *child; 2476 2477 if( state->allocate ) { 2478 void *dest; 2479 2480 dest = sec_asn1d_zalloc(state->top->their_pool, 2481 state->theTemplate->size); 2482 if( (void *)NULL == dest ) { 2483 dprintf("decodeError: zalloc\n"); 2484 state->top->status = decodeError; 2485 return (sec_asn1d_state *)NULL; 2486 } 2487 2488 state->dest = (char *)dest + state->theTemplate->offset; 2489 } 2490 2491 child = sec_asn1d_push_state(state->top, state->theTemplate + 1, 2492 (char *)state->dest - state->theTemplate->offset, 2493 PR_FALSE); 2494 if( (sec_asn1d_state *)NULL == child ) { 2495 return (sec_asn1d_state *)NULL; 2496 } 2497 2498 sec_asn1d_scrub_state(child); 2499 child = sec_asn1d_init_state_based_on_template(child, 2500 buf /* __APPLE__ */); 2501 if( (sec_asn1d_state *)NULL == child ) { 2502 return (sec_asn1d_state *)NULL; 2503 } 2504 2505 child->optional = PR_TRUE; 2506 2507 state->place = duringChoice; 2508 2509 return child; 2510} 2511 2512static sec_asn1d_state * 2513sec_asn1d_during_choice (sec_asn1d_state *state, const char *buf /* __APPLE__ */) 2514{ 2515 sec_asn1d_state *child = state->child; 2516 2517 PORT_Assert((sec_asn1d_state *)NULL != child); 2518 2519 if( child->missing ) { 2520 unsigned char child_found_tag_modifiers = 0; 2521 unsigned long child_found_tag_number = 0; 2522 void * dest; 2523 2524 state->consumed += child->consumed; 2525 2526 if (child->endofcontents) { 2527 /* This choice is probably the first item in a GROUP 2528 ** (e.g. SET_OF) that was indefinite-length encoded. 2529 ** We're actually at the end of that GROUP. 2530 ** We look up the stack to be sure that we find 2531 ** a state with indefinite length encoding before we 2532 ** find a state (like a SEQUENCE) that is definite. 2533 */ 2534 child->place = notInUse; 2535 state->place = afterChoice; 2536 state->endofcontents = PR_TRUE; /* propagate this up */ 2537 if (sec_asn1d_parent_allows_EOC(state)) 2538 return state; 2539 dprintf("decodeError: during_choice child at EOC by parent does not allow EOC\n"); 2540 PORT_SetError(SEC_ERROR_BAD_DER); 2541 state->top->status = decodeError; 2542 return NULL; 2543 } 2544 2545 dest = (char *)child->dest - child->theTemplate->offset; 2546 child->theTemplate++; 2547 2548 if( 0 == child->theTemplate->kind ) { 2549 /* Ran out of choices */ 2550 dprintf("decodeError: during_choice ran out of choice\n"); 2551 PORT_SetError(SEC_ERROR_BAD_DER); 2552 state->top->status = decodeError; 2553 return (sec_asn1d_state *)NULL; 2554 } 2555 child->dest = (char *)dest + child->theTemplate->offset; 2556 2557 /* cargo'd from next_in_sequence innards */ 2558 if( state->pending ) { 2559 PORT_Assert(!state->indefinite); 2560 if( child->consumed > state->pending ) { 2561 dprintf("decodeError: during_choice consumed > pending\n"); 2562 PORT_SetError (SEC_ERROR_BAD_DER); 2563 state->top->status = decodeError; 2564 return NULL; 2565 } 2566 state->pending -= child->consumed; 2567 if( 0 == state->pending ) { 2568 /* XXX uh.. not sure if I should have stopped this 2569 * from happening before. */ 2570 PORT_Assert(0); 2571 PORT_SetError(SEC_ERROR_BAD_DER); 2572 dprintf("decodeError: during_choice !pending\n"); 2573 state->top->status = decodeError; 2574 return (sec_asn1d_state *)NULL; 2575 } 2576 } 2577 2578 child->consumed = 0; 2579 sec_asn1d_scrub_state(child); 2580 2581 /* move it on top again */ 2582 state->top->current = child; 2583 2584 child_found_tag_modifiers = child->found_tag_modifiers; 2585 child_found_tag_number = child->found_tag_number; 2586 2587 child = sec_asn1d_init_state_based_on_template(child, buf /* __APPLE__*/); 2588 if( (sec_asn1d_state *)NULL == child ) { 2589 return (sec_asn1d_state *)NULL; 2590 } 2591 2592 /* copy our findings to the new top */ 2593 child->found_tag_modifiers = child_found_tag_modifiers; 2594 child->found_tag_number = child_found_tag_number; 2595 2596 child->optional = PR_TRUE; 2597 child->place = afterIdentifier; 2598 2599 return child; 2600 } 2601 if( (void *)NULL != state->dest ) { 2602 /* Store the enum */ 2603 int *which = (int *)state->dest; 2604 *which = (int)child->theTemplate->size; 2605 } 2606 2607 child->place = notInUse; 2608 2609 state->place = afterChoice; 2610 return state; 2611} 2612 2613static void 2614sec_asn1d_after_choice (sec_asn1d_state *state) 2615{ 2616 state->consumed += state->child->consumed; 2617 state->child->consumed = 0; 2618 state->place = afterEndOfContents; 2619 sec_asn1d_pop_state(state); 2620} 2621 2622#if 0 2623unsigned long 2624sec_asn1d_uinteger(SecAsn1Item *src) 2625{ 2626 unsigned long value; 2627 int len; 2628 2629 if (src->Length > 5 || (src->Length > 4 && src->Data[0] == 0)) 2630 return 0; 2631 2632 value = 0; 2633 len = src->Length; 2634 while (len) { 2635 value <<= 8; 2636 value |= src->Data[--len]; 2637 } 2638 return value; 2639} 2640#endif 2641 2642SECStatus 2643SEC_ASN1DecodeInteger(SecAsn1Item *src, unsigned long *value) 2644{ 2645 unsigned long v; 2646 unsigned int i; 2647 2648 if (src == NULL) { 2649 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2650 return SECFailure; 2651 } 2652 2653 if (src->Length > sizeof(unsigned long)) { 2654 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2655 return SECFailure; 2656 } 2657 2658 if (src->Data == NULL) { 2659 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2660 return SECFailure; 2661 } 2662 2663 if (src->Data[0] & 0x80) 2664 v = -1; /* signed and negative - start with all 1's */ 2665 else 2666 v = 0; 2667 2668 for (i= 0; i < src->Length; i++) { 2669 /* shift in next byte */ 2670 v <<= 8; 2671 v |= src->Data[i]; 2672 } 2673 *value = v; 2674 return SECSuccess; 2675} 2676 2677#ifdef DEBUG_ASN1D_STATES 2678static void 2679dump_states(SEC_ASN1DecoderContext *cx) 2680{ 2681 sec_asn1d_state *state; 2682 char kindBuf[256]; 2683 2684 for (state = cx->current; state->parent; state = state->parent) { 2685 ; 2686 } 2687 2688 for (; state; state = state->child) { 2689 int i; 2690 for (i = 0; i < state->depth; i++) { 2691 printf(" "); 2692 } 2693 2694 i = formatKind(state->theTemplate->kind, kindBuf); 2695 printf("%s: tmpl %p, kind%s", 2696 (state == cx->current) ? "STATE" : "State", 2697 state->theTemplate, 2698 kindBuf); 2699 printf(" %s", (state->place <= notInUse) 2700 ? place_names[ state->place ] 2701 : "(undefined)"); 2702 if (!i) 2703 printf(", expect 0x%02lx", 2704 state->expect_tag_number | state->expect_tag_modifiers); 2705 2706 printf("%s%s%s %lu\n", 2707 state->indefinite ? ", indef" : "", 2708 state->missing ? ", miss" : "", 2709 state->endofcontents ? ", EOC" : "", 2710 state->pending 2711 ); 2712 } 2713 2714 return; 2715} 2716#endif /* DEBUG_ASN1D_STATES */ 2717 2718SECStatus 2719SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, 2720 const char *buf, size_t len) 2721{ 2722 sec_asn1d_state *state = NULL; 2723 unsigned long consumed; 2724 SEC_ASN1EncodingPart what; 2725 sec_asn1d_state *stateEnd = cx->current; 2726 2727 if (cx->status == needBytes) 2728 cx->status = keepGoing; 2729 2730 while (cx->status == keepGoing) { 2731 state = cx->current; 2732 what = SEC_ASN1_Contents; 2733 consumed = 0; 2734 #if DEBUG_ASN1D_STATES 2735 if (doDumpStates > 1) { 2736 printf("\nPLACE = %s, next byte = 0x%02x, %p[%lu]\n", 2737 (state->place <= notInUse) ? 2738 place_names[ state->place ] : "(undefined)", 2739 (unsigned int)((unsigned char *)buf)[ consumed ], 2740 buf, consumed); 2741 dump_states(cx); 2742 } 2743 #endif /* DEBUG_ASN1D_STATES */ 2744 switch (state->place) { 2745 case beforeIdentifier: 2746 consumed = sec_asn1d_parse_identifier (state, buf, len); 2747 what = SEC_ASN1_Identifier; 2748 break; 2749 case duringIdentifier: 2750 consumed = sec_asn1d_parse_more_identifier (state, buf, len); 2751 what = SEC_ASN1_Identifier; 2752 break; 2753 case afterIdentifier: 2754 sec_asn1d_confirm_identifier (state); 2755 break; 2756 case beforeLength: 2757 consumed = sec_asn1d_parse_length (state, buf, len); 2758 what = SEC_ASN1_Length; 2759 break; 2760 case duringLength: 2761 consumed = sec_asn1d_parse_more_length (state, buf, len); 2762 what = SEC_ASN1_Length; 2763 break; 2764 case afterLength: 2765 sec_asn1d_prepare_for_contents (state, buf); 2766 break; 2767 case beforeBitString: 2768 consumed = sec_asn1d_parse_bit_string (state, buf, len); 2769 break; 2770 case duringBitString: 2771 consumed = sec_asn1d_parse_more_bit_string (state, buf, len); 2772 break; 2773 case duringConstructedString: 2774 sec_asn1d_next_substring (state); 2775 break; 2776 case duringGroup: 2777 sec_asn1d_next_in_group (state, buf); 2778 break; 2779 case duringLeaf: 2780 consumed = sec_asn1d_parse_leaf (state, buf, len); 2781 break; 2782 case duringSaveEncoding: 2783 sec_asn1d_reuse_encoding (state); 2784 if (cx->status == decodeError) { 2785 /* recursive call has already popped all states from stack. 2786 ** Bail out quickly. 2787 */ 2788 return SECFailure; 2789 } 2790 if (cx->status == needBytes) { 2791 /* recursive call wanted more data. Fatal. Clean up below. */ 2792 PORT_SetError (SEC_ERROR_BAD_DER); 2793 cx->status = decodeError; 2794 } 2795 break; 2796 case duringSequence: 2797 sec_asn1d_next_in_sequence (state, buf); 2798 break; 2799 case afterConstructedString: 2800 sec_asn1d_concat_substrings (state); 2801 break; 2802 case afterExplicit: 2803 case afterImplicit: 2804 case afterInline: 2805 case afterPointer: 2806 sec_asn1d_absorb_child (state); 2807 break; 2808 case afterGroup: 2809 sec_asn1d_concat_group (state); 2810 break; 2811 case afterSaveEncoding: 2812 /* SEC_ASN1DecoderUpdate has called itself recursively to 2813 ** decode SAVEd encoded data, and now is done decoding that. 2814 ** Return to the calling copy of SEC_ASN1DecoderUpdate. 2815 */ 2816 return SECSuccess; 2817 case beforeEndOfContents: 2818 sec_asn1d_prepare_for_end_of_contents (state); 2819 break; 2820 case duringEndOfContents: 2821 consumed = sec_asn1d_parse_end_of_contents (state, buf, len); 2822 what = SEC_ASN1_EndOfContents; 2823 break; 2824 case afterEndOfContents: 2825 sec_asn1d_pop_state (state); 2826 break; 2827 case beforeChoice: 2828 state = sec_asn1d_before_choice(state, buf); 2829 break; 2830 case duringChoice: 2831 state = sec_asn1d_during_choice(state, buf); 2832 break; 2833 case afterChoice: 2834 sec_asn1d_after_choice(state); 2835 break; 2836 case notInUse: 2837 default: 2838 /* This is not an error, but rather a plain old BUG! */ 2839 PORT_Assert (0); 2840 PORT_SetError (SEC_ERROR_BAD_DER); 2841 dprintf("decodeError: decoder update bad state->place\n"); 2842 cx->status = decodeError; 2843 break; 2844 } 2845 2846 if (cx->status == decodeError) 2847 break; 2848 2849 /* We should not consume more than we have. */ 2850 PORT_Assert (consumed <= len); 2851 if( consumed > len ) { 2852 dprintf("decodeError: decoder update consumed > len\n"); 2853 PORT_SetError (SEC_ERROR_BAD_DER); 2854 cx->status = decodeError; 2855 break; 2856 } 2857 2858 /* It might have changed, so we have to update our local copy. */ 2859 state = cx->current; 2860 2861 /* If it is NULL, we have popped all the way to the top. */ 2862 if (state == NULL) { 2863 PORT_Assert (consumed == 0); 2864 #if 0 2865 /* XXX I want this here, but it seems that we have situations (like 2866 * downloading a pkcs7 cert chain from some issuers) that give us a 2867 * length which is greater than the entire encoding. So, we cannot 2868 * have this be an error. 2869 */ 2870 if (len > 0) { 2871 dprintf("decodeError: decoder update nonzero len\n"); 2872 PORT_SetError (SEC_ERROR_BAD_DER); 2873 cx->status = decodeError; 2874 } 2875 else 2876 #endif 2877 cx->status = allDone; 2878 break; 2879 } 2880 else if (state->theTemplate->kind == SEC_ASN1_SKIP_REST) { 2881 cx->status = allDone; 2882 break; 2883 } 2884 2885 if (consumed == 0) 2886 continue; 2887 2888 /* 2889 * The following check is specifically looking for an ANY 2890 * that is *not* also an INNER, because we need to save aside 2891 * all bytes in that case -- the contents parts will get 2892 * handled like all other contents, and the end-of-contents 2893 * bytes are added by the concat code, but the outer header 2894 * bytes need to get saved too, so we do them explicitly here. 2895 */ 2896 if (state->underlying_kind == SEC_ASN1_ANY 2897 && !cx->filter_only && (what == SEC_ASN1_Identifier 2898 || what == SEC_ASN1_Length)) { 2899 sec_asn1d_record_any_header (state, buf, consumed); 2900 } 2901 2902 /* 2903 * We had some number of good, accepted bytes. If the caller 2904 * has registered to see them, pass them along. 2905 */ 2906 if (state->top->filter_proc != NULL) { 2907 int depth; 2908 2909 depth = state->depth; 2910 if (what == SEC_ASN1_EndOfContents && !state->indefinite) { 2911 PORT_Assert (state->parent != NULL 2912 && state->parent->indefinite); 2913 depth--; 2914 PORT_Assert (depth == state->parent->depth); 2915 } 2916 (* state->top->filter_proc) (state->top->filter_arg, 2917 buf, consumed, depth, what); 2918 } 2919 2920 state->consumed += consumed; 2921 buf += consumed; 2922 len -= consumed; 2923 } /* main decode loop */ 2924 2925 if (cx->status == decodeError) { 2926 while (state != NULL && stateEnd->parent!=state) { 2927 sec_asn1d_free_child (state, PR_TRUE); 2928 state = state->parent; 2929 } 2930#ifdef SEC_ASN1D_FREE_ON_ERROR /* 2931 * XXX This does not work because we can 2932 * end up leaving behind dangling pointers 2933 * to stuff that was allocated. In order 2934 * to make this really work (which would 2935 * be a good thing, I think), we need to 2936 * keep track of every place/pointer that 2937 * was allocated and make sure to NULL it 2938 * out before we then free back to the mark. 2939 */ 2940 if (cx->their_pool != NULL) { 2941 PORT_Assert (cx->their_mark != NULL); 2942 PORT_ArenaRelease (cx->their_pool, cx->their_mark); 2943 } 2944#endif 2945 return SECFailure; 2946 } 2947 2948#if 0 2949 /* XXX This is what I want, but cannot have because it seems we 2950 * have situations (like when downloading a pkcs7 cert chain from 2951 * some issuers) that give us a total length which is greater than 2952 * the entire encoding. So, we have to allow allDone to have a 2953 * remaining length greater than zero. I wanted to catch internal 2954 * bugs with this, noticing when we do not have the right length. 2955 * Oh well. 2956 */ 2957 PORT_Assert (len == 0 2958 && (cx->status == needBytes || cx->status == allDone)); 2959#else 2960 PORT_Assert ((len == 0 && cx->status == needBytes) 2961 || cx->status == allDone); 2962#endif 2963 return SECSuccess; 2964} 2965 2966 2967SECStatus 2968SEC_ASN1DecoderFinish (SEC_ASN1DecoderContext *cx) 2969{ 2970 SECStatus rv; 2971 2972 if (cx->status == needBytes) { 2973 #ifdef __APPLE__ 2974 /* 2975 * Special case: need more bytes, but this field and all 2976 * subsequent fields are optional. I'm surprised this case is 2977 * not handled in the original NSS code, and this workaround 2978 * is a bit of a hack... 2979 */ 2980 sec_asn1d_state *state = cx->current; 2981 assert(state != NULL); 2982 if(state->place == beforeIdentifier) { 2983 int allOptional = 1; 2984 const SecAsn1Template *templ = state->theTemplate; 2985 while(templ->kind != 0) { 2986 if(!(templ->kind & SEC_ASN1_OPTIONAL)) { 2987 allOptional = 0; 2988 break; 2989 } 2990 templ++; 2991 } 2992 if(allOptional) { 2993 /* letting this one slide */ 2994 rv = SECSuccess; 2995 } 2996 else { 2997 PORT_SetError (SEC_ERROR_BAD_DER); 2998 rv = SECFailure; 2999 } 3000 } 3001 else { 3002 PORT_SetError (SEC_ERROR_BAD_DER); 3003 rv = SECFailure; 3004 } 3005 #else 3006 PORT_SetError (SEC_ERROR_BAD_DER); 3007 rv = SECFailure; 3008 #endif /* __APPLE__ */ 3009 } else { 3010 rv = SECSuccess; 3011 } 3012 3013 /* 3014 * XXX anything else that needs to be finished? 3015 */ 3016 3017 PORT_FreeArena (cx->our_pool, PR_FALSE); 3018 3019 return rv; 3020} 3021 3022 3023SEC_ASN1DecoderContext * 3024SEC_ASN1DecoderStart (PRArenaPool *their_pool, void *dest, 3025 const SecAsn1Template *theTemplate 3026 #ifdef __APPLE__ 3027 , 3028 /* only needed if first element will be SEC_ASN1_DYNAMIC */ 3029 const char *buf 3030 #endif 3031 ) 3032{ 3033 PRArenaPool *our_pool; 3034 SEC_ASN1DecoderContext *cx; 3035 3036 our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); 3037 if (our_pool == NULL) 3038 return NULL; 3039 3040 cx = (SEC_ASN1DecoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx)); 3041 if (cx == NULL) { 3042 PORT_FreeArena (our_pool, PR_FALSE); 3043 return NULL; 3044 } 3045 3046 cx->our_pool = our_pool; 3047 if (their_pool != NULL) { 3048 cx->their_pool = their_pool; 3049#ifdef SEC_ASN1D_FREE_ON_ERROR 3050 cx->their_mark = PORT_ArenaMark (their_pool); 3051#endif 3052 } 3053 3054 cx->status = needBytes; 3055 3056 if (sec_asn1d_push_state(cx, theTemplate, dest, PR_FALSE) == NULL 3057 || sec_asn1d_init_state_based_on_template (cx->current, 3058 buf /* __APPLE__ */) == NULL) { 3059 /* 3060 * Trouble initializing (probably due to failed allocations) 3061 * requires that we just give up. 3062 */ 3063 PORT_FreeArena (our_pool, PR_FALSE); 3064 return NULL; 3065 } 3066 3067 return cx; 3068} 3069 3070 3071void 3072SEC_ASN1DecoderSetFilterProc (SEC_ASN1DecoderContext *cx, 3073 SEC_ASN1WriteProc fn, void *arg, 3074 PRBool only) 3075{ 3076 /* check that we are "between" fields here */ 3077 PORT_Assert (cx->during_notify); 3078 3079 cx->filter_proc = fn; 3080 cx->filter_arg = arg; 3081 cx->filter_only = only; 3082} 3083 3084 3085void 3086SEC_ASN1DecoderClearFilterProc (SEC_ASN1DecoderContext *cx) 3087{ 3088 /* check that we are "between" fields here */ 3089 PORT_Assert (cx->during_notify); 3090 3091 cx->filter_proc = NULL; 3092 cx->filter_arg = NULL; 3093 cx->filter_only = PR_FALSE; 3094} 3095 3096 3097void 3098SEC_ASN1DecoderSetNotifyProc (SEC_ASN1DecoderContext *cx, 3099 SEC_ASN1NotifyProc fn, void *arg) 3100{ 3101 cx->notify_proc = fn; 3102 cx->notify_arg = arg; 3103} 3104 3105 3106void 3107SEC_ASN1DecoderClearNotifyProc (SEC_ASN1DecoderContext *cx) 3108{ 3109 cx->notify_proc = NULL; 3110 cx->notify_arg = NULL; /* not necessary; just being clean */ 3111} 3112 3113 3114void 3115SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error) 3116{ 3117 PORT_Assert(cx); 3118 PORT_SetError(error); 3119 cx->status = decodeError; 3120} 3121 3122 3123SECStatus 3124SEC_ASN1Decode (PRArenaPool *poolp, void *dest, 3125 const SecAsn1Template *theTemplate, 3126 const char *buf, size_t len) 3127{ 3128 SEC_ASN1DecoderContext *dcx; 3129 SECStatus urv, frv; 3130 3131 dcx = SEC_ASN1DecoderStart (poolp, dest, theTemplate, 3132 buf /* __APPLE__ */); 3133 if (dcx == NULL) 3134 return SECFailure; 3135 3136 urv = SEC_ASN1DecoderUpdate (dcx, buf, len); 3137 frv = SEC_ASN1DecoderFinish (dcx); 3138 3139 if (urv != SECSuccess) 3140 return urv; 3141 3142 return frv; 3143} 3144 3145 3146SECStatus 3147SEC_ASN1DecodeItem (PRArenaPool *poolp, void *dest, 3148 const SecAsn1Template *theTemplate, 3149 const SecAsn1Item *item) 3150{ 3151 return SEC_ASN1Decode (poolp, dest, theTemplate, 3152 (const char *) item->Data, item->Length); 3153} 3154 3155 3156