tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

secasn1d.c (113728B)


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