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 || state->theTemplate == NULL) 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=NULL; 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 (void) state; 1147 return; 1148 } 1149 1150 /* 1151 * For GROUP (SET OF, SEQUENCE OF), even if we know the length here 1152 * we cannot tell how many items we will end up with ... so push a 1153 * state that can keep track of "children" (the individual members 1154 * of the group; we will allocate as we go and put them all together 1155 * at the end. 1156 */ 1157 if (state->underlying_kind & SEC_ASN1_GROUP) { 1158 /* XXX If this assertion holds (should be able to confirm it via 1159 * inspection, too) then move this code into the switch statement 1160 * below under cases SET_OF and SEQUENCE_OF; it will be cleaner. 1161 */ 1162 PORT_Assert (state->underlying_kind == SEC_ASN1_SET_OF 1163 || state->underlying_kind == SEC_ASN1_SEQUENCE_OF 1164 || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC) 1165 || state->underlying_kind == (SEC_ASN1_SET_OF|SEC_ASN1_DYNAMIC) 1166 ); 1167 if (state->contents_length != 0 || state->indefinite) { 1168 const SecAsn1Template *subt; 1169 1170 state->place = duringGroup; 1171 subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->dest, 1172 PR_FALSE, buf /* __APPLE__ */); 1173 state = sec_asn1d_push_state (state->top, subt, NULL, PR_TRUE); 1174 if (state != NULL) { 1175 if (!state->top->filter_only) 1176 state->allocate = PR_TRUE; /* XXX propogate this? */ 1177 /* 1178 * Do the "before" field notification for next in group. 1179 */ 1180 sec_asn1d_notify_before (state->top, state->dest, state->depth); 1181 state = sec_asn1d_init_state_based_on_template (state, 1182 buf /* __APPLE__ */); 1183 } 1184 } else { 1185 /* 1186 * A group of zero; we are done. 1187 * Set state to afterGroup and let that code plant the NULL. 1188 */ 1189 state->place = afterGroup; 1190 } 1191 (void) state; 1192 return; 1193 } 1194 1195 switch (state->underlying_kind) { 1196 case SEC_ASN1_SEQUENCE: 1197 /* 1198 * We need to push a child to handle the individual fields. 1199 */ 1200 state->place = duringSequence; 1201 state = sec_asn1d_push_state (state->top, state->theTemplate + 1, 1202 state->dest, PR_TRUE); 1203 if (state != NULL) { 1204 /* 1205 * Do the "before" field notification. 1206 */ 1207 sec_asn1d_notify_before (state->top, state->dest, state->depth); 1208 state = sec_asn1d_init_state_based_on_template (state, 1209 buf /* __APPLE__ */); 1210 } 1211 (void) state; 1212 break; 1213 1214 case SEC_ASN1_SET: /* XXX SET is not really implemented */ 1215 /* 1216 * XXX A plain SET requires special handling; scanning of a 1217 * template to see where a field should go (because by definition, 1218 * they are not in any particular order, and you have to look at 1219 * each tag to disambiguate what the field is). We may never 1220 * implement this because in practice, it seems to be unused. 1221 */ 1222 dprintf("decodeError: prepare for contents SEC_ASN1_SET\n"); 1223 PORT_Assert(0); 1224 PORT_SetError (SEC_ERROR_BAD_DER); /* XXX */ 1225 state->top->status = decodeError; 1226 break; 1227 1228 case SEC_ASN1_NULL: 1229 /* 1230 * The NULL type, by definition, is "nothing", content length of zero. 1231 * An indefinite-length encoding is not alloweed. 1232 */ 1233 if (state->contents_length || state->indefinite) { 1234 dprintf("decodeError: prepare for contents indefinite NULL\n"); 1235 PORT_SetError (SEC_ERROR_BAD_DER); 1236 state->top->status = decodeError; 1237 break; 1238 } 1239 if (state->dest != NULL) { 1240 item = (SecAsn1Item *)(state->dest); 1241 item->Data = NULL; 1242 item->Length = 0; 1243 } 1244 state->place = afterEndOfContents; 1245 break; 1246 1247 case SEC_ASN1_BMP_STRING: 1248 /* Error if length is not divisable by 2 */ 1249 if (state->contents_length % 2) { 1250 dprintf("decodeError: prepare for contents odd length BMP_STRING\n"); 1251 PORT_SetError (SEC_ERROR_BAD_DER); 1252 state->top->status = decodeError; 1253 break; 1254 } 1255 /* otherwise, handle as other string types */ 1256 goto regular_string_type; 1257 1258 case SEC_ASN1_UNIVERSAL_STRING: 1259 /* Error if length is not divisable by 4 */ 1260 if (state->contents_length % 4) { 1261 dprintf("decodeError: prepare for contents odd length UNIV_STRING\n"); 1262 PORT_SetError (SEC_ERROR_BAD_DER); 1263 state->top->status = decodeError; 1264 break; 1265 } 1266 /* otherwise, handle as other string types */ 1267 goto regular_string_type; 1268 1269 case SEC_ASN1_SKIP: 1270 case SEC_ASN1_ANY: 1271 case SEC_ASN1_ANY_CONTENTS: 1272 /* 1273 * These are not (necessarily) strings, but they need nearly 1274 * identical handling (especially when we need to deal with 1275 * constructed sub-pieces), so we pretend they are. 1276 */ 1277 /* fallthru */ 1278regular_string_type: 1279 case SEC_ASN1_BIT_STRING: 1280 case SEC_ASN1_IA5_STRING: 1281 case SEC_ASN1_OCTET_STRING: 1282 case SEC_ASN1_PRINTABLE_STRING: 1283 case SEC_ASN1_T61_STRING: 1284 case SEC_ASN1_UTC_TIME: 1285 case SEC_ASN1_UTF8_STRING: 1286 case SEC_ASN1_VISIBLE_STRING: 1287 /* 1288 * We are allocating for a primitive or a constructed string. 1289 * If it is a constructed string, it may also be indefinite-length. 1290 * If it is primitive, the length can (legally) be zero. 1291 * Our first order of business is to allocate the memory for 1292 * the string, if we can (if we know the length). 1293 */ 1294 item = (SecAsn1Item *)(state->dest); 1295 1296 /* 1297 * If the item is a definite-length constructed string, then 1298 * the contents_length is actually larger than what we need 1299 * (because it also counts each intermediate header which we 1300 * will be throwing away as we go), but it is a perfectly good 1301 * upper bound that we just allocate anyway, and then concat 1302 * as we go; we end up wasting a few extra bytes but save a 1303 * whole other copy. 1304 */ 1305 alloc_len = state->contents_length; 1306 poolp = NULL; /* quiet compiler warnings about unused... */ 1307 1308 if (item == NULL || state->top->filter_only) { 1309 if (item != NULL) { 1310 item->Data = NULL; 1311 item->Length = 0; 1312 } 1313 alloc_len = 0; 1314 } else if (state->substring) { 1315 /* 1316 * If we are a substring of a constructed string, then we may 1317 * not have to allocate anything (because our parent, the 1318 * actual constructed string, did it for us). If we are a 1319 * substring and we *do* have to allocate, that means our 1320 * parent is an indefinite-length, so we allocate from our pool; 1321 * later our parent will copy our string into the aggregated 1322 * whole and free our pool allocation. 1323 */ 1324 if (item->Data == NULL) { 1325 PORT_Assert (item->Length == 0); 1326 poolp = state->top->our_pool; 1327 } else { 1328 alloc_len = 0; 1329 } 1330 } else { 1331 item->Length = 0; 1332 item->Data = NULL; 1333 poolp = state->top->their_pool; 1334 } 1335 1336 if (alloc_len || ((! state->indefinite) 1337 && (state->subitems_head != NULL))) { 1338 struct subitem *subitem; 1339 unsigned long len; 1340 1341 PORT_Assert (item!=NULL); 1342 if (item==NULL) { 1343 PORT_SetError (SEC_ERROR_BAD_DER); 1344 state->top->status = decodeError; 1345 return; 1346 } 1347 PORT_Assert (item->Length == 0 && item->Data == NULL); 1348 /* 1349 * Check for and handle an ANY which has stashed aside the 1350 * header (identifier and length) bytes for us to include 1351 * in the saved contents. 1352 */ 1353 if (state->subitems_head != NULL) { 1354 PORT_Assert (state->underlying_kind == SEC_ASN1_ANY); 1355 for (subitem = state->subitems_head; 1356 subitem != NULL; subitem = subitem->next) 1357 alloc_len += subitem->len; 1358 } 1359 1360 item->Data = (unsigned char*)sec_asn1d_zalloc (poolp, alloc_len); 1361 if (item->Data == NULL) { 1362 dprintf("decodeError: prepare for contents zalloc\n"); 1363 state->top->status = decodeError; 1364 break; 1365 } 1366 1367 len = 0; 1368 for (subitem = state->subitems_head; 1369 subitem != NULL; subitem = subitem->next) { 1370 PORT_Memcpy (item->Data + len, subitem->data, subitem->len); 1371 len += subitem->len; 1372 } 1373 item->Length = len; 1374 1375 /* 1376 * Because we use arenas and have a mark set, we later free 1377 * everything we have allocated, so this does *not* present 1378 * a memory leak (it is just temporarily left dangling). 1379 */ 1380 state->subitems_head = state->subitems_tail = NULL; 1381 } 1382 1383 if (state->contents_length == 0 && (! state->indefinite)) { 1384 /* 1385 * A zero-length simple or constructed string; we are done. 1386 */ 1387 state->place = afterEndOfContents; 1388 } else if (state->found_tag_modifiers & SEC_ASN1_CONSTRUCTED) { 1389 const SecAsn1Template *sub; 1390 1391 switch (state->underlying_kind) { 1392 case SEC_ASN1_ANY: 1393 case SEC_ASN1_ANY_CONTENTS: 1394 sub = kSecAsn1AnyTemplate; 1395 break; 1396 case SEC_ASN1_BIT_STRING: 1397 sub = kSecAsn1BitStringTemplate; 1398 break; 1399 case SEC_ASN1_BMP_STRING: 1400 sub = kSecAsn1BMPStringTemplate; 1401 break; 1402 case SEC_ASN1_GENERALIZED_TIME: 1403 sub = kSecAsn1GeneralizedTimeTemplate; 1404 break; 1405 case SEC_ASN1_IA5_STRING: 1406 sub = kSecAsn1IA5StringTemplate; 1407 break; 1408 case SEC_ASN1_OCTET_STRING: 1409 sub = kSecAsn1OctetStringTemplate; 1410 break; 1411 case SEC_ASN1_PRINTABLE_STRING: 1412 sub = kSecAsn1PrintableStringTemplate; 1413 break; 1414 case SEC_ASN1_T61_STRING: 1415 sub = kSecAsn1T61StringTemplate; 1416 break; 1417 case SEC_ASN1_UNIVERSAL_STRING: 1418 sub = kSecAsn1UniversalStringTemplate; 1419 break; 1420 case SEC_ASN1_UTC_TIME: 1421 sub = kSecAsn1UTCTimeTemplate; 1422 break; 1423 case SEC_ASN1_UTF8_STRING: 1424 sub = kSecAsn1UTF8StringTemplate; 1425 break; 1426 case SEC_ASN1_VISIBLE_STRING: 1427 sub = kSecAsn1VisibleStringTemplate; 1428 break; 1429 case SEC_ASN1_SKIP: 1430 sub = kSecAsn1SkipTemplate; 1431 break; 1432 default: /* redundant given outer switch cases, but */ 1433 PORT_Assert(0); /* the compiler does not seem to know that, */ 1434 sub = NULL; /* so just do enough to quiet it. */ 1435 break; 1436 } 1437 1438 state->place = duringConstructedString; 1439 state = sec_asn1d_push_state (state->top, sub, item, PR_TRUE); 1440 if (state != NULL) { 1441 state->substring = PR_TRUE; /* XXX propogate? */ 1442 state = sec_asn1d_init_state_based_on_template (state, 1443 buf /* __APPLE__ */); 1444 } 1445 } else if (state->indefinite) { 1446 /* 1447 * An indefinite-length string *must* be constructed! 1448 */ 1449 dprintf("decodeError: prepare for contents indefinite not construncted\n"); 1450 PORT_SetError (SEC_ERROR_BAD_DER); 1451 state->top->status = decodeError; 1452 } else { 1453 /* 1454 * A non-zero-length simple string. 1455 */ 1456 if (state->underlying_kind == SEC_ASN1_BIT_STRING) 1457 state->place = beforeBitString; 1458 else 1459 state->place = duringLeaf; 1460 } 1461 (void) state; 1462 break; 1463 1464 default: 1465 /* 1466 * We are allocating for a simple leaf item. 1467 */ 1468 if (state->contents_length) { 1469 if (state->dest != NULL) { 1470 item = (SecAsn1Item *)(state->dest); 1471 item->Length = 0; 1472 if (state->top->filter_only) { 1473 item->Data = NULL; 1474 } else { 1475 item->Data = (unsigned char*) 1476 sec_asn1d_zalloc (state->top->their_pool, 1477 state->contents_length); 1478 if (item->Data == NULL) { 1479 dprintf("decodeError: prepare for contents zalloc\n"); 1480 state->top->status = decodeError; 1481 return; 1482 } 1483 } 1484 } 1485 state->place = duringLeaf; 1486 } else { 1487 /* 1488 * An indefinite-length or zero-length item is not allowed. 1489 * (All legal cases of such were handled above.) 1490 */ 1491 dprintf("decodeError: prepare for contents indefinite zero len \n"); 1492 PORT_SetError (SEC_ERROR_BAD_DER); 1493 state->top->status = decodeError; 1494 } 1495 } 1496} 1497 1498 1499static void 1500sec_asn1d_free_child (sec_asn1d_state *state, PRBool error) 1501{ 1502 if (state->child != NULL) { 1503 PORT_Assert (error || state->child->consumed == 0); 1504 PORT_Assert (state->our_mark != NULL); 1505 PORT_ArenaRelease (state->top->our_pool, state->our_mark); 1506 if (error && state->top->their_pool == NULL) { 1507 /* 1508 * XXX We need to free anything allocated. 1509 * At this point, we failed in the middle of decoding. But we 1510 * can't free the data we previously allocated with PR_Malloc 1511 * unless we keep track of every pointer. So instead we have a 1512 * memory leak when decoding fails half-way, unless an arena is 1513 * used. See bug 95311 . 1514 */ 1515 } 1516 state->child = NULL; 1517 state->our_mark = NULL; 1518 } else { 1519 /* 1520 * It is important that we do not leave a mark unreleased/unmarked. 1521 * But I do not think we should ever have one set in this case, only 1522 * if we had a child (handled above). So check for that. If this 1523 * assertion should ever get hit, then we probably need to add code 1524 * here to release back to our_mark (and then set our_mark to NULL). 1525 */ 1526 PORT_Assert (state->our_mark == NULL); 1527 } 1528 state->place = beforeEndOfContents; 1529} 1530 1531 1532/* We have just saved an entire encoded ASN.1 object (type) for a SAVE 1533** template, and now in the next template, we are going to decode that 1534** saved data by calling SEC_ASN1DecoderUpdate recursively. 1535** If that recursive call fails with needBytes, it is a fatal error, 1536** because the encoded object should have been complete. 1537** If that recursive call fails with decodeError, it will have already 1538** cleaned up the state stack, so we must bail out quickly. 1539** 1540** These checks of the status returned by the recursive call are now 1541** done in the caller of this function, immediately after it returns. 1542*/ 1543static void 1544sec_asn1d_reuse_encoding (sec_asn1d_state *state) 1545{ 1546 sec_asn1d_state *child; 1547 unsigned long consumed; 1548 SecAsn1Item *item; 1549 void *dest; 1550 1551 1552 child = state->child; 1553 PORT_Assert (child != NULL); 1554 1555 consumed = child->consumed; 1556 child->consumed = 0; 1557 1558 item = (SecAsn1Item *)(state->dest); 1559 PORT_Assert (item != NULL); 1560 1561 PORT_Assert (item->Length == consumed); 1562 1563 /* 1564 * Free any grandchild. 1565 */ 1566 sec_asn1d_free_child (child, PR_FALSE); 1567 1568 /* 1569 * Notify after the SAVE field. 1570 */ 1571 sec_asn1d_notify_after (state->top, state->dest, state->depth); 1572 1573 /* 1574 * Adjust to get new dest and move forward. 1575 */ 1576 dest = (char *)state->dest - state->theTemplate->offset; 1577 state->theTemplate++; 1578 child->dest = (char *)dest + state->theTemplate->offset; 1579 child->theTemplate = state->theTemplate; 1580 1581 /* 1582 * Notify before the "real" field. 1583 */ 1584 PORT_Assert (state->depth == child->depth); 1585 sec_asn1d_notify_before (state->top, child->dest, child->depth); 1586 1587 /* 1588 * This will tell DecoderUpdate to return when it is done. 1589 */ 1590 state->place = afterSaveEncoding; 1591 1592 /* 1593 * We already have a child; "push" it by making it current. 1594 */ 1595 state->top->current = child; 1596 1597 /* 1598 * And initialize it so it is ready to parse. 1599 */ 1600 (void) sec_asn1d_init_state_based_on_template(child, 1601 (char *) item->Data /* __APPLE__ */); 1602 1603 /* 1604 * Now parse that out of our data. 1605 */ 1606 if (SEC_ASN1DecoderUpdate (state->top, 1607 (char *) item->Data, item->Length) != SECSuccess) 1608 return; 1609 if (state->top->status == needBytes) { 1610 return; 1611 } 1612 1613 PORT_Assert (state->top->current == state); 1614 PORT_Assert (state->child == child); 1615 1616 /* 1617 * That should have consumed what we consumed before. 1618 */ 1619 PORT_Assert (consumed == child->consumed); 1620 child->consumed = 0; 1621 1622 /* 1623 * Done. 1624 */ 1625 state->consumed += consumed; 1626 child->place = notInUse; 1627 state->place = afterEndOfContents; 1628} 1629 1630 1631static unsigned long 1632sec_asn1d_parse_leaf (sec_asn1d_state *state, 1633 const char *buf, unsigned long len) 1634{ 1635 SecAsn1Item *item; 1636 unsigned long bufLen; 1637 1638 if (len == 0) { 1639 state->top->status = needBytes; 1640 return 0; 1641 } 1642 1643 if (state->pending < len) 1644 len = state->pending; 1645 1646 bufLen = len; 1647 1648 item = (SecAsn1Item *)(state->dest); 1649 if (item != NULL && item->Data != NULL) { 1650 /* Strip leading zeroes when target is unsigned integer */ 1651 if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */ 1652 item->Length == 0 && /* MSB */ 1653 #ifdef __APPLE__ 1654 !(state->underlying_kind & SEC_ASN1_SIGNED_INT)) 1655 #else 1656 item->type == siUnsignedInteger) /* unsigned */ 1657 #endif 1658 { 1659 while (len > 1 && buf[0] == 0) { /* leading 0 */ 1660 buf++; 1661 len--; 1662 } 1663 } 1664 PORT_Memcpy (item->Data + item->Length, buf, len); 1665 item->Length += len; 1666 } 1667 state->pending -= bufLen; 1668 if (state->pending == 0) 1669 state->place = beforeEndOfContents; 1670 1671 return bufLen; 1672} 1673 1674 1675static unsigned long 1676sec_asn1d_parse_bit_string (sec_asn1d_state *state, 1677 const char *buf, unsigned long len) 1678{ 1679 unsigned char byte; 1680 1681 /*PORT_Assert (state->pending > 0); */ 1682 PORT_Assert (state->place == beforeBitString); 1683 1684 if ((state->pending == 0) || (state->contents_length == 1)) { 1685 if (state->dest != NULL) { 1686 SecAsn1Item *item = (SecAsn1Item *)(state->dest); 1687 item->Data = NULL; 1688 item->Length = 0; 1689 state->place = beforeEndOfContents; 1690 } 1691 if(state->contents_length == 1) { 1692 /* skip over (unused) remainder byte */ 1693 return 1; 1694 } 1695 else { 1696 return 0; 1697 } 1698 } 1699 1700 if (len == 0) { 1701 state->top->status = needBytes; 1702 return 0; 1703 } 1704 1705 byte = (unsigned char) *buf; 1706 if (byte > 7) { 1707 dprintf("decodeError: parse_bit_string remainder oflow\n"); 1708 PORT_SetError (SEC_ERROR_BAD_DER); 1709 state->top->status = decodeError; 1710 return 0; 1711 } 1712 1713 state->bit_string_unused_bits = byte; 1714 state->place = duringBitString; 1715 state->pending -= 1; 1716 1717 return 1; 1718} 1719 1720 1721static unsigned long 1722sec_asn1d_parse_more_bit_string (sec_asn1d_state *state, 1723 const char *buf, unsigned long len) 1724{ 1725 PORT_Assert (state->place == duringBitString); 1726 if (state->pending == 0) { 1727 /* An empty bit string with some unused bits is invalid. */ 1728 if (state->bit_string_unused_bits) { 1729 PORT_SetError (SEC_ERROR_BAD_DER); 1730 state->top->status = decodeError; 1731 } else { 1732 /* An empty bit string with no unused bits is OK. */ 1733 state->place = beforeEndOfContents; 1734 } 1735 return 0; 1736 } 1737 1738 len = sec_asn1d_parse_leaf (state, buf, len); 1739 if (state->place == beforeEndOfContents && state->dest != NULL) { 1740 SecAsn1Item *item; 1741 1742 item = (SecAsn1Item *)(state->dest); 1743 if (item->Length) 1744 item->Length = (item->Length << 3) - state->bit_string_unused_bits; 1745 } 1746 1747 return len; 1748} 1749 1750 1751/* 1752 * XXX All callers should be looking at return value to detect 1753 * out-of-memory errors (and stop!). 1754 */ 1755static struct subitem * 1756sec_asn1d_add_to_subitems (sec_asn1d_state *state, 1757 const void *data, unsigned long len, 1758 PRBool copy_data) 1759{ 1760 struct subitem *thing; 1761 1762 thing = (struct subitem*)sec_asn1d_zalloc (state->top->our_pool, 1763 sizeof (struct subitem)); 1764 if (thing == NULL) { 1765 dprintf("decodeError: zalloc\n"); 1766 state->top->status = decodeError; 1767 return NULL; 1768 } 1769 1770 if (copy_data) { 1771 void *copy; 1772 copy = sec_asn1d_alloc (state->top->our_pool, len); 1773 if (copy == NULL) { 1774 dprintf("decodeError: alloc\n"); 1775 state->top->status = decodeError; 1776 if (!state->top->our_pool) 1777 PORT_Free(thing); 1778 return NULL; 1779 } 1780 PORT_Memcpy (copy, data, len); 1781 thing->data = copy; 1782 } else { 1783 thing->data = data; 1784 } 1785 thing->len = len; 1786 thing->next = NULL; 1787 1788 if (state->subitems_head == NULL) { 1789 PORT_Assert (state->subitems_tail == NULL); 1790 state->subitems_head = state->subitems_tail = thing; 1791 } else { 1792 state->subitems_tail->next = thing; 1793 state->subitems_tail = thing; 1794 } 1795 1796 return thing; 1797} 1798 1799 1800static void 1801sec_asn1d_record_any_header (sec_asn1d_state *state, 1802 const char *buf, 1803 unsigned long len) 1804{ 1805 SecAsn1Item *item; 1806 1807 item = (SecAsn1Item *)(state->dest); 1808 if (item != NULL && item->Data != NULL) { 1809 PORT_Assert (state->substring); 1810 PORT_Memcpy (item->Data + item->Length, buf, len); 1811 item->Length += len; 1812 } else { 1813 sec_asn1d_add_to_subitems (state, buf, len, PR_TRUE); 1814 } 1815} 1816 1817 1818/* 1819 * We are moving along through the substrings of a constructed string, 1820 * and have just finished parsing one -- we need to save our child data 1821 * (if the child was not already writing directly into the destination) 1822 * and then move forward by one. 1823 * 1824 * We also have to detect when we are done: 1825 * - a definite-length encoding stops when our pending value hits 0 1826 * - an indefinite-length encoding stops when our child is empty 1827 * (which means it was the end-of-contents octets) 1828 */ 1829static void 1830sec_asn1d_next_substring (sec_asn1d_state *state) 1831{ 1832 sec_asn1d_state *child; 1833 SecAsn1Item *item; 1834 unsigned long child_consumed; 1835 PRBool done; 1836 1837 PORT_Assert (state->place == duringConstructedString); 1838 PORT_Assert (state->child != NULL); 1839 1840 child = state->child; 1841 1842 child_consumed = child->consumed; 1843 child->consumed = 0; 1844 state->consumed += child_consumed; 1845 1846 done = PR_FALSE; 1847 1848 if (state->pending) { 1849 PORT_Assert (!state->indefinite); 1850 if( child_consumed > state->pending ) { 1851 dprintf("decodeError: next_substring consumed > pend\n"); 1852 PORT_SetError (SEC_ERROR_BAD_DER); 1853 state->top->status = decodeError; 1854 return; 1855 } 1856 1857 state->pending -= child_consumed; 1858 if (state->pending == 0) 1859 done = PR_TRUE; 1860 } else { 1861 PORT_Assert (state->indefinite); 1862 1863 item = (SecAsn1Item *)(child->dest); 1864 if (item != NULL && item->Data != NULL) { 1865 /* 1866 * Save the string away for later concatenation. 1867 */ 1868 PORT_Assert (item->Data != NULL); 1869 sec_asn1d_add_to_subitems (state, item->Data, item->Length, PR_FALSE); 1870 /* 1871 * Clear the child item for the next round. 1872 */ 1873 item->Data = NULL; 1874 item->Length = 0; 1875 } 1876 1877 /* 1878 * If our child was just our end-of-contents octets, we are done. 1879 */ 1880 if (child->endofcontents) 1881 done = PR_TRUE; 1882 } 1883 1884 /* 1885 * Stop or do the next one. 1886 */ 1887 if (done) { 1888 child->place = notInUse; 1889 state->place = afterConstructedString; 1890 } else { 1891 sec_asn1d_scrub_state (child); 1892 state->top->current = child; 1893 } 1894} 1895 1896 1897/* 1898 * We are doing a SET OF or SEQUENCE OF, and have just finished an item. 1899 */ 1900static void 1901sec_asn1d_next_in_group (sec_asn1d_state *state, 1902 const char *buf /* __APPLE__ */) 1903{ 1904 sec_asn1d_state *child; 1905 unsigned long child_consumed; 1906 1907 PORT_Assert (state->place == duringGroup); 1908 PORT_Assert (state->child != NULL); 1909 1910 child = state->child; 1911 1912 child_consumed = child->consumed; 1913 child->consumed = 0; 1914 state->consumed += child_consumed; 1915 1916 /* 1917 * If our child was just our end-of-contents octets, we are done. 1918 */ 1919 #ifdef __APPLE__ 1920 /* 1921 * Without the check for !child->indefinite, this path could 1922 * be taken erroneously if the child is indefinite! 1923 */ 1924 if(child->endofcontents && !child->indefinite) { 1925 #else 1926 if (child->endofcontents) { 1927 #endif /* __APPLE__ */ 1928 /* XXX I removed the PORT_Assert (child->dest == NULL) because there 1929 * was a bug in that a template that was a sequence of which also had 1930 * a child of a sequence of, in an indefinite group was not working 1931 * properly. This fix seems to work, (added the if statement below), 1932 * and nothing appears broken, but I am putting this note here just 1933 * in case. */ 1934 /* 1935 * XXX No matter how many times I read that comment, 1936 * I cannot figure out what case he was fixing. I believe what he 1937 * did was deliberate, so I am loathe to touch it. I need to 1938 * understand how it could ever be that child->dest != NULL but 1939 * child->endofcontents is true, and why it is important to check 1940 * that state->subitems_head is NULL. This really needs to be 1941 * figured out, as I am not sure if the following code should be 1942 * compensating for "offset", as is done a little farther below 1943 * in the more normal case. 1944 */ 1945 PORT_Assert (state->indefinite); 1946 PORT_Assert (state->pending == 0); 1947 if(child->dest && !state->subitems_head) { 1948 sec_asn1d_add_to_subitems (state, child->dest, 0, PR_FALSE); 1949 child->dest = NULL; 1950 } 1951 1952 child->place = notInUse; 1953 state->place = afterGroup; 1954 return; 1955 } 1956 1957 /* 1958 * Do the "after" field notification for next in group. 1959 */ 1960 sec_asn1d_notify_after (state->top, child->dest, child->depth); 1961 1962 /* 1963 * Save it away (unless we are not storing). 1964 */ 1965 if (child->dest != NULL) { 1966 void *dest; 1967 1968 dest = child->dest; 1969 dest = (char *)dest - child->theTemplate->offset; 1970 sec_asn1d_add_to_subitems (state, dest, 0, PR_FALSE); 1971 child->dest = NULL; 1972 } 1973 1974 /* 1975 * Account for those bytes; see if we are done. 1976 */ 1977 if (state->pending) { 1978 PORT_Assert (!state->indefinite); 1979 if( child_consumed > state->pending ) { 1980 dprintf("decodeError: next_in_group consumed > pend\n"); 1981 PORT_SetError (SEC_ERROR_BAD_DER); 1982 state->top->status = decodeError; 1983 return; 1984 } 1985 1986 state->pending -= child_consumed; 1987 if (state->pending == 0) { 1988 child->place = notInUse; 1989 state->place = afterGroup; 1990 return; 1991 } 1992 } 1993 1994 /* 1995 * Do the "before" field notification for next item in group. 1996 */ 1997 sec_asn1d_notify_before (state->top, child->dest, child->depth); 1998 1999 /* 2000 * Now we do the next one. 2001 */ 2002 sec_asn1d_scrub_state (child); 2003 2004 /* Initialize child state from the template */ 2005 sec_asn1d_init_state_based_on_template(child, buf /* __APPLE__ */); 2006 2007 state->top->current = child; 2008} 2009 2010 2011/* 2012 * We are moving along through a sequence; move forward by one, 2013 * (detecting end-of-sequence when it happens). 2014 * XXX The handling of "missing" is ugly. Fix it. 2015 */ 2016static void 2017sec_asn1d_next_in_sequence (sec_asn1d_state *state, 2018 const char *buf /* __APPLE__ */) 2019{ 2020 sec_asn1d_state *child; 2021 unsigned long child_consumed; 2022 PRBool child_missing; 2023 2024 PORT_Assert (state->place == duringSequence); 2025 PORT_Assert (state->child != NULL); 2026 2027 child = state->child; 2028 2029 /* 2030 * Do the "after" field notification. 2031 */ 2032 sec_asn1d_notify_after (state->top, child->dest, child->depth); 2033 2034 child_missing = (PRBool) child->missing; 2035 child_consumed = child->consumed; 2036 child->consumed = 0; 2037 2038 /* 2039 * Take care of accounting. 2040 */ 2041 if (child_missing) { 2042 PORT_Assert (child->optional); 2043 } else { 2044 state->consumed += child_consumed; 2045 /* 2046 * Free any grandchild. 2047 */ 2048 sec_asn1d_free_child (child, PR_FALSE); 2049 if (state->pending) { 2050 PORT_Assert (!state->indefinite); 2051 if( child_consumed > state->pending ) { 2052 dprintf("decodeError: next_in_seq consumed > pend\n"); 2053 PORT_SetError (SEC_ERROR_BAD_DER); 2054 state->top->status = decodeError; 2055 return; 2056 } 2057 state->pending -= child_consumed; 2058 if (state->pending == 0) { 2059 child->theTemplate++; 2060 while (child->theTemplate->kind != 0) { 2061 if ((child->theTemplate->kind & SEC_ASN1_OPTIONAL) == 0) { 2062 dprintf("decodeError: next_in_seq child not opt\n"); 2063 PORT_SetError (SEC_ERROR_BAD_DER); 2064 state->top->status = decodeError; 2065 return; 2066 } 2067 child->theTemplate++; 2068 } 2069 child->place = notInUse; 2070 state->place = afterEndOfContents; 2071 return; 2072 } 2073 } 2074 } 2075 2076 /* 2077 * Move forward. 2078 */ 2079 child->theTemplate++; 2080 if (child->theTemplate->kind == 0) { 2081 /* 2082 * We are done with this sequence. 2083 */ 2084 child->place = notInUse; 2085 if (state->pending) { 2086 dprintf("decodeError: next_in_seq notInUse still pending\n"); 2087 PORT_SetError (SEC_ERROR_BAD_DER); 2088 state->top->status = decodeError; 2089 } else if (child_missing) { 2090 /* 2091 * We got to the end, but have a child that started parsing 2092 * and ended up "missing". The only legitimate reason for 2093 * this is that we had one or more optional fields at the 2094 * end of our sequence, and we were encoded indefinite-length, 2095 * so when we went looking for those optional fields we 2096 * found our end-of-contents octets instead. 2097 * (Yes, this is ugly; dunno a better way to handle it.) 2098 * So, first confirm the situation, and then mark that we 2099 * are done. 2100 */ 2101 if (state->indefinite && child->endofcontents) { 2102 PORT_Assert (child_consumed == 2); 2103 if( child_consumed != 2 ) { 2104 dprintf("decodeError: next_in_seq indef len != 2\n"); 2105 PORT_SetError (SEC_ERROR_BAD_DER); 2106 state->top->status = decodeError; 2107 } else { 2108 state->consumed += child_consumed; 2109 state->place = afterEndOfContents; 2110 } 2111 } else { 2112 dprintf("decodeError: next_in_seq !indef, child missing\n"); 2113 PORT_SetError (SEC_ERROR_BAD_DER); 2114 state->top->status = decodeError; 2115 } 2116 } else { 2117 /* 2118 * We have to finish out, maybe reading end-of-contents octets; 2119 * let the normal logic do the right thing. 2120 */ 2121 state->place = beforeEndOfContents; 2122 } 2123 } else { 2124 unsigned char child_found_tag_modifiers = 0; 2125 unsigned long child_found_tag_number = 0; 2126 2127 /* 2128 * Reset state and push. 2129 */ 2130 if (state->dest != NULL) 2131 child->dest = (char *)state->dest + child->theTemplate->offset; 2132 2133 /* 2134 * Do the "before" field notification. 2135 */ 2136 sec_asn1d_notify_before (state->top, child->dest, child->depth); 2137 2138 if (child_missing) { /* if previous child was missing, copy the tag data we already have */ 2139 child_found_tag_modifiers = child->found_tag_modifiers; 2140 child_found_tag_number = child->found_tag_number; 2141 } 2142 state->top->current = child; 2143 child = sec_asn1d_init_state_based_on_template (child, 2144 buf /* __APPLE__ */); 2145 if (child_missing && child) { 2146 child->place = afterIdentifier; 2147 child->found_tag_modifiers = child_found_tag_modifiers; 2148 child->found_tag_number = child_found_tag_number; 2149 child->consumed = child_consumed; 2150 if (child->underlying_kind == SEC_ASN1_ANY 2151 && !child->top->filter_only) { 2152 /* 2153 * If the new field is an ANY, and we are storing, then 2154 * we need to save the tag out. We would have done this 2155 * already in the normal case, but since we were looking 2156 * for an optional field, and we did not find it, we only 2157 * now realize we need to save the tag. 2158 */ 2159 unsigned char identifier; 2160 2161 /* 2162 * Check that we did not end up with a high tag; for that 2163 * we need to re-encode the tag into multiple bytes in order 2164 * to store it back to look like what we parsed originally. 2165 * In practice this does not happen, but for completeness 2166 * sake it should probably be made to work at some point. 2167 */ 2168 PORT_Assert (child_found_tag_number < SEC_ASN1_HIGH_TAG_NUMBER); 2169 identifier = (unsigned char)(child_found_tag_modifiers | child_found_tag_number); 2170 sec_asn1d_record_any_header (child, (char *) &identifier, 1); 2171 } 2172 } 2173 } 2174} 2175 2176 2177static void 2178sec_asn1d_concat_substrings (sec_asn1d_state *state) 2179{ 2180 PORT_Assert (state->place == afterConstructedString); 2181 2182 if (state->subitems_head != NULL) { 2183 struct subitem *substring; 2184 unsigned long alloc_len, item_len; 2185 unsigned char *where; 2186 SecAsn1Item *item; 2187 PRBool is_bit_string; 2188 2189 item_len = 0; 2190 is_bit_string = (state->underlying_kind == SEC_ASN1_BIT_STRING) 2191 ? PR_TRUE : PR_FALSE; 2192 2193 substring = state->subitems_head; 2194 while (substring != NULL) { 2195 /* 2196 * All bit-string substrings except the last one should be 2197 * a clean multiple of 8 bits. 2198 */ 2199 if (is_bit_string && (substring->next == NULL) 2200 && (substring->len & 0x7)) { 2201 dprintf("decodeError: sec_asn1d_concat_substrings align\n"); 2202 PORT_SetError (SEC_ERROR_BAD_DER); 2203 state->top->status = decodeError; 2204 return; 2205 } 2206 item_len += substring->len; 2207 substring = substring->next; 2208 } 2209 2210 if (is_bit_string) { 2211#ifdef XP_WIN16 /* win16 compiler gets an internal error otherwise */ 2212 alloc_len = (((long)item_len + 7) / 8); 2213#else 2214 alloc_len = ((item_len + 7) >> 3); 2215#endif 2216 } else { 2217 /* 2218 * Add 2 for the end-of-contents octets of an indefinite-length 2219 * ANY that is *not* also an INNER. Because we zero-allocate 2220 * below, all we need to do is increase the length here. 2221 */ 2222 if (state->underlying_kind == SEC_ASN1_ANY && state->indefinite) 2223 item_len += 2; 2224 alloc_len = item_len; 2225 } 2226 2227 item = (SecAsn1Item *)(state->dest); 2228 PORT_Assert (item != NULL); 2229 PORT_Assert (item->Data == NULL); 2230 item->Data = (unsigned char*)sec_asn1d_zalloc (state->top->their_pool, 2231 alloc_len); 2232 if (item->Data == NULL) { 2233 dprintf("decodeError: zalloc\n"); 2234 state->top->status = decodeError; 2235 return; 2236 } 2237 item->Length = item_len; 2238 2239 where = item->Data; 2240 substring = state->subitems_head; 2241 while (substring != NULL) { 2242 if (is_bit_string) 2243 item_len = (substring->len + 7) >> 3; 2244 else 2245 item_len = substring->len; 2246 PORT_Memcpy (where, substring->data, item_len); 2247 where += item_len; 2248 substring = substring->next; 2249 } 2250 2251 /* 2252 * Because we use arenas and have a mark set, we later free 2253 * everything we have allocated, so this does *not* present 2254 * a memory leak (it is just temporarily left dangling). 2255 */ 2256 state->subitems_head = state->subitems_tail = NULL; 2257 } 2258 2259 state->place = afterEndOfContents; 2260} 2261 2262 2263static void 2264sec_asn1d_concat_group (sec_asn1d_state *state) 2265{ 2266 const void ***placep; 2267 2268 PORT_Assert (state->place == afterGroup); 2269 2270 placep = (const void***)state->dest; 2271 PORT_Assert(state->subitems_head == NULL || placep != NULL); 2272 if (placep != NULL) { 2273 struct subitem *item; 2274 const void **group; 2275 int count; 2276 2277 count = 0; 2278 item = state->subitems_head; 2279 while (item != NULL) { 2280 PORT_Assert (item->next != NULL || item == state->subitems_tail); 2281 count++; 2282 item = item->next; 2283 } 2284 2285 group = (const void**)sec_asn1d_zalloc (state->top->their_pool, 2286 (count + 1) * (sizeof(void *))); 2287 if (group == NULL) { 2288 dprintf("decodeError: zalloc\n"); 2289 state->top->status = decodeError; 2290 return; 2291 } 2292 2293 *placep = group; 2294 2295 item = state->subitems_head; 2296 while (item != NULL) { 2297 *group++ = item->data; 2298 item = item->next; 2299 } 2300 *group = NULL; 2301 2302 /* 2303 * Because we use arenas and have a mark set, we later free 2304 * everything we have allocated, so this does *not* present 2305 * a memory leak (it is just temporarily left dangling). 2306 */ 2307 state->subitems_head = state->subitems_tail = NULL; 2308 } 2309 2310 state->place = afterEndOfContents; 2311} 2312 2313/* 2314 * For those states that push a child to handle a subtemplate, 2315 * "absorb" that child (transfer necessary information). 2316 */ 2317static void 2318sec_asn1d_absorb_child (sec_asn1d_state *state) 2319{ 2320 /* 2321 * There is absolutely supposed to be a child there. 2322 */ 2323 PORT_Assert (state->child != NULL); 2324 2325 /* 2326 * Inherit the missing status of our child, and do the ugly 2327 * backing-up if necessary. 2328 */ 2329 state->missing = state->child->missing; 2330 if (state->missing) { 2331 state->found_tag_number = state->child->found_tag_number; 2332 state->found_tag_modifiers = state->child->found_tag_modifiers; 2333 state->endofcontents = state->child->endofcontents; 2334 } 2335 2336 /* 2337 * Add in number of bytes consumed by child. 2338 * (Only EXPLICIT should have already consumed bytes itself.) 2339 */ 2340 PORT_Assert (state->place == afterExplicit || state->consumed == 0); 2341 state->consumed += state->child->consumed; 2342 2343 /* 2344 * Subtract from bytes pending; this only applies to a definite-length 2345 * EXPLICIT field. 2346 */ 2347 if (state->pending) { 2348 PORT_Assert (!state->indefinite); 2349 PORT_Assert (state->place == afterExplicit); 2350 2351 /* 2352 * If we had a definite-length explicit, then what the child 2353 * consumed should be what was left pending. 2354 */ 2355 if (state->pending != state->child->consumed) { 2356 if (state->pending < state->child->consumed) { 2357 dprintf("decodeError: absorb_child pending < consumed\n"); 2358 PORT_SetError (SEC_ERROR_BAD_DER); 2359 state->top->status = decodeError; 2360 return; 2361 } 2362 /* 2363 * Okay, this is a hack. It *should* be an error whether 2364 * pending is too big or too small, but it turns out that 2365 * we had a bug in our *old* DER encoder that ended up 2366 * counting an explicit header twice in the case where 2367 * the underlying type was an ANY. So, because we cannot 2368 * prevent receiving these (our own certificate server can 2369 * send them to us), we need to be lenient and accept them. 2370 * To do so, we need to pretend as if we read all of the 2371 * bytes that the header said we would find, even though 2372 * we actually came up short. 2373 */ 2374 state->consumed += (state->pending - state->child->consumed); 2375 } 2376 state->pending = 0; 2377 } 2378 2379 /* 2380 * Indicate that we are done with child. 2381 */ 2382 state->child->consumed = 0; 2383 2384 /* 2385 * And move on to final state. 2386 * (Technically everybody could move to afterEndOfContents except 2387 * for an indefinite-length EXPLICIT; for simplicity though we assert 2388 * that but let the end-of-contents code do the real determination.) 2389 */ 2390 PORT_Assert (state->place == afterExplicit || (! state->indefinite)); 2391 state->place = beforeEndOfContents; 2392} 2393 2394 2395static void 2396sec_asn1d_prepare_for_end_of_contents (sec_asn1d_state *state) 2397{ 2398 PORT_Assert (state->place == beforeEndOfContents); 2399 2400 if (state->indefinite) { 2401 state->place = duringEndOfContents; 2402 state->pending = 2; 2403 } else { 2404 state->place = afterEndOfContents; 2405 } 2406} 2407 2408 2409static unsigned long 2410sec_asn1d_parse_end_of_contents (sec_asn1d_state *state, 2411 const char *buf, unsigned long len) 2412{ 2413 unsigned int i; 2414 2415 PORT_Assert (state->pending <= 2); 2416 PORT_Assert (state->place == duringEndOfContents); 2417 2418 if (len == 0) { 2419 state->top->status = needBytes; 2420 return 0; 2421 } 2422 2423 if (state->pending < len) 2424 len = state->pending; 2425 2426 for (i = 0; i < len; i++) { 2427 if (buf[i] != 0) { 2428 /* 2429 * We expect to find only zeros; if not, just give up. 2430 */ 2431 dprintf("decodeError: end of contents non zero\n"); 2432 PORT_SetError (SEC_ERROR_BAD_DER); 2433 state->top->status = decodeError; 2434 return 0; 2435 } 2436 } 2437 2438 state->pending -= len; 2439 2440 if (state->pending == 0) { 2441 state->place = afterEndOfContents; 2442 state->endofcontents = PR_TRUE; 2443 } 2444 2445 return len; 2446} 2447 2448 2449static void 2450sec_asn1d_pop_state (sec_asn1d_state *state) 2451{ 2452#if 0 /* XXX I think this should always be handled explicitly by parent? */ 2453 /* 2454 * Account for our child. 2455 */ 2456 if (state->child != NULL) { 2457 state->consumed += state->child->consumed; 2458 if (state->pending) { 2459 PORT_Assert (!state->indefinite); 2460 if( state->child->consumed > state->pending ) { 2461 dprintf("decodeError: pop_state pending < consumed\n"); 2462 PORT_SetError (SEC_ERROR_BAD_DER); 2463 state->top->status = decodeError; 2464 } else { 2465 state->pending -= state->child->consumed; 2466 } 2467 } 2468 state->child->consumed = 0; 2469 } 2470#endif /* XXX */ 2471 2472 /* 2473 * Free our child. 2474 */ 2475 sec_asn1d_free_child (state, PR_FALSE); 2476 2477 /* 2478 * Just make my parent be the current state. It will then clean 2479 * up after me and free me (or reuse me). 2480 */ 2481 state->top->current = state->parent; 2482} 2483 2484static sec_asn1d_state * 2485sec_asn1d_before_choice (sec_asn1d_state *state, const char *buf /* __APPLE__ */) 2486{ 2487 sec_asn1d_state *child; 2488 2489 if( state->allocate ) { 2490 void *dest; 2491 2492 dest = sec_asn1d_zalloc(state->top->their_pool, 2493 state->theTemplate->size); 2494 if( (void *)NULL == dest ) { 2495 dprintf("decodeError: zalloc\n"); 2496 state->top->status = decodeError; 2497 return (sec_asn1d_state *)NULL; 2498 } 2499 2500 state->dest = (char *)dest + state->theTemplate->offset; 2501 } 2502 2503 child = sec_asn1d_push_state(state->top, state->theTemplate + 1, 2504 (char *)state->dest - state->theTemplate->offset, 2505 PR_FALSE); 2506 if( (sec_asn1d_state *)NULL == child ) { 2507 return (sec_asn1d_state *)NULL; 2508 } 2509 2510 sec_asn1d_scrub_state(child); 2511 child = sec_asn1d_init_state_based_on_template(child, 2512 buf /* __APPLE__ */); 2513 if( (sec_asn1d_state *)NULL == child ) { 2514 return (sec_asn1d_state *)NULL; 2515 } 2516 2517 child->optional = PR_TRUE; 2518 2519 state->place = duringChoice; 2520 2521 return child; 2522} 2523 2524static sec_asn1d_state * 2525sec_asn1d_during_choice (sec_asn1d_state *state, const char *buf /* __APPLE__ */) 2526{ 2527 sec_asn1d_state *child = state->child; 2528 2529 PORT_Assert((sec_asn1d_state *)NULL != child); 2530 2531 if( child->missing ) { 2532 unsigned char child_found_tag_modifiers = 0; 2533 unsigned long child_found_tag_number = 0; 2534 void * dest; 2535 2536 state->consumed += child->consumed; 2537 2538 if (child->endofcontents) { 2539 /* This choice is probably the first item in a GROUP 2540 ** (e.g. SET_OF) that was indefinite-length encoded. 2541 ** We're actually at the end of that GROUP. 2542 ** We look up the stack to be sure that we find 2543 ** a state with indefinite length encoding before we 2544 ** find a state (like a SEQUENCE) that is definite. 2545 */ 2546 child->place = notInUse; 2547 state->place = afterChoice; 2548 state->endofcontents = PR_TRUE; /* propagate this up */ 2549 if (sec_asn1d_parent_allows_EOC(state)) 2550 return state; 2551 dprintf("decodeError: during_choice child at EOC by parent does not allow EOC\n"); 2552 PORT_SetError(SEC_ERROR_BAD_DER); 2553 state->top->status = decodeError; 2554 return NULL; 2555 } 2556 2557 dest = (char *)child->dest - child->theTemplate->offset; 2558 child->theTemplate++; 2559 2560 if( 0 == child->theTemplate->kind ) { 2561 /* Ran out of choices */ 2562 dprintf("decodeError: during_choice ran out of choice\n"); 2563 PORT_SetError(SEC_ERROR_BAD_DER); 2564 state->top->status = decodeError; 2565 return (sec_asn1d_state *)NULL; 2566 } 2567 child->dest = (char *)dest + child->theTemplate->offset; 2568 2569 /* cargo'd from next_in_sequence innards */ 2570 if( state->pending ) { 2571 PORT_Assert(!state->indefinite); 2572 if( child->consumed > state->pending ) { 2573 dprintf("decodeError: during_choice consumed > pending\n"); 2574 PORT_SetError (SEC_ERROR_BAD_DER); 2575 state->top->status = decodeError; 2576 return NULL; 2577 } 2578 state->pending -= child->consumed; 2579 if( 0 == state->pending ) { 2580 /* XXX uh.. not sure if I should have stopped this 2581 * from happening before. */ 2582 PORT_Assert(0); 2583 PORT_SetError(SEC_ERROR_BAD_DER); 2584 dprintf("decodeError: during_choice !pending\n"); 2585 state->top->status = decodeError; 2586 return (sec_asn1d_state *)NULL; 2587 } 2588 } 2589 2590 child->consumed = 0; 2591 sec_asn1d_scrub_state(child); 2592 2593 /* move it on top again */ 2594 state->top->current = child; 2595 2596 child_found_tag_modifiers = child->found_tag_modifiers; 2597 child_found_tag_number = child->found_tag_number; 2598 2599 child = sec_asn1d_init_state_based_on_template(child, buf /* __APPLE__*/); 2600 if( (sec_asn1d_state *)NULL == child ) { 2601 return (sec_asn1d_state *)NULL; 2602 } 2603 2604 /* copy our findings to the new top */ 2605 child->found_tag_modifiers = child_found_tag_modifiers; 2606 child->found_tag_number = child_found_tag_number; 2607 2608 child->optional = PR_TRUE; 2609 child->place = afterIdentifier; 2610 2611 return child; 2612 } 2613 if( (void *)NULL != state->dest ) { 2614 /* Store the enum */ 2615 int *which = (int *)state->dest; 2616 *which = (int)child->theTemplate->size; 2617 } 2618 2619 child->place = notInUse; 2620 2621 state->place = afterChoice; 2622 return state; 2623} 2624 2625static void 2626sec_asn1d_after_choice (sec_asn1d_state *state) 2627{ 2628 state->consumed += state->child->consumed; 2629 state->child->consumed = 0; 2630 state->place = afterEndOfContents; 2631 sec_asn1d_pop_state(state); 2632} 2633 2634#if 0 2635unsigned long 2636sec_asn1d_uinteger(SecAsn1Item *src) 2637{ 2638 unsigned long value; 2639 int len; 2640 2641 if (src->Length > 5 || (src->Length > 4 && src->Data[0] == 0)) 2642 return 0; 2643 2644 value = 0; 2645 len = src->Length; 2646 while (len) { 2647 value <<= 8; 2648 value |= src->Data[--len]; 2649 } 2650 return value; 2651} 2652#endif 2653 2654SECStatus 2655SEC_ASN1DecodeInteger(SecAsn1Item *src, unsigned long *value) 2656{ 2657 unsigned long v; 2658 unsigned int i; 2659 2660 if (src == NULL) { 2661 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2662 return SECFailure; 2663 } 2664 2665 if (src->Length > sizeof(unsigned long)) { 2666 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2667 return SECFailure; 2668 } 2669 2670 if (src->Data == NULL) { 2671 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2672 return SECFailure; 2673 } 2674 2675 if (src->Data[0] & 0x80) 2676 v = -1; /* signed and negative - start with all 1's */ 2677 else 2678 v = 0; 2679 2680 for (i= 0; i < src->Length; i++) { 2681 /* shift in next byte */ 2682 v <<= 8; 2683 v |= src->Data[i]; 2684 } 2685 *value = v; 2686 return SECSuccess; 2687} 2688 2689#ifdef DEBUG_ASN1D_STATES 2690static void 2691dump_states(SEC_ASN1DecoderContext *cx) 2692{ 2693 sec_asn1d_state *state; 2694 char kindBuf[256]; 2695 2696 for (state = cx->current; state->parent; state = state->parent) { 2697 ; 2698 } 2699 2700 for (; state; state = state->child) { 2701 int i; 2702 for (i = 0; i < state->depth; i++) { 2703 printf(" "); 2704 } 2705 2706 i = formatKind(state->theTemplate->kind, kindBuf); 2707 printf("%s: tmpl %p, kind%s", 2708 (state == cx->current) ? "STATE" : "State", 2709 state->theTemplate, 2710 kindBuf); 2711 printf(" %s", (state->place <= notInUse) 2712 ? place_names[ state->place ] 2713 : "(undefined)"); 2714 if (!i) 2715 printf(", expect 0x%02lx", 2716 state->expect_tag_number | state->expect_tag_modifiers); 2717 2718 printf("%s%s%s %lu\n", 2719 state->indefinite ? ", indef" : "", 2720 state->missing ? ", miss" : "", 2721 state->endofcontents ? ", EOC" : "", 2722 state->pending 2723 ); 2724 } 2725 2726 return; 2727} 2728#endif /* DEBUG_ASN1D_STATES */ 2729 2730SECStatus 2731SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, 2732 const char *buf, size_t len) 2733{ 2734 sec_asn1d_state *state = NULL; 2735 unsigned long consumed; 2736 SEC_ASN1EncodingPart what; 2737 sec_asn1d_state *stateEnd = cx->current; 2738 2739 if (cx->status == needBytes) 2740 cx->status = keepGoing; 2741 2742 while (cx->status == keepGoing) { 2743 state = cx->current; 2744 what = SEC_ASN1_Contents; 2745 consumed = 0; 2746 #if DEBUG_ASN1D_STATES 2747 if (doDumpStates > 1) { 2748 printf("\nPLACE = %s, next byte = 0x%02x, %p[%lu]\n", 2749 (state->place <= notInUse) ? 2750 place_names[ state->place ] : "(undefined)", 2751 (unsigned int)((unsigned char *)buf)[ consumed ], 2752 buf, consumed); 2753 dump_states(cx); 2754 } 2755 #endif /* DEBUG_ASN1D_STATES */ 2756 switch (state->place) { 2757 case beforeIdentifier: 2758 consumed = sec_asn1d_parse_identifier (state, buf, len); 2759 what = SEC_ASN1_Identifier; 2760 break; 2761 case duringIdentifier: 2762 consumed = sec_asn1d_parse_more_identifier (state, buf, len); 2763 what = SEC_ASN1_Identifier; 2764 break; 2765 case afterIdentifier: 2766 sec_asn1d_confirm_identifier (state); 2767 break; 2768 case beforeLength: 2769 consumed = sec_asn1d_parse_length (state, buf, len); 2770 what = SEC_ASN1_Length; 2771 break; 2772 case duringLength: 2773 consumed = sec_asn1d_parse_more_length (state, buf, len); 2774 what = SEC_ASN1_Length; 2775 break; 2776 case afterLength: 2777 sec_asn1d_prepare_for_contents (state, buf); 2778 break; 2779 case beforeBitString: 2780 consumed = sec_asn1d_parse_bit_string (state, buf, len); 2781 break; 2782 case duringBitString: 2783 consumed = sec_asn1d_parse_more_bit_string (state, buf, len); 2784 break; 2785 case duringConstructedString: 2786 sec_asn1d_next_substring (state); 2787 break; 2788 case duringGroup: 2789 sec_asn1d_next_in_group (state, buf); 2790 break; 2791 case duringLeaf: 2792 consumed = sec_asn1d_parse_leaf (state, buf, len); 2793 break; 2794 case duringSaveEncoding: 2795 sec_asn1d_reuse_encoding (state); 2796 if (cx->status == decodeError) { 2797 /* recursive call has already popped all states from stack. 2798 ** Bail out quickly. 2799 */ 2800 return SECFailure; 2801 } 2802 if (cx->status == needBytes) { 2803 /* recursive call wanted more data. Fatal. Clean up below. */ 2804 PORT_SetError (SEC_ERROR_BAD_DER); 2805 cx->status = decodeError; 2806 } 2807 break; 2808 case duringSequence: 2809 sec_asn1d_next_in_sequence (state, buf); 2810 break; 2811 case afterConstructedString: 2812 sec_asn1d_concat_substrings (state); 2813 break; 2814 case afterExplicit: 2815 case afterImplicit: 2816 case afterInline: 2817 case afterPointer: 2818 sec_asn1d_absorb_child (state); 2819 break; 2820 case afterGroup: 2821 sec_asn1d_concat_group (state); 2822 break; 2823 case afterSaveEncoding: 2824 /* SEC_ASN1DecoderUpdate has called itself recursively to 2825 ** decode SAVEd encoded data, and now is done decoding that. 2826 ** Return to the calling copy of SEC_ASN1DecoderUpdate. 2827 */ 2828 return SECSuccess; 2829 case beforeEndOfContents: 2830 sec_asn1d_prepare_for_end_of_contents (state); 2831 break; 2832 case duringEndOfContents: 2833 consumed = sec_asn1d_parse_end_of_contents (state, buf, len); 2834 what = SEC_ASN1_EndOfContents; 2835 break; 2836 case afterEndOfContents: 2837 sec_asn1d_pop_state (state); 2838 break; 2839 case beforeChoice: 2840 state = sec_asn1d_before_choice(state, buf); 2841 break; 2842 case duringChoice: 2843 state = sec_asn1d_during_choice(state, buf); 2844 break; 2845 case afterChoice: 2846 sec_asn1d_after_choice(state); 2847 break; 2848 case notInUse: 2849 default: 2850 /* This is not an error, but rather a plain old BUG! */ 2851 PORT_Assert (0); 2852 PORT_SetError (SEC_ERROR_BAD_DER); 2853 dprintf("decodeError: decoder update bad state->place\n"); 2854 cx->status = decodeError; 2855 break; 2856 } 2857 2858 if (cx->status == decodeError) 2859 break; 2860 2861 /* We should not consume more than we have. */ 2862 PORT_Assert (consumed <= len); 2863 if( consumed > len ) { 2864 dprintf("decodeError: decoder update consumed > len\n"); 2865 PORT_SetError (SEC_ERROR_BAD_DER); 2866 cx->status = decodeError; 2867 break; 2868 } 2869 2870 /* It might have changed, so we have to update our local copy. */ 2871 state = cx->current; 2872 2873 /* If it is NULL, we have popped all the way to the top. */ 2874 if (state == NULL) { 2875 PORT_Assert (consumed == 0); 2876 #if 0 2877 /* XXX I want this here, but it seems that we have situations (like 2878 * downloading a pkcs7 cert chain from some issuers) that give us a 2879 * length which is greater than the entire encoding. So, we cannot 2880 * have this be an error. 2881 */ 2882 if (len > 0) { 2883 dprintf("decodeError: decoder update nonzero len\n"); 2884 PORT_SetError (SEC_ERROR_BAD_DER); 2885 cx->status = decodeError; 2886 } 2887 else 2888 #endif 2889 cx->status = allDone; 2890 break; 2891 } 2892 else if (state->theTemplate->kind == SEC_ASN1_SKIP_REST) { 2893 cx->status = allDone; 2894 break; 2895 } 2896 2897 if (consumed == 0) 2898 continue; 2899 2900 /* 2901 * The following check is specifically looking for an ANY 2902 * that is *not* also an INNER, because we need to save aside 2903 * all bytes in that case -- the contents parts will get 2904 * handled like all other contents, and the end-of-contents 2905 * bytes are added by the concat code, but the outer header 2906 * bytes need to get saved too, so we do them explicitly here. 2907 */ 2908 if (state->underlying_kind == SEC_ASN1_ANY 2909 && !cx->filter_only && (what == SEC_ASN1_Identifier 2910 || what == SEC_ASN1_Length)) { 2911 sec_asn1d_record_any_header (state, buf, consumed); 2912 } 2913 2914 /* 2915 * We had some number of good, accepted bytes. If the caller 2916 * has registered to see them, pass them along. 2917 */ 2918 if (state->top->filter_proc != NULL) { 2919 int depth; 2920 2921 depth = state->depth; 2922 if (what == SEC_ASN1_EndOfContents && !state->indefinite) { 2923 PORT_Assert (state->parent != NULL 2924 && state->parent->indefinite); 2925 depth--; 2926 PORT_Assert (depth == state->parent->depth); 2927 } 2928 (* state->top->filter_proc) (state->top->filter_arg, 2929 buf, consumed, depth, what); 2930 } 2931 2932 state->consumed += consumed; 2933 buf += consumed; 2934 len -= consumed; 2935 } /* main decode loop */ 2936 2937 if (cx->status == decodeError) { 2938 while (state != NULL && stateEnd->parent!=state) { 2939 sec_asn1d_free_child (state, PR_TRUE); 2940 state = state->parent; 2941 } 2942#ifdef SEC_ASN1D_FREE_ON_ERROR /* 2943 * XXX This does not work because we can 2944 * end up leaving behind dangling pointers 2945 * to stuff that was allocated. In order 2946 * to make this really work (which would 2947 * be a good thing, I think), we need to 2948 * keep track of every place/pointer that 2949 * was allocated and make sure to NULL it 2950 * out before we then free back to the mark. 2951 */ 2952 if (cx->their_pool != NULL) { 2953 PORT_Assert (cx->their_mark != NULL); 2954 PORT_ArenaRelease (cx->their_pool, cx->their_mark); 2955 } 2956#endif 2957 return SECFailure; 2958 } 2959 2960#if 0 2961 /* XXX This is what I want, but cannot have because it seems we 2962 * have situations (like when downloading a pkcs7 cert chain from 2963 * some issuers) that give us a total length which is greater than 2964 * the entire encoding. So, we have to allow allDone to have a 2965 * remaining length greater than zero. I wanted to catch internal 2966 * bugs with this, noticing when we do not have the right length. 2967 * Oh well. 2968 */ 2969 PORT_Assert (len == 0 2970 && (cx->status == needBytes || cx->status == allDone)); 2971#else 2972 PORT_Assert ((len == 0 && cx->status == needBytes) 2973 || cx->status == allDone); 2974#endif 2975 return SECSuccess; 2976} 2977 2978 2979SECStatus 2980SEC_ASN1DecoderFinish (SEC_ASN1DecoderContext *cx) 2981{ 2982 SECStatus rv; 2983 2984 if (cx->status == needBytes) { 2985 #ifdef __APPLE__ 2986 /* 2987 * Special case: need more bytes, but this field and all 2988 * subsequent fields are optional. I'm surprised this case is 2989 * not handled in the original NSS code, and this workaround 2990 * is a bit of a hack... 2991 */ 2992 sec_asn1d_state *state = cx->current; 2993 assert(state != NULL); 2994 if(state->place == beforeIdentifier) { 2995 int allOptional = 1; 2996 const SecAsn1Template *templ = state->theTemplate; 2997 while(templ->kind != 0) { 2998 if(!(templ->kind & SEC_ASN1_OPTIONAL)) { 2999 allOptional = 0; 3000 break; 3001 } 3002 templ++; 3003 } 3004 if(allOptional) { 3005 /* letting this one slide */ 3006 rv = SECSuccess; 3007 } 3008 else { 3009 PORT_SetError (SEC_ERROR_BAD_DER); 3010 rv = SECFailure; 3011 } 3012 } 3013 else { 3014 PORT_SetError (SEC_ERROR_BAD_DER); 3015 rv = SECFailure; 3016 } 3017 #else 3018 PORT_SetError (SEC_ERROR_BAD_DER); 3019 rv = SECFailure; 3020 #endif /* __APPLE__ */ 3021 } else { 3022 rv = SECSuccess; 3023 } 3024 3025 /* 3026 * XXX anything else that needs to be finished? 3027 */ 3028 3029 PORT_FreeArena (cx->our_pool, PR_FALSE); 3030 3031 return rv; 3032} 3033 3034 3035SEC_ASN1DecoderContext * 3036SEC_ASN1DecoderStart (PRArenaPool *their_pool, void *dest, 3037 const SecAsn1Template *theTemplate 3038 #ifdef __APPLE__ 3039 , 3040 /* only needed if first element will be SEC_ASN1_DYNAMIC */ 3041 const char *buf 3042 #endif 3043 ) 3044{ 3045 PRArenaPool *our_pool; 3046 SEC_ASN1DecoderContext *cx; 3047 3048 our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); 3049 if (our_pool == NULL) 3050 return NULL; 3051 3052 cx = (SEC_ASN1DecoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx)); 3053 if (cx == NULL) { 3054 PORT_FreeArena (our_pool, PR_FALSE); 3055 return NULL; 3056 } 3057 3058 cx->our_pool = our_pool; 3059 if (their_pool != NULL) { 3060 cx->their_pool = their_pool; 3061#ifdef SEC_ASN1D_FREE_ON_ERROR 3062 cx->their_mark = PORT_ArenaMark (their_pool); 3063#endif 3064 } 3065 3066 cx->status = needBytes; 3067 3068 if (sec_asn1d_push_state(cx, theTemplate, dest, PR_FALSE) == NULL 3069 || sec_asn1d_init_state_based_on_template (cx->current, 3070 buf /* __APPLE__ */) == NULL) { 3071 /* 3072 * Trouble initializing (probably due to failed allocations) 3073 * requires that we just give up. 3074 */ 3075 PORT_FreeArena (our_pool, PR_FALSE); 3076 return NULL; 3077 } 3078 3079 return cx; 3080} 3081 3082 3083void 3084SEC_ASN1DecoderSetFilterProc (SEC_ASN1DecoderContext *cx, 3085 SEC_ASN1WriteProc fn, void *arg, 3086 PRBool only) 3087{ 3088 /* check that we are "between" fields here */ 3089 PORT_Assert (cx->during_notify); 3090 3091 cx->filter_proc = fn; 3092 cx->filter_arg = arg; 3093 cx->filter_only = only; 3094} 3095 3096 3097void 3098SEC_ASN1DecoderClearFilterProc (SEC_ASN1DecoderContext *cx) 3099{ 3100 /* check that we are "between" fields here */ 3101 PORT_Assert (cx->during_notify); 3102 3103 cx->filter_proc = NULL; 3104 cx->filter_arg = NULL; 3105 cx->filter_only = PR_FALSE; 3106} 3107 3108 3109void 3110SEC_ASN1DecoderSetNotifyProc (SEC_ASN1DecoderContext *cx, 3111 SEC_ASN1NotifyProc fn, void *arg) 3112{ 3113 cx->notify_proc = fn; 3114 cx->notify_arg = arg; 3115} 3116 3117 3118void 3119SEC_ASN1DecoderClearNotifyProc (SEC_ASN1DecoderContext *cx) 3120{ 3121 cx->notify_proc = NULL; 3122 cx->notify_arg = NULL; /* not necessary; just being clean */ 3123} 3124 3125 3126void 3127SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error) 3128{ 3129 PORT_Assert(cx); 3130 PORT_SetError(error); 3131 cx->status = decodeError; 3132} 3133 3134 3135SECStatus 3136SEC_ASN1Decode (PRArenaPool *poolp, void *dest, 3137 const SecAsn1Template *theTemplate, 3138 const char *buf, size_t len) 3139{ 3140 SEC_ASN1DecoderContext *dcx; 3141 SECStatus urv, frv; 3142 3143 dcx = SEC_ASN1DecoderStart (poolp, dest, theTemplate, 3144 buf /* __APPLE__ */); 3145 if (dcx == NULL) 3146 return SECFailure; 3147 3148 urv = SEC_ASN1DecoderUpdate (dcx, buf, len); 3149 frv = SEC_ASN1DecoderFinish (dcx); 3150 3151 if (urv != SECSuccess) 3152 return urv; 3153 3154 return frv; 3155} 3156 3157 3158SECStatus 3159SEC_ASN1DecodeItem (PRArenaPool *poolp, void *dest, 3160 const SecAsn1Template *theTemplate, 3161 const SecAsn1Item *item) 3162{ 3163 return SEC_ASN1Decode (poolp, dest, theTemplate, 3164 (const char *) item->Data, item->Length); 3165} 3166 3167 3168