security/nss/lib/util/secasn1d.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished
     7  * Encoding Rules).
     8  */
    10 /* #define DEBUG_ASN1D_STATES 1 */
    12 #ifdef DEBUG_ASN1D_STATES
    13 #include <stdio.h>
    14 #define PR_Assert sec_asn1d_Assert
    15 #endif
    17 #include "secasn1.h"
    18 #include "secerr.h"
    20 typedef enum {
    21     beforeIdentifier,
    22     duringIdentifier,
    23     afterIdentifier,
    24     beforeLength,
    25     duringLength,
    26     afterLength,
    27     beforeBitString,
    28     duringBitString,
    29     duringConstructedString,
    30     duringGroup,
    31     duringLeaf,
    32     duringSaveEncoding,
    33     duringSequence,
    34     afterConstructedString,
    35     afterGroup,
    36     afterExplicit,
    37     afterImplicit,
    38     afterInline,
    39     afterPointer,
    40     afterSaveEncoding,
    41     beforeEndOfContents,
    42     duringEndOfContents,
    43     afterEndOfContents,
    44     beforeChoice,
    45     duringChoice,
    46     afterChoice,
    47     notInUse
    48 } sec_asn1d_parse_place;
    50 #ifdef DEBUG_ASN1D_STATES
    51 static const char * const place_names[] = {
    52     "beforeIdentifier",
    53     "duringIdentifier",
    54     "afterIdentifier",
    55     "beforeLength",
    56     "duringLength",
    57     "afterLength",
    58     "beforeBitString",
    59     "duringBitString",
    60     "duringConstructedString",
    61     "duringGroup",
    62     "duringLeaf",
    63     "duringSaveEncoding",
    64     "duringSequence",
    65     "afterConstructedString",
    66     "afterGroup",
    67     "afterExplicit",
    68     "afterImplicit",
    69     "afterInline",
    70     "afterPointer",
    71     "afterSaveEncoding",
    72     "beforeEndOfContents",
    73     "duringEndOfContents",
    74     "afterEndOfContents",
    75     "beforeChoice",
    76     "duringChoice",
    77     "afterChoice",
    78     "notInUse"
    79 };
    81 static const char * const class_names[] = {
    82     "UNIVERSAL",
    83     "APPLICATION",
    84     "CONTEXT_SPECIFIC",
    85     "PRIVATE"
    86 };
    88 static const char * const method_names[] = { "PRIMITIVE", "CONSTRUCTED" };
    90 static const char * const type_names[] = {
    91     "END_OF_CONTENTS",
    92     "BOOLEAN",
    93     "INTEGER",
    94     "BIT_STRING",
    95     "OCTET_STRING",
    96     "NULL",
    97     "OBJECT_ID",
    98     "OBJECT_DESCRIPTOR",
    99     "(type 08)",
   100     "REAL",
   101     "ENUMERATED",
   102     "EMBEDDED",
   103     "UTF8_STRING",
   104     "(type 0d)",
   105     "(type 0e)",
   106     "(type 0f)",
   107     "SEQUENCE",
   108     "SET",
   109     "NUMERIC_STRING",
   110     "PRINTABLE_STRING",
   111     "T61_STRING",
   112     "VIDEOTEXT_STRING",
   113     "IA5_STRING",
   114     "UTC_TIME",
   115     "GENERALIZED_TIME",
   116     "GRAPHIC_STRING",
   117     "VISIBLE_STRING",
   118     "GENERAL_STRING",
   119     "UNIVERSAL_STRING",
   120     "(type 1d)",
   121     "BMP_STRING",
   122     "HIGH_TAG_VALUE"
   123 };
   125 static const char * const flag_names[] = { /* flags, right to left */
   126     "OPTIONAL",
   127     "EXPLICIT",
   128     "ANY",
   129     "INLINE",
   130     "POINTER",
   131     "GROUP",
   132     "DYNAMIC",
   133     "SKIP",
   134     "INNER",
   135     "SAVE",
   136     "",            /* decoder ignores "MAY_STREAM", */
   137     "SKIP_REST",
   138     "CHOICE",
   139     "NO_STREAM",
   140     "DEBUG_BREAK",
   141     "unknown 08",
   142     "unknown 10",
   143     "unknown 20",
   144     "unknown 40",
   145     "unknown 80"
   146 };
   148 static int /* bool */
   149 formatKind(unsigned long kind, char * buf)
   150 {
   151     int i;
   152     unsigned long k = kind & SEC_ASN1_TAGNUM_MASK;
   153     unsigned long notag = kind & (SEC_ASN1_CHOICE | SEC_ASN1_POINTER |
   154         SEC_ASN1_INLINE | SEC_ASN1_ANY | SEC_ASN1_SAVE);
   156     buf[0] = 0;
   157     if ((kind & SEC_ASN1_CLASS_MASK) != SEC_ASN1_UNIVERSAL) {
   158         sprintf(buf, " %s", class_names[(kind & SEC_ASN1_CLASS_MASK) >> 6] );
   159         buf += strlen(buf);
   160     }
   161     if (kind & SEC_ASN1_METHOD_MASK) {
   162         sprintf(buf, " %s", method_names[1]);
   163         buf += strlen(buf);
   164     }
   165     if ((kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) {
   166         if (k || !notag) {
   167             sprintf(buf, " %s", type_names[k] );
   168             if ((k == SEC_ASN1_SET || k == SEC_ASN1_SEQUENCE) &&
   169                 (kind & SEC_ASN1_GROUP)) {
   170                 buf += strlen(buf);
   171                 sprintf(buf, "_OF");
   172             }
   173         }
   174     } else {
   175         sprintf(buf, " [%d]", k);
   176     }
   177     buf += strlen(buf);
   179     for (k = kind >> 8, i = 0; k; k >>= 1, ++i) {
   180         if (k & 1) {
   181             sprintf(buf, " %s", flag_names[i]);
   182             buf += strlen(buf);
   183         }
   184     }
   185     return notag != 0;
   186 }
   188 #endif /* DEBUG_ASN1D_STATES */
   190 typedef enum {
   191     allDone,
   192     decodeError,
   193     keepGoing,
   194     needBytes
   195 } sec_asn1d_parse_status;
   197 struct subitem {
   198     const void *data;
   199     unsigned long len;		/* only used for substrings */
   200     struct subitem *next;
   201 };
   203 typedef struct sec_asn1d_state_struct {
   204     SEC_ASN1DecoderContext *top;
   205     const SEC_ASN1Template *theTemplate;
   206     void *dest;
   208     void *our_mark;	/* free on completion */
   210     struct sec_asn1d_state_struct *parent;	/* aka prev */
   211     struct sec_asn1d_state_struct *child;	/* aka next */
   213     sec_asn1d_parse_place place;
   215     /*
   216      * XXX explain the next fields as clearly as possible...
   217      */
   218     unsigned char found_tag_modifiers;
   219     unsigned char expect_tag_modifiers;
   220     unsigned long check_tag_mask;
   221     unsigned long found_tag_number;
   222     unsigned long expect_tag_number;
   223     unsigned long underlying_kind;
   225     unsigned long contents_length;
   226     unsigned long pending;
   227     unsigned long consumed;
   229     int depth;
   231     /*
   232      * Bit strings have their length adjusted -- the first octet of the
   233      * contents contains a value between 0 and 7 which says how many bits
   234      * at the end of the octets are not actually part of the bit string;
   235      * when parsing bit strings we put that value here because we need it
   236      * later, for adjustment of the length (when the whole string is done).
   237      */
   238     unsigned int bit_string_unused_bits;
   240     /*
   241      * The following are used for indefinite-length constructed strings.
   242      */
   243     struct subitem *subitems_head;
   244     struct subitem *subitems_tail;
   246     PRPackedBool
   247 	allocate,	/* when true, need to allocate the destination */
   248 	endofcontents,	/* this state ended up parsing end-of-contents octets */
   249 	explicit,	/* we are handling an explicit header */
   250 	indefinite,	/* the current item has indefinite-length encoding */
   251 	missing,	/* an optional field that was not present */
   252 	optional,	/* the template says this field may be omitted */
   253 	substring;	/* this is a substring of a constructed string */
   255 } sec_asn1d_state;
   257 #define IS_HIGH_TAG_NUMBER(n)	((n) == SEC_ASN1_HIGH_TAG_NUMBER)
   258 #define LAST_TAG_NUMBER_BYTE(b)	(((b) & 0x80) == 0)
   259 #define TAG_NUMBER_BITS		7
   260 #define TAG_NUMBER_MASK		0x7f
   262 #define LENGTH_IS_SHORT_FORM(b)	(((b) & 0x80) == 0)
   263 #define LONG_FORM_LENGTH(b)	((b) & 0x7f)
   265 #define HIGH_BITS(field,cnt)	((field) >> ((sizeof(field) * 8) - (cnt)))
   268 /*
   269  * An "outsider" will have an opaque pointer to this, created by calling
   270  * SEC_ASN1DecoderStart().  It will be passed back in to all subsequent
   271  * calls to SEC_ASN1DecoderUpdate(), and when done it is passed to
   272  * SEC_ASN1DecoderFinish().
   273  */
   274 struct sec_DecoderContext_struct {
   275     PLArenaPool *our_pool;		/* for our internal allocs */
   276     PLArenaPool *their_pool;		/* for destination structure allocs */
   277 #ifdef SEC_ASN1D_FREE_ON_ERROR		/*
   278 					 * XXX see comment below (by same
   279 					 * ifdef) that explains why this
   280 					 * does not work (need more smarts
   281 					 * in order to free back to mark)
   282 					 */
   283     /*
   284      * XXX how to make their_mark work in the case where they do NOT
   285      * give us a pool pointer?
   286      */
   287     void *their_mark;			/* free on error */
   288 #endif
   290     sec_asn1d_state *current;
   291     sec_asn1d_parse_status status;
   293     SEC_ASN1NotifyProc notify_proc;	/* call before/after handling field */
   294     void *notify_arg;			/* argument to notify_proc */
   295     PRBool during_notify;		/* true during call to notify_proc */
   297     SEC_ASN1WriteProc filter_proc;	/* pass field bytes to this  */
   298     void *filter_arg;			/* argument to that function */
   299     PRBool filter_only;			/* do not allocate/store fields */
   300 };
   303 /*
   304  * XXX this is a fairly generic function that may belong elsewhere
   305  */
   306 static void *
   307 sec_asn1d_alloc (PLArenaPool *poolp, unsigned long len)
   308 {
   309     void *thing;
   311     if (poolp != NULL) {
   312 	/*
   313 	 * Allocate from the pool.
   314 	 */
   315 	thing = PORT_ArenaAlloc (poolp, len);
   316     } else {
   317 	/*
   318 	 * Allocate generically.
   319 	 */
   320 	thing = PORT_Alloc (len);
   321     }
   323     return thing;
   324 }
   327 /*
   328  * XXX this is a fairly generic function that may belong elsewhere
   329  */
   330 static void *
   331 sec_asn1d_zalloc (PLArenaPool *poolp, unsigned long len)
   332 {
   333     void *thing;
   335     thing = sec_asn1d_alloc (poolp, len);
   336     if (thing != NULL)
   337 	PORT_Memset (thing, 0, len);
   338     return thing;
   339 }
   342 static sec_asn1d_state *
   343 sec_asn1d_push_state (SEC_ASN1DecoderContext *cx,
   344 		      const SEC_ASN1Template *theTemplate,
   345 		      void *dest, PRBool new_depth)
   346 {
   347     sec_asn1d_state *state, *new_state;
   349     state = cx->current;
   351     PORT_Assert (state == NULL || state->child == NULL);
   353     if (state != NULL) {
   354 	PORT_Assert (state->our_mark == NULL);
   355 	state->our_mark = PORT_ArenaMark (cx->our_pool);
   356     }
   358     new_state = (sec_asn1d_state*)sec_asn1d_zalloc (cx->our_pool, 
   359 						    sizeof(*new_state));
   360     if (new_state == NULL) {
   361 	goto loser;
   362     }
   364     new_state->top         = cx;
   365     new_state->parent      = state;
   366     new_state->theTemplate = theTemplate;
   367     new_state->place       = notInUse;
   368     if (dest != NULL)
   369 	new_state->dest = (char *)dest + theTemplate->offset;
   371     if (state != NULL) {
   372 	new_state->depth = state->depth;
   373 	if (new_depth) {
   374 	    if (++new_state->depth > SEC_ASN1D_MAX_DEPTH) {
   375 		PORT_SetError (SEC_ERROR_BAD_DER);
   376 		goto loser;
   377 	    }
   378 	}
   379 	state->child = new_state;
   380     }
   382     cx->current = new_state;
   383     return new_state;
   385 loser:
   386     cx->status = decodeError;
   387     if (state != NULL) {
   388 	PORT_ArenaRelease(cx->our_pool, state->our_mark);
   389 	state->our_mark = NULL;
   390     }
   391     return NULL;
   392 }
   395 static void
   396 sec_asn1d_scrub_state (sec_asn1d_state *state)
   397 {
   398     /*
   399      * Some default "scrubbing".
   400      * XXX right set of initializations?
   401      */
   402     state->place = beforeIdentifier;
   403     state->endofcontents = PR_FALSE;
   404     state->indefinite = PR_FALSE;
   405     state->missing = PR_FALSE;
   406     PORT_Assert (state->consumed == 0);
   407 }
   410 static void
   411 sec_asn1d_notify_before (SEC_ASN1DecoderContext *cx, void *dest, int depth)
   412 {
   413     if (cx->notify_proc == NULL)
   414 	return;
   416     cx->during_notify = PR_TRUE;
   417     (* cx->notify_proc) (cx->notify_arg, PR_TRUE, dest, depth);
   418     cx->during_notify = PR_FALSE;
   419 }
   422 static void
   423 sec_asn1d_notify_after (SEC_ASN1DecoderContext *cx, void *dest, int depth)
   424 {
   425     if (cx->notify_proc == NULL)
   426 	return;
   428     cx->during_notify = PR_TRUE;
   429     (* cx->notify_proc) (cx->notify_arg, PR_FALSE, dest, depth);
   430     cx->during_notify = PR_FALSE;
   431 }
   434 static sec_asn1d_state *
   435 sec_asn1d_init_state_based_on_template (sec_asn1d_state *state)
   436 {
   437     PRBool explicit, optional, universal;
   438     unsigned char expect_tag_modifiers;
   439     unsigned long encode_kind, under_kind;
   440     unsigned long check_tag_mask, expect_tag_number;
   443     /* XXX Check that both of these tests are really needed/appropriate. */
   444     if (state == NULL || state->top->status == decodeError)
   445 	return state;
   447     encode_kind = state->theTemplate->kind;
   449     if (encode_kind & SEC_ASN1_SAVE) {
   450 	/*
   451 	 * This is a "magic" field that saves away all bytes, allowing
   452 	 * the immediately following field to still be decoded from this
   453 	 * same spot -- sort of a fork.
   454 	 */
   455 	/* check that there are no extraneous bits */
   456 	PORT_Assert (encode_kind == SEC_ASN1_SAVE);
   457 	if (state->top->filter_only) {
   458 	    /*
   459 	     * If we are not storing, then we do not do the SAVE field
   460 	     * at all.  Just move ahead to the "real" field instead,
   461 	     * doing the appropriate notify calls before and after.
   462 	     */
   463 	    sec_asn1d_notify_after (state->top, state->dest, state->depth);
   464 	    /*
   465 	     * Since we are not storing, allow for our current dest value
   466 	     * to be NULL.  (This might not actually occur, but right now I
   467 	     * cannot convince myself one way or the other.)  If it is NULL,
   468 	     * assume that our parent dest can help us out.
   469 	     */
   470 	    if (state->dest == NULL)
   471 		state->dest = state->parent->dest;
   472 	    else
   473 		state->dest = (char *)state->dest - state->theTemplate->offset;
   474 	    state->theTemplate++;
   475 	    if (state->dest != NULL)
   476 		state->dest = (char *)state->dest + state->theTemplate->offset;
   477 	    sec_asn1d_notify_before (state->top, state->dest, state->depth);
   478 	    encode_kind = state->theTemplate->kind;
   479 	    PORT_Assert ((encode_kind & SEC_ASN1_SAVE) == 0);
   480 	} else {
   481 	    sec_asn1d_scrub_state (state);
   482 	    state->place = duringSaveEncoding;
   483 	    state = sec_asn1d_push_state (state->top, SEC_AnyTemplate,
   484 					  state->dest, PR_FALSE);
   485 	    if (state != NULL)
   486 		state = sec_asn1d_init_state_based_on_template (state);
   487 	    return state;
   488 	}
   489     }
   492     universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
   493 		? PR_TRUE : PR_FALSE;
   495     explicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
   496     encode_kind &= ~SEC_ASN1_EXPLICIT;
   498     optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
   499     encode_kind &= ~SEC_ASN1_OPTIONAL;
   501     PORT_Assert (!(explicit && universal));	/* bad templates */
   503     encode_kind &= ~SEC_ASN1_DYNAMIC;
   504     encode_kind &= ~SEC_ASN1_MAY_STREAM;
   506     if (encode_kind & SEC_ASN1_CHOICE) {
   507 #if 0	/* XXX remove? */
   508       sec_asn1d_state *child = sec_asn1d_push_state(state->top, state->theTemplate, state->dest, PR_FALSE);
   509       if ((sec_asn1d_state *)NULL == child) {
   510         return (sec_asn1d_state *)NULL;
   511       }
   513       child->allocate = state->allocate;
   514       child->place = beforeChoice;
   515       return child;
   516 #else
   517       state->place = beforeChoice;
   518       return state;
   519 #endif
   520     }
   522     if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || (!universal
   523 							      && !explicit)) {
   524 	const SEC_ASN1Template *subt;
   525 	void *dest;
   526 	PRBool child_allocate;
   528 	PORT_Assert ((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0);
   530 	sec_asn1d_scrub_state (state);
   531 	child_allocate = PR_FALSE;
   533 	if (encode_kind & SEC_ASN1_POINTER) {
   534 	    /*
   535 	     * A POINTER means we need to allocate the destination for
   536 	     * this field.  But, since it may also be an optional field,
   537 	     * we defer the allocation until later; we just record that
   538 	     * it needs to be done.
   539 	     *
   540 	     * There are two possible scenarios here -- one is just a
   541 	     * plain POINTER (kind of like INLINE, except with allocation)
   542 	     * and the other is an implicitly-tagged POINTER.  We don't
   543 	     * need to do anything special here for the two cases, but
   544 	     * since the template definition can be tricky, we do check
   545 	     * that there are no extraneous bits set in encode_kind.
   546 	     *
   547 	     * XXX The same conditions which assert should set an error.
   548 	     */
   549 	    if (universal) {
   550 		/*
   551 		 * "universal" means this entry is a standalone POINTER;
   552 		 * there should be no other bits set in encode_kind.
   553 		 */
   554 		PORT_Assert (encode_kind == SEC_ASN1_POINTER);
   555 	    } else {
   556 		/*
   557 		 * If we get here we have an implicitly-tagged field
   558 		 * that needs to be put into a POINTER.  The subtemplate
   559 		 * will determine how to decode the field, but encode_kind
   560 		 * describes the (implicit) tag we are looking for.
   561 		 * The non-tag bits of encode_kind will be ignored by
   562 		 * the code below; none of them should be set, however,
   563 		 * except for the POINTER bit itself -- so check that.
   564 		 */
   565 		PORT_Assert ((encode_kind & ~SEC_ASN1_TAG_MASK)
   566 			     == SEC_ASN1_POINTER);
   567 	    }
   568 	    if (!state->top->filter_only)
   569 		child_allocate = PR_TRUE;
   570 	    dest = NULL;
   571 	    state->place = afterPointer;
   572 	} else {
   573 	    dest = state->dest;
   574 	    if (encode_kind & SEC_ASN1_INLINE) {
   575 		/* check that there are no extraneous bits */
   576 		PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional);
   577 		state->place = afterInline;
   578 	    } else {
   579 		state->place = afterImplicit;
   580 	    }
   581 	}
   583 	state->optional = optional;
   584 	subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->dest, PR_FALSE);
   585 	state = sec_asn1d_push_state (state->top, subt, dest, PR_FALSE);
   586 	if (state == NULL)
   587 	    return NULL;
   589 	state->allocate = child_allocate;
   591 	if (universal) {
   592 	    state = sec_asn1d_init_state_based_on_template (state);
   593 	    if (state != NULL) {
   594 		/*
   595 		 * If this field is optional, we need to record that on
   596 		 * the pushed child so it won't fail if the field isn't
   597 		 * found.  I can't think of a way that this new state
   598 		 * could already have optional set (which we would wipe
   599 		 * out below if our local optional is not set) -- but
   600 		 * just to be sure, assert that it isn't set.
   601 		 */
   602 		PORT_Assert (!state->optional);
   603 		state->optional = optional;
   604 	    }
   605 	    return state;
   606 	}
   608 	under_kind = state->theTemplate->kind;
   609 	under_kind &= ~SEC_ASN1_MAY_STREAM;
   610     } else if (explicit) {
   611 	/*
   612 	 * For explicit, we only need to match the encoding tag next,
   613 	 * then we will push another state to handle the entire inner
   614 	 * part.  In this case, there is no underlying kind which plays
   615 	 * any part in the determination of the outer, explicit tag.
   616 	 * So we just set under_kind to 0, which is not a valid tag,
   617 	 * and the rest of the tag matching stuff should be okay.
   618 	 */
   619 	under_kind = 0;
   620     } else {
   621 	/*
   622 	 * Nothing special; the underlying kind and the given encoding
   623 	 * information are the same.
   624 	 */
   625 	under_kind = encode_kind;
   626     }
   628     /* XXX is this the right set of bits to test here? */
   629     PORT_Assert ((under_kind & (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL
   630 				| SEC_ASN1_MAY_STREAM
   631 				| SEC_ASN1_INLINE | SEC_ASN1_POINTER)) == 0);
   633     if (encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) {
   634 	PORT_Assert (encode_kind == under_kind);
   635 	if (encode_kind & SEC_ASN1_SKIP) {
   636 	    PORT_Assert (!optional);
   637 	    PORT_Assert (encode_kind == SEC_ASN1_SKIP);
   638 	    state->dest = NULL;
   639 	}
   640 	check_tag_mask = 0;
   641 	expect_tag_modifiers = 0;
   642 	expect_tag_number = 0;
   643     } else {
   644 	check_tag_mask = SEC_ASN1_TAG_MASK;
   645 	expect_tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK
   646 				& ~SEC_ASN1_TAGNUM_MASK;
   647 	/*
   648 	 * XXX This assumes only single-octet identifiers.  To handle
   649 	 * the HIGH TAG form we would need to do some more work, especially
   650 	 * in how to specify them in the template, because right now we
   651 	 * do not provide a way to specify more *tag* bits in encode_kind.
   652 	 */
   653 	expect_tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK;
   655 	switch (under_kind & SEC_ASN1_TAGNUM_MASK) {
   656 	  case SEC_ASN1_SET:
   657 	    /*
   658 	     * XXX A plain old SET (as opposed to a SET OF) is not implemented.
   659 	     * If it ever is, remove this assert...
   660 	     */
   661 	    PORT_Assert ((under_kind & SEC_ASN1_GROUP) != 0);
   662 	    /* fallthru */
   663 	  case SEC_ASN1_SEQUENCE:
   664 	    expect_tag_modifiers |= SEC_ASN1_CONSTRUCTED;
   665 	    break;
   666 	  case SEC_ASN1_BIT_STRING:
   667 	  case SEC_ASN1_BMP_STRING:
   668 	  case SEC_ASN1_GENERALIZED_TIME:
   669 	  case SEC_ASN1_IA5_STRING:
   670 	  case SEC_ASN1_OCTET_STRING:
   671 	  case SEC_ASN1_PRINTABLE_STRING:
   672 	  case SEC_ASN1_T61_STRING:
   673 	  case SEC_ASN1_UNIVERSAL_STRING:
   674 	  case SEC_ASN1_UTC_TIME:
   675 	  case SEC_ASN1_UTF8_STRING:
   676 	  case SEC_ASN1_VISIBLE_STRING:
   677 	    check_tag_mask &= ~SEC_ASN1_CONSTRUCTED;
   678 	    break;
   679 	}
   680     }
   682     state->check_tag_mask = check_tag_mask;
   683     state->expect_tag_modifiers = expect_tag_modifiers;
   684     state->expect_tag_number = expect_tag_number;
   685     state->underlying_kind = under_kind;
   686     state->explicit = explicit;
   687     state->optional = optional;
   689     sec_asn1d_scrub_state (state);
   691     return state;
   692 }
   694 static sec_asn1d_state *
   695 sec_asn1d_get_enclosing_construct(sec_asn1d_state *state)
   696 {
   697     for (state = state->parent; state; state = state->parent) {
   698 	sec_asn1d_parse_place place = state->place;
   699 	if (place != afterImplicit      &&
   700 	    place != afterPointer       &&
   701 	    place != afterInline        &&
   702 	    place != afterSaveEncoding  &&
   703 	    place != duringSaveEncoding &&
   704 	    place != duringChoice) {
   706             /* we've walked up the stack to a state that represents
   707             ** the enclosing construct.  
   708 	    */
   709             break;
   710 	}
   711     }
   712     return state;
   713 }
   715 static PRBool
   716 sec_asn1d_parent_allows_EOC(sec_asn1d_state *state)
   717 {
   718     /* get state of enclosing construct. */
   719     state = sec_asn1d_get_enclosing_construct(state);
   720     if (state) {
   721 	sec_asn1d_parse_place place = state->place;
   722         /* Is it one of the types that permits an unexpected EOC? */
   723 	int eoc_permitted = 
   724 	    (place == duringGroup ||
   725 	     place == duringConstructedString ||
   726 	     state->child->optional);
   727 	return (state->indefinite && eoc_permitted) ? PR_TRUE : PR_FALSE;
   728     }
   729     return PR_FALSE;
   730 }
   732 static unsigned long
   733 sec_asn1d_parse_identifier (sec_asn1d_state *state,
   734 			    const char *buf, unsigned long len)
   735 {
   736     unsigned char byte;
   737     unsigned char tag_number;
   739     PORT_Assert (state->place == beforeIdentifier);
   741     if (len == 0) {
   742 	state->top->status = needBytes;
   743 	return 0;
   744     }
   746     byte = (unsigned char) *buf;
   747 #ifdef DEBUG_ASN1D_STATES
   748     {
   749         char kindBuf[256];
   750         formatKind(byte, kindBuf);
   751         printf("Found tag %02x %s\n", byte, kindBuf);
   752     }
   753 #endif
   754     tag_number = byte & SEC_ASN1_TAGNUM_MASK;
   756     if (IS_HIGH_TAG_NUMBER (tag_number)) {
   757 	state->place = duringIdentifier;
   758 	state->found_tag_number = 0;
   759 	/*
   760 	 * Actually, we have no idea how many bytes are pending, but we
   761 	 * do know that it is at least 1.  That is all we know; we have
   762 	 * to look at each byte to know if there is another, etc.
   763 	 */
   764 	state->pending = 1;
   765     } else {
   766 	if (byte == 0 && sec_asn1d_parent_allows_EOC(state)) {
   767 	    /*
   768 	     * Our parent has indefinite-length encoding, and the
   769 	     * entire tag found is 0, so it seems that we have hit the
   770 	     * end-of-contents octets.  To handle this, we just change
   771 	     * our state to that which expects to get the bytes of the
   772 	     * end-of-contents octets and let that code re-read this byte
   773 	     * so that our categorization of field types is correct.
   774 	     * After that, our parent will then deal with everything else.
   775 	     */
   776 	    state->place = duringEndOfContents;
   777 	    state->pending = 2;
   778 	    state->found_tag_number = 0;
   779 	    state->found_tag_modifiers = 0;
   780 	    /*
   781 	     * We might be an optional field that is, as we now find out,
   782 	     * missing.  Give our parent a clue that this happened.
   783 	     */
   784 	    if (state->optional)
   785 		state->missing = PR_TRUE;
   786 	    return 0;
   787 	}
   788 	state->place = afterIdentifier;
   789 	state->found_tag_number = tag_number;
   790     }
   791     state->found_tag_modifiers = byte & ~SEC_ASN1_TAGNUM_MASK;
   793     return 1;
   794 }
   797 static unsigned long
   798 sec_asn1d_parse_more_identifier (sec_asn1d_state *state,
   799 				 const char *buf, unsigned long len)
   800 {
   801     unsigned char byte;
   802     int count;
   804     PORT_Assert (state->pending == 1);
   805     PORT_Assert (state->place == duringIdentifier);
   807     if (len == 0) {
   808 	state->top->status = needBytes;
   809 	return 0;
   810     }
   812     count = 0;
   814     while (len && state->pending) {
   815 	if (HIGH_BITS (state->found_tag_number, TAG_NUMBER_BITS) != 0) {
   816 	    /*
   817 	     * The given high tag number overflows our container;
   818 	     * just give up.  This is not likely to *ever* happen.
   819 	     */
   820 	    PORT_SetError (SEC_ERROR_BAD_DER);
   821 	    state->top->status = decodeError;
   822 	    return 0;
   823 	}
   825 	state->found_tag_number <<= TAG_NUMBER_BITS;
   827 	byte = (unsigned char) buf[count++];
   828 	state->found_tag_number |= (byte & TAG_NUMBER_MASK);
   830 	len--;
   831 	if (LAST_TAG_NUMBER_BYTE (byte))
   832 	    state->pending = 0;
   833     }
   835     if (state->pending == 0)
   836 	state->place = afterIdentifier;
   838     return count;
   839 }
   842 static void
   843 sec_asn1d_confirm_identifier (sec_asn1d_state *state)
   844 {
   845     PRBool match;
   847     PORT_Assert (state->place == afterIdentifier);
   849     match = (PRBool)(((state->found_tag_modifiers & state->check_tag_mask)
   850 	     == state->expect_tag_modifiers)
   851 	    && ((state->found_tag_number & state->check_tag_mask)
   852 		== state->expect_tag_number));
   853     if (match) {
   854 	state->place = beforeLength;
   855     } else {
   856 	if (state->optional) {
   857 	    state->missing = PR_TRUE;
   858 	    state->place = afterEndOfContents;
   859 	} else {
   860 	    PORT_SetError (SEC_ERROR_BAD_DER);
   861 	    state->top->status = decodeError;
   862 	}
   863     }
   864 }
   867 static unsigned long
   868 sec_asn1d_parse_length (sec_asn1d_state *state,
   869 			const char *buf, unsigned long len)
   870 {
   871     unsigned char byte;
   873     PORT_Assert (state->place == beforeLength);
   875     if (len == 0) {
   876 	state->top->status = needBytes;
   877 	return 0;
   878     }
   880     /*
   881      * The default/likely outcome.  It may get adjusted below.
   882      */
   883     state->place = afterLength;
   885     byte = (unsigned char) *buf;
   887     if (LENGTH_IS_SHORT_FORM (byte)) {
   888 	state->contents_length = byte;
   889     } else {
   890 	state->contents_length = 0;
   891 	state->pending = LONG_FORM_LENGTH (byte);
   892 	if (state->pending == 0) {
   893 	    state->indefinite = PR_TRUE;
   894 	} else {
   895 	    state->place = duringLength;
   896 	}
   897     }
   899     /* If we're parsing an ANY, SKIP, or SAVE template, and 
   900     ** the object being saved is definite length encoded and constructed, 
   901     ** there's no point in decoding that construct's members.
   902     ** So, just forget it's constructed and treat it as primitive.
   903     ** (SAVE appears as an ANY at this point)
   904     */
   905     if (!state->indefinite &&
   906 	(state->underlying_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP))) {
   907 	state->found_tag_modifiers &= ~SEC_ASN1_CONSTRUCTED;
   908     }
   910     return 1;
   911 }
   914 static unsigned long
   915 sec_asn1d_parse_more_length (sec_asn1d_state *state,
   916 			     const char *buf, unsigned long len)
   917 {
   918     int count;
   920     PORT_Assert (state->pending > 0);
   921     PORT_Assert (state->place == duringLength);
   923     if (len == 0) {
   924 	state->top->status = needBytes;
   925 	return 0;
   926     }
   928     count = 0;
   930     while (len && state->pending) {
   931 	if (HIGH_BITS (state->contents_length, 9) != 0) {
   932 	    /*
   933 	     * The given full content length overflows our container;
   934 	     * just give up.
   935 	     */
   936 	    PORT_SetError (SEC_ERROR_BAD_DER);
   937 	    state->top->status = decodeError;
   938 	    return 0;
   939 	}
   941 	state->contents_length <<= 8;
   942 	state->contents_length |= (unsigned char) buf[count++];
   944 	len--;
   945 	state->pending--;
   946     }
   948     if (state->pending == 0)
   949 	state->place = afterLength;
   951     return count;
   952 }
   955 static void
   956 sec_asn1d_prepare_for_contents (sec_asn1d_state *state)
   957 {
   958     SECItem *item;
   959     PLArenaPool *poolp;
   960     unsigned long alloc_len;
   962 #ifdef DEBUG_ASN1D_STATES
   963     {
   964         printf("Found Length %d %s\n", state->contents_length,
   965                state->indefinite ? "indefinite" : "");
   966     }
   967 #endif
   969     /*
   970      * XXX I cannot decide if this allocation should exclude the case
   971      *     where state->endofcontents is true -- figure it out!
   972      */
   973     if (state->allocate) {
   974 	void *dest;
   976 	PORT_Assert (state->dest == NULL);
   977 	/*
   978 	 * We are handling a POINTER or a member of a GROUP, and need to
   979 	 * allocate for the data structure.
   980 	 */
   981 	dest = sec_asn1d_zalloc (state->top->their_pool,
   982 				 state->theTemplate->size);
   983 	if (dest == NULL) {
   984 	    state->top->status = decodeError;
   985 	    return;
   986 	}
   987 	state->dest = (char *)dest + state->theTemplate->offset;
   989 	/*
   990 	 * For a member of a GROUP, our parent will later put the
   991 	 * pointer wherever it belongs.  But for a POINTER, we need
   992 	 * to record the destination now, in case notify or filter
   993 	 * procs need access to it -- they cannot find it otherwise,
   994 	 * until it is too late (for one-pass processing).
   995 	 */
   996 	if (state->parent->place == afterPointer) {
   997 	    void **placep;
   999 	    placep = state->parent->dest;
  1000 	    *placep = dest;
  1004     /*
  1005      * Remember, length may be indefinite here!  In that case,
  1006      * both contents_length and pending will be zero.
  1007      */
  1008     state->pending = state->contents_length;
  1010     /* If this item has definite length encoding, and 
  1011     ** is enclosed by a definite length constructed type,
  1012     ** make sure it isn't longer than the remaining space in that 
  1013     ** constructed type.  
  1014     */
  1015     if (state->contents_length > 0) {
  1016 	sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(state);
  1017 	if (parent && !parent->indefinite && 
  1018 	    state->consumed + state->contents_length > parent->pending) {
  1019 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1020 	    state->top->status = decodeError;
  1021 	    return;
  1025     /*
  1026      * An EXPLICIT is nothing but an outer header, which we have
  1027      * already parsed and accepted.  Now we need to do the inner
  1028      * header and its contents.
  1029      */
  1030     if (state->explicit) {
  1031 	state->place = afterExplicit;
  1032 	state = sec_asn1d_push_state (state->top,
  1033 				      SEC_ASN1GetSubtemplate(state->theTemplate,
  1034 							     state->dest,
  1035 							     PR_FALSE),
  1036 				      state->dest, PR_TRUE);
  1037 	if (state != NULL)
  1038 	    state = sec_asn1d_init_state_based_on_template (state);
  1039 	return;
  1042     /*
  1043      * For GROUP (SET OF, SEQUENCE OF), even if we know the length here
  1044      * we cannot tell how many items we will end up with ... so push a
  1045      * state that can keep track of "children" (the individual members
  1046      * of the group; we will allocate as we go and put them all together
  1047      * at the end.
  1048      */
  1049     if (state->underlying_kind & SEC_ASN1_GROUP) {
  1050 	/* XXX If this assertion holds (should be able to confirm it via
  1051 	 * inspection, too) then move this code into the switch statement
  1052 	 * below under cases SET_OF and SEQUENCE_OF; it will be cleaner.
  1053 	 */
  1054 	PORT_Assert (state->underlying_kind == SEC_ASN1_SET_OF
  1055 	   || state->underlying_kind == SEC_ASN1_SEQUENCE_OF
  1056 	   || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC)
  1057 	   || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC)
  1058 		     );
  1059 	if (state->contents_length != 0 || state->indefinite) {
  1060 	    const SEC_ASN1Template *subt;
  1062 	    state->place = duringGroup;
  1063 	    subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->dest,
  1064 					   PR_FALSE);
  1065 	    state = sec_asn1d_push_state (state->top, subt, NULL, PR_TRUE);
  1066 	    if (state != NULL) {
  1067 		if (!state->top->filter_only)
  1068 		    state->allocate = PR_TRUE;	/* XXX propogate this? */
  1069 		/*
  1070 		 * Do the "before" field notification for next in group.
  1071 		 */
  1072 		sec_asn1d_notify_before (state->top, state->dest, state->depth);
  1073 		state = sec_asn1d_init_state_based_on_template (state);
  1075 	} else {
  1076 	    /*
  1077 	     * A group of zero; we are done.
  1078 	     * Set state to afterGroup and let that code plant the NULL.
  1079 	     */
  1080 	    state->place = afterGroup;
  1082 	return;
  1085     switch (state->underlying_kind) {
  1086       case SEC_ASN1_SEQUENCE:
  1087 	/*
  1088 	 * We need to push a child to handle the individual fields.
  1089 	 */
  1090 	state->place = duringSequence;
  1091 	state = sec_asn1d_push_state (state->top, state->theTemplate + 1,
  1092 				      state->dest, PR_TRUE);
  1093 	if (state != NULL) {
  1094 	    /*
  1095 	     * Do the "before" field notification.
  1096 	     */
  1097 	    sec_asn1d_notify_before (state->top, state->dest, state->depth);
  1098 	    state = sec_asn1d_init_state_based_on_template (state);
  1100 	break;
  1102       case SEC_ASN1_SET:	/* XXX SET is not really implemented */
  1103 	/*
  1104 	 * XXX A plain SET requires special handling; scanning of a
  1105 	 * template to see where a field should go (because by definition,
  1106 	 * they are not in any particular order, and you have to look at
  1107 	 * each tag to disambiguate what the field is).  We may never
  1108 	 * implement this because in practice, it seems to be unused.
  1109 	 */
  1110 	PORT_Assert(0);
  1111 	PORT_SetError (SEC_ERROR_BAD_DER); /* XXX */
  1112 	state->top->status = decodeError;
  1113 	break;
  1115       case SEC_ASN1_NULL:
  1116 	/*
  1117 	 * The NULL type, by definition, is "nothing", content length of zero.
  1118 	 * An indefinite-length encoding is not alloweed.
  1119 	 */
  1120 	if (state->contents_length || state->indefinite) {
  1121 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1122 	    state->top->status = decodeError;
  1123 	    break;
  1125 	if (state->dest != NULL) {
  1126 	    item = (SECItem *)(state->dest);
  1127 	    item->data = NULL;
  1128 	    item->len = 0;
  1130 	state->place = afterEndOfContents;
  1131 	break;
  1133       case SEC_ASN1_BMP_STRING:
  1134 	/* Error if length is not divisable by 2 */
  1135 	if (state->contents_length % 2) {
  1136 	   PORT_SetError (SEC_ERROR_BAD_DER);
  1137 	   state->top->status = decodeError;
  1138 	   break;
  1140 	/* otherwise, handle as other string types */
  1141 	goto regular_string_type;
  1143       case SEC_ASN1_UNIVERSAL_STRING:
  1144 	/* Error if length is not divisable by 4 */
  1145 	if (state->contents_length % 4) {
  1146 	   PORT_SetError (SEC_ERROR_BAD_DER);
  1147 	   state->top->status = decodeError;
  1148 	   break;
  1150 	/* otherwise, handle as other string types */
  1151 	goto regular_string_type;
  1153       case SEC_ASN1_SKIP:
  1154       case SEC_ASN1_ANY:
  1155       case SEC_ASN1_ANY_CONTENTS:
  1156 	/*
  1157 	 * These are not (necessarily) strings, but they need nearly
  1158 	 * identical handling (especially when we need to deal with
  1159 	 * constructed sub-pieces), so we pretend they are.
  1160 	 */
  1161 	/* fallthru */
  1162 regular_string_type:
  1163       case SEC_ASN1_BIT_STRING:
  1164       case SEC_ASN1_IA5_STRING:
  1165       case SEC_ASN1_OCTET_STRING:
  1166       case SEC_ASN1_PRINTABLE_STRING:
  1167       case SEC_ASN1_T61_STRING:
  1168       case SEC_ASN1_UTC_TIME:
  1169       case SEC_ASN1_UTF8_STRING:
  1170       case SEC_ASN1_VISIBLE_STRING:
  1171 	/*
  1172 	 * We are allocating for a primitive or a constructed string.
  1173 	 * If it is a constructed string, it may also be indefinite-length.
  1174 	 * If it is primitive, the length can (legally) be zero.
  1175 	 * Our first order of business is to allocate the memory for
  1176 	 * the string, if we can (if we know the length).
  1177 	 */
  1178 	item = (SECItem *)(state->dest);
  1180 	/*
  1181 	 * If the item is a definite-length constructed string, then
  1182 	 * the contents_length is actually larger than what we need
  1183 	 * (because it also counts each intermediate header which we
  1184 	 * will be throwing away as we go), but it is a perfectly good
  1185 	 * upper bound that we just allocate anyway, and then concat
  1186 	 * as we go; we end up wasting a few extra bytes but save a
  1187 	 * whole other copy.
  1188 	 */
  1189 	alloc_len = state->contents_length;
  1190 	poolp = NULL;	/* quiet compiler warnings about unused... */
  1192 	if (item == NULL || state->top->filter_only) {
  1193 	    if (item != NULL) {
  1194 		item->data = NULL;
  1195 		item->len = 0;
  1197 	    alloc_len = 0;
  1198 	} else if (state->substring) {
  1199 	    /*
  1200 	     * If we are a substring of a constructed string, then we may
  1201 	     * not have to allocate anything (because our parent, the
  1202 	     * actual constructed string, did it for us).  If we are a
  1203 	     * substring and we *do* have to allocate, that means our
  1204 	     * parent is an indefinite-length, so we allocate from our pool;
  1205 	     * later our parent will copy our string into the aggregated
  1206 	     * whole and free our pool allocation.
  1207 	     */
  1208 	    if (item->data == NULL) {
  1209 		PORT_Assert (item->len == 0);
  1210 		poolp = state->top->our_pool;
  1211 	    } else {
  1212 		alloc_len = 0;
  1214 	} else {
  1215 	    item->len = 0;
  1216 	    item->data = NULL;
  1217 	    poolp = state->top->their_pool;
  1220 	if (alloc_len || ((! state->indefinite)
  1221 			  && (state->subitems_head != NULL))) {
  1222 	    struct subitem *subitem;
  1223 	    int len;
  1225 	    PORT_Assert (item);
  1226 	    if (!item) {
  1227 		PORT_SetError (SEC_ERROR_BAD_DER);
  1228 		state->top->status = decodeError;
  1229 		return;
  1231 	    PORT_Assert (item->len == 0 && item->data == NULL);
  1232 	    /*
  1233 	     * Check for and handle an ANY which has stashed aside the
  1234 	     * header (identifier and length) bytes for us to include
  1235 	     * in the saved contents.
  1236 	     */
  1237 	    if (state->subitems_head != NULL) {
  1238 		PORT_Assert (state->underlying_kind == SEC_ASN1_ANY);
  1239 		for (subitem = state->subitems_head;
  1240 		     subitem != NULL; subitem = subitem->next)
  1241 		    alloc_len += subitem->len;
  1244 	    item->data = (unsigned char*)sec_asn1d_zalloc (poolp, alloc_len);
  1245 	    if (item->data == NULL) {
  1246 		state->top->status = decodeError;
  1247 		break;
  1250 	    len = 0;
  1251 	    for (subitem = state->subitems_head;
  1252 		 subitem != NULL; subitem = subitem->next) {
  1253 		PORT_Memcpy (item->data + len, subitem->data, subitem->len);
  1254 		len += subitem->len;
  1256 	    item->len = len;
  1258 	    /*
  1259 	     * Because we use arenas and have a mark set, we later free
  1260 	     * everything we have allocated, so this does *not* present
  1261 	     * a memory leak (it is just temporarily left dangling).
  1262 	     */
  1263 	    state->subitems_head = state->subitems_tail = NULL;
  1266 	if (state->contents_length == 0 && (! state->indefinite)) {
  1267 	    /*
  1268 	     * A zero-length simple or constructed string; we are done.
  1269 	     */
  1270 	    state->place = afterEndOfContents;
  1271 	} else if (state->found_tag_modifiers & SEC_ASN1_CONSTRUCTED) {
  1272 	    const SEC_ASN1Template *sub;
  1274 	    switch (state->underlying_kind) {
  1275 	      case SEC_ASN1_ANY:
  1276 	      case SEC_ASN1_ANY_CONTENTS:
  1277 		sub = SEC_AnyTemplate;
  1278 		break;
  1279 	      case SEC_ASN1_BIT_STRING:
  1280 		sub = SEC_BitStringTemplate;
  1281 		break;
  1282 	      case SEC_ASN1_BMP_STRING:
  1283 		sub = SEC_BMPStringTemplate;
  1284 		break;
  1285 	      case SEC_ASN1_GENERALIZED_TIME:
  1286 		sub = SEC_GeneralizedTimeTemplate;
  1287 		break;
  1288 	      case SEC_ASN1_IA5_STRING:
  1289 		sub = SEC_IA5StringTemplate;
  1290 		break;
  1291 	      case SEC_ASN1_OCTET_STRING:
  1292 		sub = SEC_OctetStringTemplate;
  1293 		break;
  1294 	      case SEC_ASN1_PRINTABLE_STRING:
  1295 		sub = SEC_PrintableStringTemplate;
  1296 		break;
  1297 	      case SEC_ASN1_T61_STRING:
  1298 		sub = SEC_T61StringTemplate;
  1299 		break;
  1300 	      case SEC_ASN1_UNIVERSAL_STRING:
  1301 		sub = SEC_UniversalStringTemplate;
  1302 		break;
  1303 	      case SEC_ASN1_UTC_TIME:
  1304 		sub = SEC_UTCTimeTemplate;
  1305 		break;
  1306 	      case SEC_ASN1_UTF8_STRING:
  1307 		sub = SEC_UTF8StringTemplate;
  1308 		break;
  1309 	      case SEC_ASN1_VISIBLE_STRING:
  1310 		sub = SEC_VisibleStringTemplate;
  1311 		break;
  1312 	      case SEC_ASN1_SKIP:
  1313 		sub = SEC_SkipTemplate;
  1314 		break;
  1315 	      default:		/* redundant given outer switch cases, but */
  1316 		PORT_Assert(0);	/* the compiler does not seem to know that, */
  1317 		sub = NULL;	/* so just do enough to quiet it. */
  1318 		break;
  1321 	    state->place = duringConstructedString;
  1322 	    state = sec_asn1d_push_state (state->top, sub, item, PR_TRUE);
  1323 	    if (state != NULL) {
  1324 		state->substring = PR_TRUE;	/* XXX propogate? */
  1325 		state = sec_asn1d_init_state_based_on_template (state);
  1327 	} else if (state->indefinite) {
  1328 	    /*
  1329 	     * An indefinite-length string *must* be constructed!
  1330 	     */
  1331 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1332 	    state->top->status = decodeError;
  1333 	} else {
  1334 	    /*
  1335 	     * A non-zero-length simple string.
  1336 	     */
  1337 	    if (state->underlying_kind == SEC_ASN1_BIT_STRING)
  1338 		state->place = beforeBitString;
  1339 	    else
  1340 		state->place = duringLeaf;
  1342 	break;
  1344       default:
  1345 	/*
  1346 	 * We are allocating for a simple leaf item.
  1347 	 */
  1348 	if (state->contents_length) {
  1349 	    if (state->dest != NULL) {
  1350 		item = (SECItem *)(state->dest);
  1351 		item->len = 0;
  1352 		if (state->top->filter_only) {
  1353 		    item->data = NULL;
  1354 		} else {
  1355 		    item->data = (unsigned char*)
  1356 		                  sec_asn1d_zalloc (state->top->their_pool,
  1357 						   state->contents_length);
  1358 		    if (item->data == NULL) {
  1359 			state->top->status = decodeError;
  1360 			return;
  1364 	    state->place = duringLeaf;
  1365 	} else {
  1366 	    /*
  1367 	     * An indefinite-length or zero-length item is not allowed.
  1368 	     * (All legal cases of such were handled above.)
  1369 	     */
  1370 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1371 	    state->top->status = decodeError;
  1377 static void
  1378 sec_asn1d_free_child (sec_asn1d_state *state, PRBool error)
  1380     if (state->child != NULL) {
  1381 	PORT_Assert (error || state->child->consumed == 0);
  1382 	PORT_Assert (state->our_mark != NULL);
  1383 	PORT_ArenaZRelease (state->top->our_pool, state->our_mark);
  1384 	if (error && state->top->their_pool == NULL) {
  1385 	    /*
  1386 	     * XXX We need to free anything allocated.
  1387              * At this point, we failed in the middle of decoding. But we
  1388              * can't free the data we previously allocated with PR_Malloc
  1389              * unless we keep track of every pointer. So instead we have a
  1390              * memory leak when decoding fails half-way, unless an arena is
  1391              * used. See bug 95311 .
  1392 	     */
  1394 	state->child = NULL;
  1395 	state->our_mark = NULL;
  1396     } else {
  1397 	/*
  1398 	 * It is important that we do not leave a mark unreleased/unmarked.
  1399 	 * But I do not think we should ever have one set in this case, only
  1400 	 * if we had a child (handled above).  So check for that.  If this
  1401 	 * assertion should ever get hit, then we probably need to add code
  1402 	 * here to release back to our_mark (and then set our_mark to NULL).
  1403 	 */
  1404 	PORT_Assert (state->our_mark == NULL);
  1406     state->place = beforeEndOfContents;
  1409 /* We have just saved an entire encoded ASN.1 object (type) for a SAVE 
  1410 ** template, and now in the next template, we are going to decode that 
  1411 ** saved data  by calling SEC_ASN1DecoderUpdate recursively.
  1412 ** If that recursive call fails with needBytes, it is a fatal error,
  1413 ** because the encoded object should have been complete.
  1414 ** If that recursive call fails with decodeError, it will have already
  1415 ** cleaned up the state stack, so we must bail out quickly.
  1416 **
  1417 ** These checks of the status returned by the recursive call are now
  1418 ** done in the caller of this function, immediately after it returns.
  1419 */
  1420 static void
  1421 sec_asn1d_reuse_encoding (sec_asn1d_state *state)
  1423     sec_asn1d_state *child;
  1424     unsigned long consumed;
  1425     SECItem *item;
  1426     void *dest;
  1429     child = state->child;
  1430     PORT_Assert (child != NULL);
  1432     consumed = child->consumed;
  1433     child->consumed = 0;
  1435     item = (SECItem *)(state->dest);
  1436     PORT_Assert (item != NULL);
  1438     PORT_Assert (item->len == consumed);
  1440     /*
  1441      * Free any grandchild.
  1442      */
  1443     sec_asn1d_free_child (child, PR_FALSE);
  1445     /*
  1446      * Notify after the SAVE field.
  1447      */
  1448     sec_asn1d_notify_after (state->top, state->dest, state->depth);
  1450     /*
  1451      * Adjust to get new dest and move forward.
  1452      */
  1453     dest = (char *)state->dest - state->theTemplate->offset;
  1454     state->theTemplate++;
  1455     child->dest = (char *)dest + state->theTemplate->offset;
  1456     child->theTemplate = state->theTemplate;
  1458     /*
  1459      * Notify before the "real" field.
  1460      */
  1461     PORT_Assert (state->depth == child->depth);
  1462     sec_asn1d_notify_before (state->top, child->dest, child->depth);
  1464     /*
  1465      * This will tell DecoderUpdate to return when it is done.
  1466      */
  1467     state->place = afterSaveEncoding;
  1469     /*
  1470      * We already have a child; "push" it by making it current.
  1471      */
  1472     state->top->current = child;
  1474     /*
  1475      * And initialize it so it is ready to parse.
  1476      */
  1477     (void) sec_asn1d_init_state_based_on_template(child);
  1479     /*
  1480      * Now parse that out of our data.
  1481      */
  1482     if (SEC_ASN1DecoderUpdate (state->top,
  1483 			       (char *) item->data, item->len) != SECSuccess)
  1484 	return;
  1485     if (state->top->status == needBytes) {
  1486 	return;
  1489     PORT_Assert (state->top->current == state);
  1490     PORT_Assert (state->child == child);
  1492     /*
  1493      * That should have consumed what we consumed before.
  1494      */
  1495     PORT_Assert (consumed == child->consumed);
  1496     child->consumed = 0;
  1498     /*
  1499      * Done.
  1500      */
  1501     state->consumed += consumed;
  1502     child->place = notInUse;
  1503     state->place = afterEndOfContents;
  1507 static unsigned long
  1508 sec_asn1d_parse_leaf (sec_asn1d_state *state,
  1509 		      const char *buf, unsigned long len)
  1511     SECItem *item;
  1512     unsigned long bufLen;
  1514     if (len == 0) {
  1515 	state->top->status = needBytes;
  1516 	return 0;
  1519     if (state->pending < len)
  1520 	len = state->pending;
  1522     bufLen = len;
  1524     item = (SECItem *)(state->dest);
  1525     if (item != NULL && item->data != NULL) {
  1526 	/* Strip leading zeroes when target is unsigned integer */
  1527 	if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER   */
  1528 	    item->len == 0 &&                             /* MSB       */
  1529 	    item->type == siUnsignedInteger)              /* unsigned  */
  1531 	    while (len > 1 && buf[0] == 0) {              /* leading 0 */
  1532 		buf++;
  1533 		len--;
  1536 	PORT_Memcpy (item->data + item->len, buf, len);
  1537 	item->len += len;
  1539     state->pending -= bufLen;
  1540     if (state->pending == 0)
  1541 	state->place = beforeEndOfContents;
  1543     return bufLen;
  1547 static unsigned long
  1548 sec_asn1d_parse_bit_string (sec_asn1d_state *state,
  1549 			    const char *buf, unsigned long len)
  1551     unsigned char byte;
  1553     /*PORT_Assert (state->pending > 0); */
  1554     PORT_Assert (state->place == beforeBitString);
  1556     if (state->pending == 0) {
  1557 	if (state->dest != NULL) {
  1558 	    SECItem *item = (SECItem *)(state->dest);
  1559 	    item->data = NULL;
  1560 	    item->len = 0;
  1561 	    state->place = beforeEndOfContents;
  1562 	    return 0;
  1566     if (len == 0) {
  1567 	state->top->status = needBytes;
  1568 	return 0;
  1571     byte = (unsigned char) *buf;
  1572     if (byte > 7) {
  1573 	PORT_SetError (SEC_ERROR_BAD_DER);
  1574 	state->top->status = decodeError;
  1575 	return 0;
  1578     state->bit_string_unused_bits = byte;
  1579     state->place = duringBitString;
  1580     state->pending -= 1;
  1582     return 1;
  1586 static unsigned long
  1587 sec_asn1d_parse_more_bit_string (sec_asn1d_state *state,
  1588 				 const char *buf, unsigned long len)
  1590     PORT_Assert (state->place == duringBitString);
  1591     if (state->pending == 0) {
  1592 	/* An empty bit string with some unused bits is invalid. */
  1593 	if (state->bit_string_unused_bits) {
  1594 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1595 	    state->top->status = decodeError;
  1596 	} else {
  1597 	    /* An empty bit string with no unused bits is OK. */
  1598 	    state->place = beforeEndOfContents;
  1600 	return 0;
  1603     len = sec_asn1d_parse_leaf (state, buf, len);
  1604     if (state->place == beforeEndOfContents && state->dest != NULL) {
  1605 	SECItem *item;
  1607 	item = (SECItem *)(state->dest);
  1608 	if (item->len)
  1609 	    item->len = (item->len << 3) - state->bit_string_unused_bits;
  1612     return len;
  1616 /*
  1617  * XXX All callers should be looking at return value to detect
  1618  * out-of-memory errors (and stop!).
  1619  */
  1620 static struct subitem *
  1621 sec_asn1d_add_to_subitems (sec_asn1d_state *state,
  1622 			   const void *data, unsigned long len,
  1623 			   PRBool copy_data)
  1625     struct subitem *thing;
  1627     thing = (struct subitem*)sec_asn1d_zalloc (state->top->our_pool,
  1628 				sizeof (struct subitem));
  1629     if (thing == NULL) {
  1630 	state->top->status = decodeError;
  1631 	return NULL;
  1634     if (copy_data) {
  1635 	void *copy;
  1636 	copy = sec_asn1d_alloc (state->top->our_pool, len);
  1637 	if (copy == NULL) {
  1638 	    state->top->status = decodeError;
  1639 	    if (!state->top->our_pool)
  1640 	    	PORT_Free(thing);
  1641 	    return NULL;
  1643 	PORT_Memcpy (copy, data, len);
  1644 	thing->data = copy;
  1645     } else {
  1646 	thing->data = data;
  1648     thing->len = len;
  1649     thing->next = NULL;
  1651     if (state->subitems_head == NULL) {
  1652 	PORT_Assert (state->subitems_tail == NULL);
  1653 	state->subitems_head = state->subitems_tail = thing;
  1654     } else {
  1655 	state->subitems_tail->next = thing;
  1656 	state->subitems_tail = thing;
  1659     return thing;
  1663 static void
  1664 sec_asn1d_record_any_header (sec_asn1d_state *state,
  1665 			     const char *buf,
  1666 			     unsigned long len)
  1668     SECItem *item;
  1670     item = (SECItem *)(state->dest);
  1671     if (item != NULL && item->data != NULL) {
  1672 	PORT_Assert (state->substring);
  1673 	PORT_Memcpy (item->data + item->len, buf, len);
  1674 	item->len += len;
  1675     } else {
  1676 	sec_asn1d_add_to_subitems (state, buf, len, PR_TRUE);
  1681 /*
  1682  * We are moving along through the substrings of a constructed string,
  1683  * and have just finished parsing one -- we need to save our child data
  1684  * (if the child was not already writing directly into the destination)
  1685  * and then move forward by one.
  1687  * We also have to detect when we are done:
  1688  *	- a definite-length encoding stops when our pending value hits 0
  1689  *	- an indefinite-length encoding stops when our child is empty
  1690  *	  (which means it was the end-of-contents octets)
  1691  */
  1692 static void
  1693 sec_asn1d_next_substring (sec_asn1d_state *state)
  1695     sec_asn1d_state *child;
  1696     SECItem *item;
  1697     unsigned long child_consumed;
  1698     PRBool done;
  1700     PORT_Assert (state->place == duringConstructedString);
  1701     PORT_Assert (state->child != NULL);
  1703     child = state->child;
  1705     child_consumed = child->consumed;
  1706     child->consumed = 0;
  1707     state->consumed += child_consumed;
  1709     done = PR_FALSE;
  1711     if (state->pending) {
  1712 	PORT_Assert (!state->indefinite);
  1713 	if (child_consumed > state->pending) {
  1714 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1715 	    state->top->status = decodeError;
  1716 	    return;
  1719 	state->pending -= child_consumed;
  1720 	if (state->pending == 0)
  1721 	    done = PR_TRUE;
  1722     } else {
  1723 	PORT_Assert (state->indefinite);
  1725 	item = (SECItem *)(child->dest);
  1726 	if (item != NULL && item->data != NULL) {
  1727 	    /*
  1728 	     * Save the string away for later concatenation.
  1729 	     */
  1730 	    PORT_Assert (item->data != NULL);
  1731 	    sec_asn1d_add_to_subitems (state, item->data, item->len, PR_FALSE);
  1732 	    /*
  1733 	     * Clear the child item for the next round.
  1734 	     */
  1735 	    item->data = NULL;
  1736 	    item->len = 0;
  1739 	/*
  1740 	 * If our child was just our end-of-contents octets, we are done.
  1741 	 */
  1742 	if (child->endofcontents)
  1743 	    done = PR_TRUE;
  1746     /*
  1747      * Stop or do the next one.
  1748      */
  1749     if (done) {
  1750 	child->place = notInUse;
  1751 	state->place = afterConstructedString;
  1752     } else {
  1753 	sec_asn1d_scrub_state (child);
  1754 	state->top->current = child;
  1759 /*
  1760  * We are doing a SET OF or SEQUENCE OF, and have just finished an item.
  1761  */
  1762 static void
  1763 sec_asn1d_next_in_group (sec_asn1d_state *state)
  1765     sec_asn1d_state *child;
  1766     unsigned long child_consumed;
  1768     PORT_Assert (state->place == duringGroup);
  1769     PORT_Assert (state->child != NULL);
  1771     child = state->child;
  1773     child_consumed = child->consumed;
  1774     child->consumed = 0;
  1775     state->consumed += child_consumed;
  1777     /*
  1778      * If our child was just our end-of-contents octets, we are done.
  1779      */
  1780     if (child->endofcontents) {
  1781 	/* XXX I removed the PORT_Assert (child->dest == NULL) because there
  1782 	 * was a bug in that a template that was a sequence of which also had
  1783 	 * a child of a sequence of, in an indefinite group was not working 
  1784 	 * properly.  This fix seems to work, (added the if statement below),
  1785 	 * and nothing appears broken, but I am putting this note here just
  1786 	 * in case. */
  1787 	/*
  1788 	 * XXX No matter how many times I read that comment,
  1789 	 * I cannot figure out what case he was fixing.  I believe what he
  1790 	 * did was deliberate, so I am loathe to touch it.  I need to
  1791 	 * understand how it could ever be that child->dest != NULL but
  1792 	 * child->endofcontents is true, and why it is important to check
  1793 	 * that state->subitems_head is NULL.  This really needs to be
  1794 	 * figured out, as I am not sure if the following code should be
  1795 	 * compensating for "offset", as is done a little farther below
  1796 	 * in the more normal case.
  1797 	 */
  1798 	PORT_Assert (state->indefinite);
  1799 	PORT_Assert (state->pending == 0);
  1800 	if(child->dest && !state->subitems_head) {
  1801 	    sec_asn1d_add_to_subitems (state, child->dest, 0, PR_FALSE);
  1802 	    child->dest = NULL;
  1805 	child->place = notInUse;
  1806 	state->place = afterGroup;
  1807 	return;
  1810     /* 
  1811      * Do the "after" field notification for next in group.
  1812      */
  1813     sec_asn1d_notify_after (state->top, child->dest, child->depth);
  1815     /*
  1816      * Save it away (unless we are not storing).
  1817      */
  1818     if (child->dest != NULL) {
  1819 	void *dest;
  1821 	dest = child->dest;
  1822 	dest = (char *)dest - child->theTemplate->offset;
  1823 	sec_asn1d_add_to_subitems (state, dest, 0, PR_FALSE);
  1824 	child->dest = NULL;
  1827     /*
  1828      * Account for those bytes; see if we are done.
  1829      */
  1830     if (state->pending) {
  1831 	PORT_Assert (!state->indefinite);
  1832 	if (child_consumed > state->pending) {
  1833 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1834 	    state->top->status = decodeError;
  1835 	    return;
  1838 	state->pending -= child_consumed;
  1839 	if (state->pending == 0) {
  1840 	    child->place = notInUse;
  1841 	    state->place = afterGroup;
  1842 	    return;
  1846     /*
  1847      * Do the "before" field notification for next item in group.
  1848      */
  1849     sec_asn1d_notify_before (state->top, child->dest, child->depth);
  1851     /*
  1852      * Now we do the next one.
  1853      */
  1854     sec_asn1d_scrub_state (child);
  1856     /* Initialize child state from the template */
  1857     sec_asn1d_init_state_based_on_template(child);
  1859     state->top->current = child;
  1863 /*
  1864  * We are moving along through a sequence; move forward by one,
  1865  * (detecting end-of-sequence when it happens).
  1866  * XXX The handling of "missing" is ugly.  Fix it.
  1867  */
  1868 static void
  1869 sec_asn1d_next_in_sequence (sec_asn1d_state *state)
  1871     sec_asn1d_state *child;
  1872     unsigned long child_consumed;
  1873     PRBool child_missing;
  1875     PORT_Assert (state->place == duringSequence);
  1876     PORT_Assert (state->child != NULL);
  1878     child = state->child;
  1880     /*
  1881      * Do the "after" field notification.
  1882      */
  1883     sec_asn1d_notify_after (state->top, child->dest, child->depth);
  1885     child_missing = (PRBool) child->missing;
  1886     child_consumed = child->consumed;
  1887     child->consumed = 0;
  1889     /*
  1890      * Take care of accounting.
  1891      */
  1892     if (child_missing) {
  1893 	PORT_Assert (child->optional);
  1894     } else {
  1895 	state->consumed += child_consumed;
  1896 	/*
  1897 	 * Free any grandchild.
  1898 	 */
  1899 	sec_asn1d_free_child (child, PR_FALSE);
  1900 	if (state->pending) {
  1901 	    PORT_Assert (!state->indefinite);
  1902 	    if (child_consumed > state->pending) {
  1903 		PORT_SetError (SEC_ERROR_BAD_DER);
  1904 		state->top->status = decodeError;
  1905 		return;
  1907 	    state->pending -= child_consumed;
  1908 	    if (state->pending == 0) {
  1909 		child->theTemplate++;
  1910 		while (child->theTemplate->kind != 0) {
  1911 		    if ((child->theTemplate->kind & SEC_ASN1_OPTIONAL) == 0) {
  1912 			PORT_SetError (SEC_ERROR_BAD_DER);
  1913 			state->top->status = decodeError;
  1914 			return;
  1916 		    child->theTemplate++;
  1918 		child->place = notInUse;
  1919 		state->place = afterEndOfContents;
  1920 		return;
  1925     /*
  1926      * Move forward.
  1927      */
  1928     child->theTemplate++;
  1929     if (child->theTemplate->kind == 0) {
  1930 	/*
  1931 	 * We are done with this sequence.
  1932 	 */
  1933 	child->place = notInUse;
  1934 	if (state->pending) {
  1935 	    PORT_SetError (SEC_ERROR_BAD_DER);
  1936 	    state->top->status = decodeError;
  1937 	} else if (child_missing) {
  1938 	    /*
  1939 	     * We got to the end, but have a child that started parsing
  1940 	     * and ended up "missing".  The only legitimate reason for
  1941 	     * this is that we had one or more optional fields at the
  1942 	     * end of our sequence, and we were encoded indefinite-length,
  1943 	     * so when we went looking for those optional fields we
  1944 	     * found our end-of-contents octets instead.
  1945 	     * (Yes, this is ugly; dunno a better way to handle it.)
  1946 	     * So, first confirm the situation, and then mark that we
  1947 	     * are done.
  1948 	     */
  1949 	    if (state->indefinite && child->endofcontents) {
  1950 		PORT_Assert (child_consumed == 2);
  1951 		if (child_consumed != 2) {
  1952 		    PORT_SetError (SEC_ERROR_BAD_DER);
  1953 		    state->top->status = decodeError;
  1954 		} else {
  1955 		    state->consumed += child_consumed;
  1956 		    state->place = afterEndOfContents;
  1958 	    } else {
  1959 		PORT_SetError (SEC_ERROR_BAD_DER);
  1960 		state->top->status = decodeError;
  1962 	} else {
  1963 	    /*
  1964 	     * We have to finish out, maybe reading end-of-contents octets;
  1965 	     * let the normal logic do the right thing.
  1966 	     */
  1967 	    state->place = beforeEndOfContents;
  1969     } else {
  1970 	unsigned char child_found_tag_modifiers = 0;
  1971 	unsigned long child_found_tag_number = 0;
  1973 	/*
  1974 	 * Reset state and push.
  1975 	 */
  1976 	if (state->dest != NULL)
  1977 	    child->dest = (char *)state->dest + child->theTemplate->offset;
  1979 	/*
  1980 	 * Do the "before" field notification.
  1981 	 */
  1982 	sec_asn1d_notify_before (state->top, child->dest, child->depth);
  1984 	if (child_missing) { /* if previous child was missing, copy the tag data we already have */
  1985 	    child_found_tag_modifiers = child->found_tag_modifiers;
  1986 	    child_found_tag_number = child->found_tag_number;
  1988 	state->top->current = child;
  1989 	child = sec_asn1d_init_state_based_on_template (child);
  1990 	if (child_missing && child) {
  1991 	    child->place = afterIdentifier;
  1992 	    child->found_tag_modifiers = child_found_tag_modifiers;
  1993 	    child->found_tag_number = child_found_tag_number;
  1994 	    child->consumed = child_consumed;
  1995 	    if (child->underlying_kind == SEC_ASN1_ANY
  1996 		&& !child->top->filter_only) {
  1997 		/*
  1998 		 * If the new field is an ANY, and we are storing, then
  1999 		 * we need to save the tag out.  We would have done this
  2000 		 * already in the normal case, but since we were looking
  2001 		 * for an optional field, and we did not find it, we only
  2002 		 * now realize we need to save the tag.
  2003 		 */
  2004 		unsigned char identifier;
  2006 		/*
  2007 		 * Check that we did not end up with a high tag; for that
  2008 		 * we need to re-encode the tag into multiple bytes in order
  2009 		 * to store it back to look like what we parsed originally.
  2010 		 * In practice this does not happen, but for completeness
  2011 		 * sake it should probably be made to work at some point.
  2012 		 */
  2013 		PORT_Assert (child_found_tag_number < SEC_ASN1_HIGH_TAG_NUMBER);
  2014 		identifier = (unsigned char)(child_found_tag_modifiers | child_found_tag_number);
  2015 		sec_asn1d_record_any_header (child, (char *) &identifier, 1);
  2022 static void
  2023 sec_asn1d_concat_substrings (sec_asn1d_state *state)
  2025     PORT_Assert (state->place == afterConstructedString);
  2027     if (state->subitems_head != NULL) {
  2028 	struct subitem *substring;
  2029 	unsigned long alloc_len, item_len;
  2030 	unsigned char *where;
  2031 	SECItem *item;
  2032 	PRBool is_bit_string;
  2034 	item_len = 0;
  2035 	is_bit_string = (state->underlying_kind == SEC_ASN1_BIT_STRING)
  2036 			? PR_TRUE : PR_FALSE;
  2038 	substring = state->subitems_head;
  2039 	while (substring != NULL) {
  2040 	    /*
  2041 	     * All bit-string substrings except the last one should be
  2042 	     * a clean multiple of 8 bits.
  2043 	     */
  2044 	    if (is_bit_string && (substring->next == NULL)
  2045 			      && (substring->len & 0x7)) {
  2046 		PORT_SetError (SEC_ERROR_BAD_DER);
  2047 		state->top->status = decodeError;
  2048 		return;
  2050 	    item_len += substring->len;
  2051 	    substring = substring->next;
  2054 	if (is_bit_string) {
  2055 	    alloc_len = ((item_len + 7) >> 3);
  2056 	} else {
  2057 	    /*
  2058 	     * Add 2 for the end-of-contents octets of an indefinite-length
  2059 	     * ANY that is *not* also an INNER.  Because we zero-allocate
  2060 	     * below, all we need to do is increase the length here.
  2061 	     */
  2062 	    if (state->underlying_kind == SEC_ASN1_ANY && state->indefinite)
  2063 		item_len += 2; 
  2064 	    alloc_len = item_len;
  2067 	item = (SECItem *)(state->dest);
  2068 	PORT_Assert (item != NULL);
  2069 	PORT_Assert (item->data == NULL);
  2070 	item->data = (unsigned char*)sec_asn1d_zalloc (state->top->their_pool, 
  2071 						       alloc_len);
  2072 	if (item->data == NULL) {
  2073 	    state->top->status = decodeError;
  2074 	    return;
  2076 	item->len = item_len;
  2078 	where = item->data;
  2079 	substring = state->subitems_head;
  2080 	while (substring != NULL) {
  2081 	    if (is_bit_string)
  2082 		item_len = (substring->len + 7) >> 3;
  2083 	    else
  2084 		item_len = substring->len;
  2085 	    PORT_Memcpy (where, substring->data, item_len);
  2086 	    where += item_len;
  2087 	    substring = substring->next;
  2090 	/*
  2091 	 * Because we use arenas and have a mark set, we later free
  2092 	 * everything we have allocated, so this does *not* present
  2093 	 * a memory leak (it is just temporarily left dangling).
  2094 	 */
  2095 	state->subitems_head = state->subitems_tail = NULL;
  2098     state->place = afterEndOfContents;
  2102 static void
  2103 sec_asn1d_concat_group (sec_asn1d_state *state)
  2105     const void ***placep;
  2107     PORT_Assert (state->place == afterGroup);
  2109     placep = (const void***)state->dest;
  2110     PORT_Assert(state->subitems_head == NULL || placep != NULL);
  2111     if (placep != NULL) {
  2112 	struct subitem *item;
  2113 	const void **group;
  2114 	int count;
  2116 	count = 0;
  2117 	item = state->subitems_head;
  2118 	while (item != NULL) {
  2119 	    PORT_Assert (item->next != NULL || item == state->subitems_tail);
  2120 	    count++;
  2121 	    item = item->next;
  2124 	group = (const void**)sec_asn1d_zalloc (state->top->their_pool,
  2125 				  (count + 1) * (sizeof(void *)));
  2126 	if (group == NULL) {
  2127 	    state->top->status = decodeError;
  2128 	    return;
  2131 	*placep = group;
  2133 	item = state->subitems_head;
  2134 	while (item != NULL) {
  2135 	    *group++ = item->data;
  2136 	    item = item->next;
  2138 	*group = NULL;
  2140 	/*
  2141 	 * Because we use arenas and have a mark set, we later free
  2142 	 * everything we have allocated, so this does *not* present
  2143 	 * a memory leak (it is just temporarily left dangling).
  2144 	 */
  2145 	state->subitems_head = state->subitems_tail = NULL;
  2148     state->place = afterEndOfContents;
  2152 /*
  2153  * For those states that push a child to handle a subtemplate,
  2154  * "absorb" that child (transfer necessary information).
  2155  */
  2156 static void
  2157 sec_asn1d_absorb_child (sec_asn1d_state *state)
  2159     /*
  2160      * There is absolutely supposed to be a child there.
  2161      */
  2162     PORT_Assert (state->child != NULL);
  2164     /*
  2165      * Inherit the missing status of our child, and do the ugly
  2166      * backing-up if necessary.
  2167      */
  2168     state->missing = state->child->missing;
  2169     if (state->missing) {
  2170 	state->found_tag_number = state->child->found_tag_number;
  2171 	state->found_tag_modifiers = state->child->found_tag_modifiers;
  2172 	state->endofcontents = state->child->endofcontents;
  2175     /*
  2176      * Add in number of bytes consumed by child.
  2177      * (Only EXPLICIT should have already consumed bytes itself.)
  2178      */
  2179     PORT_Assert (state->place == afterExplicit || state->consumed == 0);
  2180     state->consumed += state->child->consumed;
  2182     /*
  2183      * Subtract from bytes pending; this only applies to a definite-length
  2184      * EXPLICIT field.
  2185      */
  2186     if (state->pending) {
  2187 	PORT_Assert (!state->indefinite);
  2188 	PORT_Assert (state->place == afterExplicit);
  2190 	/*
  2191 	 * If we had a definite-length explicit, then what the child
  2192 	 * consumed should be what was left pending.
  2193 	 */
  2194 	if (state->pending != state->child->consumed) {
  2195 	    if (state->pending < state->child->consumed) {
  2196 		PORT_SetError (SEC_ERROR_BAD_DER);
  2197 		state->top->status = decodeError;
  2198 		return;
  2200 	    /*
  2201 	     * Okay, this is a hack.  It *should* be an error whether
  2202 	     * pending is too big or too small, but it turns out that
  2203 	     * we had a bug in our *old* DER encoder that ended up
  2204 	     * counting an explicit header twice in the case where
  2205 	     * the underlying type was an ANY.  So, because we cannot
  2206 	     * prevent receiving these (our own certificate server can
  2207 	     * send them to us), we need to be lenient and accept them.
  2208 	     * To do so, we need to pretend as if we read all of the
  2209 	     * bytes that the header said we would find, even though
  2210 	     * we actually came up short.
  2211 	     */
  2212 	    state->consumed += (state->pending - state->child->consumed);
  2214 	state->pending = 0;
  2217     /*
  2218      * Indicate that we are done with child.
  2219      */
  2220     state->child->consumed = 0;
  2222     /*
  2223      * And move on to final state.
  2224      * (Technically everybody could move to afterEndOfContents except
  2225      * for an indefinite-length EXPLICIT; for simplicity though we assert
  2226      * that but let the end-of-contents code do the real determination.)
  2227      */
  2228     PORT_Assert (state->place == afterExplicit || (! state->indefinite));
  2229     state->place = beforeEndOfContents;
  2233 static void
  2234 sec_asn1d_prepare_for_end_of_contents (sec_asn1d_state *state)
  2236     PORT_Assert (state->place == beforeEndOfContents);
  2238     if (state->indefinite) {
  2239 	state->place = duringEndOfContents;
  2240 	state->pending = 2;
  2241     } else {
  2242 	state->place = afterEndOfContents;
  2247 static unsigned long
  2248 sec_asn1d_parse_end_of_contents (sec_asn1d_state *state,
  2249 				 const char *buf, unsigned long len)
  2251     unsigned int i;
  2253     PORT_Assert (state->pending <= 2);
  2254     PORT_Assert (state->place == duringEndOfContents);
  2256     if (len == 0) {
  2257 	state->top->status = needBytes;
  2258 	return 0;
  2261     if (state->pending < len)
  2262 	len = state->pending;
  2264     for (i = 0; i < len; i++) {
  2265 	if (buf[i] != 0) {
  2266 	    /*
  2267 	     * We expect to find only zeros; if not, just give up.
  2268 	     */
  2269 	    PORT_SetError (SEC_ERROR_BAD_DER);
  2270 	    state->top->status = decodeError;
  2271 	    return 0;
  2275     state->pending -= len;
  2277     if (state->pending == 0) {
  2278 	state->place = afterEndOfContents;
  2279 	state->endofcontents = PR_TRUE;
  2282     return len;
  2286 static void
  2287 sec_asn1d_pop_state (sec_asn1d_state *state)
  2289 #if 0	/* XXX I think this should always be handled explicitly by parent? */
  2290     /*
  2291      * Account for our child.
  2292      */
  2293     if (state->child != NULL) {
  2294 	state->consumed += state->child->consumed;
  2295 	if (state->pending) {
  2296 	    PORT_Assert (!state->indefinite);
  2297 	    if (state->child->consumed > state->pending) {
  2298 		PORT_SetError (SEC_ERROR_BAD_DER);
  2299 		state->top->status = decodeError;
  2300 	    } else {
  2301 		state->pending -= state->child->consumed;
  2304 	state->child->consumed = 0;
  2306 #endif	/* XXX */
  2308     /*
  2309      * Free our child.
  2310      */
  2311     sec_asn1d_free_child (state, PR_FALSE);
  2313     /*
  2314      * Just make my parent be the current state.  It will then clean
  2315      * up after me and free me (or reuse me).
  2316      */
  2317     state->top->current = state->parent;
  2320 static sec_asn1d_state *
  2321 sec_asn1d_before_choice (sec_asn1d_state *state)
  2323     sec_asn1d_state *child;
  2325     if (state->allocate) {
  2326 	void *dest;
  2328 	dest = sec_asn1d_zalloc(state->top->their_pool, state->theTemplate->size);
  2329 	if ((void *)NULL == dest) {
  2330 	    state->top->status = decodeError;
  2331 	    return (sec_asn1d_state *)NULL;
  2334 	state->dest = (char *)dest + state->theTemplate->offset;
  2337     child = sec_asn1d_push_state(state->top, state->theTemplate + 1, 
  2338 				 (char *)state->dest - state->theTemplate->offset, 
  2339 				 PR_FALSE);
  2340     if ((sec_asn1d_state *)NULL == child) {
  2341 	return (sec_asn1d_state *)NULL;
  2344     sec_asn1d_scrub_state(child);
  2345     child = sec_asn1d_init_state_based_on_template(child);
  2346     if ((sec_asn1d_state *)NULL == child) {
  2347 	return (sec_asn1d_state *)NULL;
  2350     child->optional = PR_TRUE;
  2352     state->place = duringChoice;
  2354     return child;
  2357 static sec_asn1d_state *
  2358 sec_asn1d_during_choice (sec_asn1d_state *state)
  2360     sec_asn1d_state *child = state->child;
  2362     PORT_Assert((sec_asn1d_state *)NULL != child);
  2364     if (child->missing) {
  2365 	unsigned char child_found_tag_modifiers = 0;
  2366 	unsigned long child_found_tag_number = 0;
  2367 	void *        dest;
  2369 	state->consumed += child->consumed;
  2371 	if (child->endofcontents) {
  2372 	    /* This choice is probably the first item in a GROUP
  2373 	    ** (e.g. SET_OF) that was indefinite-length encoded.
  2374 	    ** We're actually at the end of that GROUP.
  2375 	    ** We look up the stack to be sure that we find
  2376 	    ** a state with indefinite length encoding before we
  2377 	    ** find a state (like a SEQUENCE) that is definite.
  2378 	    */
  2379 	    child->place = notInUse;
  2380 	    state->place = afterChoice;
  2381 	    state->endofcontents = PR_TRUE;  /* propagate this up */
  2382 	    if (sec_asn1d_parent_allows_EOC(state))
  2383 		return state;
  2384 	    PORT_SetError(SEC_ERROR_BAD_DER);
  2385 	    state->top->status = decodeError;
  2386 	    return NULL;
  2389 	dest = (char *)child->dest - child->theTemplate->offset;
  2390 	child->theTemplate++;
  2392 	if (0 == child->theTemplate->kind) {
  2393 	    /* Ran out of choices */
  2394 	    PORT_SetError(SEC_ERROR_BAD_DER);
  2395 	    state->top->status = decodeError;
  2396 	    return (sec_asn1d_state *)NULL;
  2398 	child->dest = (char *)dest + child->theTemplate->offset;
  2400 	/* cargo'd from next_in_sequence innards */
  2401 	if (state->pending) {
  2402 	    PORT_Assert(!state->indefinite);
  2403 	    if (child->consumed > state->pending) {
  2404 		PORT_SetError (SEC_ERROR_BAD_DER);
  2405 		state->top->status = decodeError;
  2406 		return NULL;
  2408 	    state->pending -= child->consumed;
  2409 	    if (0 == state->pending) {
  2410 		/* XXX uh.. not sure if I should have stopped this
  2411 		 * from happening before. */
  2412 		PORT_Assert(0);
  2413 		PORT_SetError(SEC_ERROR_BAD_DER);
  2414 		state->top->status = decodeError;
  2415 		return (sec_asn1d_state *)NULL;
  2419 	child->consumed = 0;
  2420 	sec_asn1d_scrub_state(child);
  2422 	/* move it on top again */
  2423 	state->top->current = child;
  2425 	child_found_tag_modifiers = child->found_tag_modifiers;
  2426 	child_found_tag_number = child->found_tag_number;
  2428 	child = sec_asn1d_init_state_based_on_template(child);
  2429 	if ((sec_asn1d_state *)NULL == child) {
  2430 	    return (sec_asn1d_state *)NULL;
  2433 	/* copy our findings to the new top */
  2434 	child->found_tag_modifiers = child_found_tag_modifiers;
  2435 	child->found_tag_number = child_found_tag_number;
  2437 	child->optional = PR_TRUE;
  2438 	child->place = afterIdentifier;
  2440 	return child;
  2442     if ((void *)NULL != state->dest) {
  2443 	/* Store the enum */
  2444 	int *which = (int *)state->dest;
  2445 	*which = (int)child->theTemplate->size;
  2448     child->place = notInUse;
  2450     state->place = afterChoice;
  2451     return state;
  2454 static void
  2455 sec_asn1d_after_choice (sec_asn1d_state *state)
  2457     state->consumed += state->child->consumed;
  2458     state->child->consumed = 0;
  2459     state->place = afterEndOfContents;
  2460     sec_asn1d_pop_state(state);
  2463 unsigned long
  2464 sec_asn1d_uinteger(SECItem *src)
  2466     unsigned long value;
  2467     int len;
  2469     if (src->len > 5 || (src->len > 4 && src->data[0] == 0))
  2470 	return 0;
  2472     value = 0;
  2473     len = src->len;
  2474     while (len) {
  2475 	value <<= 8;
  2476 	value |= src->data[--len];
  2478     return value;
  2481 SECStatus
  2482 SEC_ASN1DecodeInteger(SECItem *src, unsigned long *value)
  2484     unsigned long v;
  2485     unsigned int i;
  2487     if (src == NULL) {
  2488 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
  2489 	return SECFailure;
  2492     if (src->len > sizeof(unsigned long)) {
  2493 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
  2494 	return SECFailure;
  2497     if (src->data == NULL) {
  2498 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
  2499     	return SECFailure;
  2502     if (src->data[0] & 0x80)
  2503 	v = -1;		/* signed and negative - start with all 1's */
  2504     else
  2505 	v = 0;
  2507     for (i= 0; i < src->len; i++) {
  2508 	/* shift in next byte */
  2509 	v <<= 8;
  2510 	v |= src->data[i];
  2512     *value = v;
  2513     return SECSuccess;
  2516 #ifdef DEBUG_ASN1D_STATES
  2517 static void
  2518 dump_states(SEC_ASN1DecoderContext *cx)
  2520     sec_asn1d_state *state;
  2521     char kindBuf[256];
  2523     for (state = cx->current; state->parent; state = state->parent) {
  2527     for (; state; state = state->child) {
  2528         int i;
  2529         for (i = 0; i < state->depth; i++) {
  2530             printf("  ");
  2533         i = formatKind(state->theTemplate->kind, kindBuf);
  2534         printf("%s: tmpl %08x, kind%s",
  2535                (state == cx->current) ? "STATE" : "State",
  2536                state->theTemplate,
  2537                kindBuf);
  2538         printf(" %s", (state->place >= 0 && state->place <= notInUse)
  2539                        ? place_names[ state->place ]
  2540                        : "(undefined)");
  2541         if (!i)
  2542             printf(", expect 0x%02x",
  2543                    state->expect_tag_number | state->expect_tag_modifiers);
  2545         printf("%s%s%s %d\n",
  2546                state->indefinite    ? ", indef"   : "",
  2547                state->missing       ? ", miss"    : "",
  2548                state->endofcontents ? ", EOC"     : "",
  2549                state->pending
  2550                );
  2553     return;
  2555 #endif /* DEBUG_ASN1D_STATES */
  2557 SECStatus
  2558 SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx,
  2559 		       const char *buf, unsigned long len)
  2561     sec_asn1d_state *state = NULL;
  2562     unsigned long consumed;
  2563     SEC_ASN1EncodingPart what;
  2564     sec_asn1d_state *stateEnd = cx->current;
  2566     if (cx->status == needBytes)
  2567 	cx->status = keepGoing;
  2569     while (cx->status == keepGoing) {
  2570 	state = cx->current;
  2571 	what = SEC_ASN1_Contents;
  2572 	consumed = 0;
  2573 #ifdef DEBUG_ASN1D_STATES
  2574         printf("\nPLACE = %s, next byte = 0x%02x, %08x[%d]\n",
  2575                (state->place >= 0 && state->place <= notInUse) ?
  2576                place_names[ state->place ] : "(undefined)",
  2577                (unsigned int)((unsigned char *)buf)[ consumed ],
  2578                buf, consumed);
  2579         dump_states(cx);
  2580 #endif /* DEBUG_ASN1D_STATES */
  2581 	switch (state->place) {
  2582 	  case beforeIdentifier:
  2583 	    consumed = sec_asn1d_parse_identifier (state, buf, len);
  2584 	    what = SEC_ASN1_Identifier;
  2585 	    break;
  2586 	  case duringIdentifier:
  2587 	    consumed = sec_asn1d_parse_more_identifier (state, buf, len);
  2588 	    what = SEC_ASN1_Identifier;
  2589 	    break;
  2590 	  case afterIdentifier:
  2591 	    sec_asn1d_confirm_identifier (state);
  2592 	    break;
  2593 	  case beforeLength:
  2594 	    consumed = sec_asn1d_parse_length (state, buf, len);
  2595 	    what = SEC_ASN1_Length;
  2596 	    break;
  2597 	  case duringLength:
  2598 	    consumed = sec_asn1d_parse_more_length (state, buf, len);
  2599 	    what = SEC_ASN1_Length;
  2600 	    break;
  2601 	  case afterLength:
  2602 	    sec_asn1d_prepare_for_contents (state);
  2603 	    break;
  2604 	  case beforeBitString:
  2605 	    consumed = sec_asn1d_parse_bit_string (state, buf, len);
  2606 	    break;
  2607 	  case duringBitString:
  2608 	    consumed = sec_asn1d_parse_more_bit_string (state, buf, len);
  2609 	    break;
  2610 	  case duringConstructedString:
  2611 	    sec_asn1d_next_substring (state);
  2612 	    break;
  2613 	  case duringGroup:
  2614 	    sec_asn1d_next_in_group (state);
  2615 	    break;
  2616 	  case duringLeaf:
  2617 	    consumed = sec_asn1d_parse_leaf (state, buf, len);
  2618 	    break;
  2619 	  case duringSaveEncoding:
  2620 	    sec_asn1d_reuse_encoding (state);
  2621 	    if (cx->status == decodeError) {
  2622 		/* recursive call has already popped all states from stack.
  2623 		** Bail out quickly.
  2624 		*/
  2625 		return SECFailure;
  2627 	    if (cx->status == needBytes) {
  2628 		/* recursive call wanted more data. Fatal. Clean up below. */
  2629 		PORT_SetError (SEC_ERROR_BAD_DER);
  2630 		cx->status = decodeError;
  2632 	    break;
  2633 	  case duringSequence:
  2634 	    sec_asn1d_next_in_sequence (state);
  2635 	    break;
  2636 	  case afterConstructedString:
  2637 	    sec_asn1d_concat_substrings (state);
  2638 	    break;
  2639 	  case afterExplicit:
  2640 	  case afterImplicit:
  2641 	  case afterInline:
  2642 	  case afterPointer:
  2643 	    sec_asn1d_absorb_child (state);
  2644 	    break;
  2645 	  case afterGroup:
  2646 	    sec_asn1d_concat_group (state);
  2647 	    break;
  2648 	  case afterSaveEncoding:
  2649 	    /* SEC_ASN1DecoderUpdate has called itself recursively to 
  2650 	    ** decode SAVEd encoded data, and now is done decoding that.
  2651 	    ** Return to the calling copy of SEC_ASN1DecoderUpdate.
  2652 	    */
  2653 	    return SECSuccess;
  2654 	  case beforeEndOfContents:
  2655 	    sec_asn1d_prepare_for_end_of_contents (state);
  2656 	    break;
  2657 	  case duringEndOfContents:
  2658 	    consumed = sec_asn1d_parse_end_of_contents (state, buf, len);
  2659 	    what = SEC_ASN1_EndOfContents;
  2660 	    break;
  2661 	  case afterEndOfContents:
  2662 	    sec_asn1d_pop_state (state);
  2663 	    break;
  2664           case beforeChoice:
  2665             state = sec_asn1d_before_choice(state);
  2666             break;
  2667           case duringChoice:
  2668             state = sec_asn1d_during_choice(state);
  2669             break;
  2670           case afterChoice:
  2671             sec_asn1d_after_choice(state);
  2672             break;
  2673 	  case notInUse:
  2674 	  default:
  2675 	    /* This is not an error, but rather a plain old BUG! */
  2676 	    PORT_Assert (0);
  2677 	    PORT_SetError (SEC_ERROR_BAD_DER);
  2678 	    cx->status = decodeError;
  2679 	    break;
  2682 	if (cx->status == decodeError)
  2683 	    break;
  2685 	/* We should not consume more than we have.  */
  2686 	PORT_Assert (consumed <= len);
  2687 	if (consumed > len) {
  2688 	    PORT_SetError (SEC_ERROR_BAD_DER);
  2689 	    cx->status = decodeError;
  2690 	    break;
  2693 	/* It might have changed, so we have to update our local copy.  */
  2694 	state = cx->current;
  2696 	/* If it is NULL, we have popped all the way to the top.  */
  2697 	if (state == NULL) {
  2698 	    PORT_Assert (consumed == 0);
  2699 #if 0	/* XXX I want this here, but it seems that we have situations (like
  2700 	 * downloading a pkcs7 cert chain from some issuers) that give us a
  2701 	 * length which is greater than the entire encoding.  So, we cannot
  2702 	 * have this be an error.
  2703 	 */
  2704 	    if (len > 0) {
  2705 		PORT_SetError (SEC_ERROR_BAD_DER);
  2706 		cx->status = decodeError;
  2707 	    } else
  2708 #endif
  2709 		cx->status = allDone;
  2710 	    break;
  2712 	else if (state->theTemplate->kind == SEC_ASN1_SKIP_REST) {
  2713 	    cx->status = allDone;
  2714 	    break;
  2717 	if (consumed == 0)
  2718 	    continue;
  2720 	/*
  2721 	 * The following check is specifically looking for an ANY
  2722 	 * that is *not* also an INNER, because we need to save aside
  2723 	 * all bytes in that case -- the contents parts will get
  2724 	 * handled like all other contents, and the end-of-contents
  2725 	 * bytes are added by the concat code, but the outer header
  2726 	 * bytes need to get saved too, so we do them explicitly here.
  2727 	 */
  2728 	if (state->underlying_kind == SEC_ASN1_ANY
  2729 	    && !cx->filter_only && (what == SEC_ASN1_Identifier
  2730 				    || what == SEC_ASN1_Length)) {
  2731 	    sec_asn1d_record_any_header (state, buf, consumed);
  2734 	/*
  2735 	 * We had some number of good, accepted bytes.  If the caller
  2736 	 * has registered to see them, pass them along.
  2737 	 */
  2738 	if (state->top->filter_proc != NULL) {
  2739 	    int depth;
  2741 	    depth = state->depth;
  2742 	    if (what == SEC_ASN1_EndOfContents && !state->indefinite) {
  2743 		PORT_Assert (state->parent != NULL
  2744 			     && state->parent->indefinite);
  2745 		depth--;
  2746 		PORT_Assert (depth == state->parent->depth);
  2748 	    (* state->top->filter_proc) (state->top->filter_arg,
  2749 					 buf, consumed, depth, what);
  2752 	state->consumed += consumed;
  2753 	buf += consumed;
  2754 	len -= consumed;
  2757     if (cx->status == decodeError) {
  2758 	while (state != NULL && stateEnd->parent!=state) {
  2759 	    sec_asn1d_free_child (state, PR_TRUE);
  2760 	    state = state->parent;
  2762 #ifdef SEC_ASN1D_FREE_ON_ERROR	/*
  2763 				 * XXX This does not work because we can
  2764 				 * end up leaving behind dangling pointers
  2765 				 * to stuff that was allocated.  In order
  2766 				 * to make this really work (which would
  2767 				 * be a good thing, I think), we need to
  2768 				 * keep track of every place/pointer that
  2769 				 * was allocated and make sure to NULL it
  2770 				 * out before we then free back to the mark.	
  2771 				 */
  2772 	if (cx->their_pool != NULL) {
  2773 	    PORT_Assert (cx->their_mark != NULL);
  2774 	    PORT_ArenaRelease (cx->their_pool, cx->their_mark);
  2775 	    cx->their_mark = NULL;
  2777 #endif
  2778 	return SECFailure;
  2781 #if 0	/* XXX This is what I want, but cannot have because it seems we
  2782 	 * have situations (like when downloading a pkcs7 cert chain from
  2783 	 * some issuers) that give us a total length which is greater than
  2784 	 * the entire encoding.  So, we have to allow allDone to have a
  2785 	 * remaining length greater than zero.  I wanted to catch internal
  2786 	 * bugs with this, noticing when we do not have the right length.
  2787 	 * Oh well.
  2788 	 */
  2789     PORT_Assert (len == 0
  2790 		 && (cx->status == needBytes || cx->status == allDone));
  2791 #else
  2792     PORT_Assert ((len == 0 && cx->status == needBytes)
  2793 		 || cx->status == allDone);
  2794 #endif
  2795     return SECSuccess;
  2799 SECStatus
  2800 SEC_ASN1DecoderFinish (SEC_ASN1DecoderContext *cx)
  2802     SECStatus rv;
  2804     if (cx->status == needBytes) {
  2805 	PORT_SetError (SEC_ERROR_BAD_DER);
  2806 	rv = SECFailure;
  2807     } else {
  2808 	rv = SECSuccess;
  2811     /*
  2812      * XXX anything else that needs to be finished?
  2813      */
  2815     PORT_FreeArena (cx->our_pool, PR_TRUE);
  2817     return rv;
  2821 SEC_ASN1DecoderContext *
  2822 SEC_ASN1DecoderStart (PLArenaPool *their_pool, void *dest,
  2823 		      const SEC_ASN1Template *theTemplate)
  2825     PLArenaPool *our_pool;
  2826     SEC_ASN1DecoderContext *cx;
  2828     our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
  2829     if (our_pool == NULL)
  2830 	return NULL;
  2832     cx = (SEC_ASN1DecoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx));
  2833     if (cx == NULL) {
  2834 	PORT_FreeArena (our_pool, PR_FALSE);
  2835 	return NULL;
  2838     cx->our_pool = our_pool;
  2839     if (their_pool != NULL) {
  2840 	cx->their_pool = their_pool;
  2841 #ifdef SEC_ASN1D_FREE_ON_ERROR
  2842 	cx->their_mark = PORT_ArenaMark (their_pool);
  2843 #endif
  2846     cx->status = needBytes;
  2848     if (sec_asn1d_push_state(cx, theTemplate, dest, PR_FALSE) == NULL
  2849 	|| sec_asn1d_init_state_based_on_template (cx->current) == NULL) {
  2850 	/*
  2851 	 * Trouble initializing (probably due to failed allocations)
  2852 	 * requires that we just give up.
  2853 	 */
  2854 	PORT_FreeArena (our_pool, PR_FALSE);
  2855 	return NULL;
  2858     return cx;
  2862 void
  2863 SEC_ASN1DecoderSetFilterProc (SEC_ASN1DecoderContext *cx,
  2864 			      SEC_ASN1WriteProc fn, void *arg,
  2865 			      PRBool only)
  2867     /* check that we are "between" fields here */
  2868     PORT_Assert (cx->during_notify);
  2870     cx->filter_proc = fn;
  2871     cx->filter_arg = arg;
  2872     cx->filter_only = only;
  2876 void
  2877 SEC_ASN1DecoderClearFilterProc (SEC_ASN1DecoderContext *cx)
  2879     /* check that we are "between" fields here */
  2880     PORT_Assert (cx->during_notify);
  2882     cx->filter_proc = NULL;
  2883     cx->filter_arg = NULL;
  2884     cx->filter_only = PR_FALSE;
  2888 void
  2889 SEC_ASN1DecoderSetNotifyProc (SEC_ASN1DecoderContext *cx,
  2890 			      SEC_ASN1NotifyProc fn, void *arg)
  2892     cx->notify_proc = fn;
  2893     cx->notify_arg = arg;
  2897 void
  2898 SEC_ASN1DecoderClearNotifyProc (SEC_ASN1DecoderContext *cx)
  2900     cx->notify_proc = NULL;
  2901     cx->notify_arg = NULL;	/* not necessary; just being clean */
  2904 void
  2905 SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error)
  2907     PORT_Assert(cx);
  2908     PORT_SetError(error);
  2909     cx->status = decodeError;
  2913 SECStatus
  2914 SEC_ASN1Decode (PLArenaPool *poolp, void *dest,
  2915 		const SEC_ASN1Template *theTemplate,
  2916 		const char *buf, long len)
  2918     SEC_ASN1DecoderContext *dcx;
  2919     SECStatus urv, frv;
  2921     dcx = SEC_ASN1DecoderStart (poolp, dest, theTemplate);
  2922     if (dcx == NULL)
  2923 	return SECFailure;
  2925     urv = SEC_ASN1DecoderUpdate (dcx, buf, len);
  2926     frv = SEC_ASN1DecoderFinish (dcx);
  2928     if (urv != SECSuccess)
  2929 	return urv;
  2931     return frv;
  2935 SECStatus
  2936 SEC_ASN1DecodeItem (PLArenaPool *poolp, void *dest,
  2937 		    const SEC_ASN1Template *theTemplate,
  2938 		    const SECItem *src)
  2940     return SEC_ASN1Decode (poolp, dest, theTemplate,
  2941 			   (const char *)src->data, src->len);
  2944 #ifdef DEBUG_ASN1D_STATES
  2945 void sec_asn1d_Assert(const char *s, const char *file, PRIntn ln)
  2947     printf("Assertion failed, \"%s\", file %s, line %d\n", s, file, ln);
  2948     fflush(stdout);
  2950 #endif
  2952 /*
  2953  * Generic templates for individual/simple items and pointers to
  2954  * and sets of same.
  2956  * If you need to add a new one, please note the following:
  2957  *	 - For each new basic type you should add *four* templates:
  2958  *	one plain, one PointerTo, one SequenceOf and one SetOf.
  2959  *	 - If the new type can be constructed (meaning, it is a
  2960  *	*string* type according to BER/DER rules), then you should
  2961  *	or-in SEC_ASN1_MAY_STREAM to the type in the basic template.
  2962  *	See the definition of the OctetString template for an example.
  2963  *	 - It may not be obvious, but these are in *alphabetical*
  2964  *	order based on the SEC_ASN1_XXX name; so put new ones in
  2965  *	the appropriate place.
  2966  */
  2968 const SEC_ASN1Template SEC_SequenceOfAnyTemplate[] = {
  2969     { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }
  2970 };
  2972 #if 0
  2974 const SEC_ASN1Template SEC_PointerToBitStringTemplate[] = {
  2975     { SEC_ASN1_POINTER, 0, SEC_BitStringTemplate }
  2976 };
  2978 const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[] = {
  2979     { SEC_ASN1_SEQUENCE_OF, 0, SEC_BitStringTemplate }
  2980 };
  2982 const SEC_ASN1Template SEC_SetOfBitStringTemplate[] = {
  2983     { SEC_ASN1_SET_OF, 0, SEC_BitStringTemplate }
  2984 };
  2986 const SEC_ASN1Template SEC_PointerToBMPStringTemplate[] = {
  2987     { SEC_ASN1_POINTER, 0, SEC_BMPStringTemplate }
  2988 };
  2990 const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[] = {
  2991     { SEC_ASN1_SEQUENCE_OF, 0, SEC_BMPStringTemplate }
  2992 };
  2994 const SEC_ASN1Template SEC_SetOfBMPStringTemplate[] = {
  2995     { SEC_ASN1_SET_OF, 0, SEC_BMPStringTemplate }
  2996 };
  2998 const SEC_ASN1Template SEC_PointerToBooleanTemplate[] = {
  2999     { SEC_ASN1_POINTER, 0, SEC_BooleanTemplate }
  3000 };
  3002 const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[] = {
  3003     { SEC_ASN1_SEQUENCE_OF, 0, SEC_BooleanTemplate }
  3004 };
  3006 const SEC_ASN1Template SEC_SetOfBooleanTemplate[] = {
  3007     { SEC_ASN1_SET_OF, 0, SEC_BooleanTemplate }
  3008 };
  3010 #endif
  3012 const SEC_ASN1Template SEC_EnumeratedTemplate[] = {
  3013     { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) }
  3014 };
  3016 const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[] = {
  3017     { SEC_ASN1_POINTER, 0, SEC_EnumeratedTemplate }
  3018 };
  3020 #if 0
  3022 const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[] = {
  3023     { SEC_ASN1_SEQUENCE_OF, 0, SEC_EnumeratedTemplate }
  3024 };
  3026 #endif
  3028 const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[] = {
  3029     { SEC_ASN1_SET_OF, 0, SEC_EnumeratedTemplate }
  3030 };
  3032 const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[] = {
  3033     { SEC_ASN1_POINTER, 0, SEC_GeneralizedTimeTemplate }
  3034 };
  3036 #if 0
  3038 const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[] = {
  3039     { SEC_ASN1_SEQUENCE_OF, 0, SEC_GeneralizedTimeTemplate }
  3040 };
  3042 const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[] = {
  3043     { SEC_ASN1_SET_OF, 0, SEC_GeneralizedTimeTemplate }
  3044 };
  3046 const SEC_ASN1Template SEC_PointerToIA5StringTemplate[] = {
  3047     { SEC_ASN1_POINTER, 0, SEC_IA5StringTemplate }
  3048 };
  3050 const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[] = {
  3051     { SEC_ASN1_SEQUENCE_OF, 0, SEC_IA5StringTemplate }
  3052 };
  3054 const SEC_ASN1Template SEC_SetOfIA5StringTemplate[] = {
  3055     { SEC_ASN1_SET_OF, 0, SEC_IA5StringTemplate }
  3056 };
  3058 const SEC_ASN1Template SEC_PointerToIntegerTemplate[] = {
  3059     { SEC_ASN1_POINTER, 0, SEC_IntegerTemplate }
  3060 };
  3062 const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[] = {
  3063     { SEC_ASN1_SEQUENCE_OF, 0, SEC_IntegerTemplate }
  3064 };
  3066 const SEC_ASN1Template SEC_SetOfIntegerTemplate[] = {
  3067     { SEC_ASN1_SET_OF, 0, SEC_IntegerTemplate }
  3068 };
  3070 const SEC_ASN1Template SEC_PointerToNullTemplate[] = {
  3071     { SEC_ASN1_POINTER, 0, SEC_NullTemplate }
  3072 };
  3074 const SEC_ASN1Template SEC_SequenceOfNullTemplate[] = {
  3075     { SEC_ASN1_SEQUENCE_OF, 0, SEC_NullTemplate }
  3076 };
  3078 const SEC_ASN1Template SEC_SetOfNullTemplate[] = {
  3079     { SEC_ASN1_SET_OF, 0, SEC_NullTemplate }
  3080 };
  3082 const SEC_ASN1Template SEC_PointerToObjectIDTemplate[] = {
  3083     { SEC_ASN1_POINTER, 0, SEC_ObjectIDTemplate }
  3084 };
  3086 #endif
  3088 const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[] = {
  3089     { SEC_ASN1_SEQUENCE_OF, 0, SEC_ObjectIDTemplate }
  3090 };
  3092 #if 0
  3094 const SEC_ASN1Template SEC_SetOfObjectIDTemplate[] = {
  3095     { SEC_ASN1_SET_OF, 0, SEC_ObjectIDTemplate }
  3096 };
  3098 const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[] = {
  3099     { SEC_ASN1_SEQUENCE_OF, 0, SEC_OctetStringTemplate }
  3100 };
  3102 const SEC_ASN1Template SEC_SetOfOctetStringTemplate[] = {
  3103     { SEC_ASN1_SET_OF, 0, SEC_OctetStringTemplate }
  3104 };
  3106 #endif
  3108 const SEC_ASN1Template SEC_PrintableStringTemplate[] = {
  3109     { SEC_ASN1_PRINTABLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
  3110 };
  3112 #if 0
  3114 const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[] = {
  3115     { SEC_ASN1_POINTER, 0, SEC_PrintableStringTemplate }
  3116 };
  3118 const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[] = {
  3119     { SEC_ASN1_SEQUENCE_OF, 0, SEC_PrintableStringTemplate }
  3120 };
  3122 const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[] = {
  3123     { SEC_ASN1_SET_OF, 0, SEC_PrintableStringTemplate }
  3124 };
  3126 #endif
  3128 const SEC_ASN1Template SEC_T61StringTemplate[] = {
  3129     { SEC_ASN1_T61_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
  3130 };
  3132 #if 0
  3134 const SEC_ASN1Template SEC_PointerToT61StringTemplate[] = {
  3135     { SEC_ASN1_POINTER, 0, SEC_T61StringTemplate }
  3136 };
  3138 const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[] = {
  3139     { SEC_ASN1_SEQUENCE_OF, 0, SEC_T61StringTemplate }
  3140 };
  3142 const SEC_ASN1Template SEC_SetOfT61StringTemplate[] = {
  3143     { SEC_ASN1_SET_OF, 0, SEC_T61StringTemplate }
  3144 };
  3146 #endif
  3148 const SEC_ASN1Template SEC_UniversalStringTemplate[] = {
  3149     { SEC_ASN1_UNIVERSAL_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
  3150 };
  3152 #if 0
  3154 const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[] = {
  3155     { SEC_ASN1_POINTER, 0, SEC_UniversalStringTemplate }
  3156 };
  3158 const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[] = {
  3159     { SEC_ASN1_SEQUENCE_OF, 0, SEC_UniversalStringTemplate }
  3160 };
  3162 const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[] = {
  3163     { SEC_ASN1_SET_OF, 0, SEC_UniversalStringTemplate }
  3164 };
  3166 const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[] = {
  3167     { SEC_ASN1_POINTER, 0, SEC_UTCTimeTemplate }
  3168 };
  3170 const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[] = {
  3171     { SEC_ASN1_SEQUENCE_OF, 0, SEC_UTCTimeTemplate }
  3172 };
  3174 const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[] = {
  3175     { SEC_ASN1_SET_OF, 0, SEC_UTCTimeTemplate }
  3176 };
  3178 const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[] = {
  3179     { SEC_ASN1_POINTER, 0, SEC_UTF8StringTemplate }
  3180 };
  3182 const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[] = {
  3183     { SEC_ASN1_SEQUENCE_OF, 0, SEC_UTF8StringTemplate }
  3184 };
  3186 const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[] = {
  3187     { SEC_ASN1_SET_OF, 0, SEC_UTF8StringTemplate }
  3188 };
  3190 #endif
  3192 const SEC_ASN1Template SEC_VisibleStringTemplate[] = {
  3193     { SEC_ASN1_VISIBLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
  3194 };
  3196 #if 0
  3198 const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[] = {
  3199     { SEC_ASN1_POINTER, 0, SEC_VisibleStringTemplate }
  3200 };
  3202 const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[] = {
  3203     { SEC_ASN1_SEQUENCE_OF, 0, SEC_VisibleStringTemplate }
  3204 };
  3206 const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[] = {
  3207     { SEC_ASN1_SET_OF, 0, SEC_VisibleStringTemplate }
  3208 };
  3210 #endif
  3212 /*
  3213  * Template for skipping a subitem.
  3215  * Note that it only makes sense to use this for decoding (when you want
  3216  * to decode something where you are only interested in one or two of
  3217  * the fields); you cannot encode a SKIP!
  3218  */
  3219 const SEC_ASN1Template SEC_SkipTemplate[] = {
  3220     { SEC_ASN1_SKIP }
  3221 };
  3224 /* These functions simply return the address of the above-declared templates.
  3225 ** This is necessary for Windows DLLs.  Sigh.
  3226 */
  3227 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_EnumeratedTemplate)
  3228 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToEnumeratedTemplate)
  3229 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfAnyTemplate)
  3230 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfObjectIDTemplate)
  3231 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SkipTemplate)
  3232 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UniversalStringTemplate)
  3233 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PrintableStringTemplate)
  3234 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_T61StringTemplate)
  3235 SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToGeneralizedTimeTemplate)

mercurial