Coverage Report

Created: 2025-08-18 06:34

/src/nss/lib/util/secasn1d.c
Line
Count
Source (jump to first uncovered line)
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
7.62M
#define IS_HIGH_TAG_NUMBER(n) ((n) == SEC_ASN1_HIGH_TAG_NUMBER)
261
218M
#define LAST_TAG_NUMBER_BYTE(b) (((b)&0x80) == 0)
262
218M
#define TAG_NUMBER_BITS 7
263
218M
#define TAG_NUMBER_MASK 0x7f
264
265
6.84M
#define LENGTH_IS_SHORT_FORM(b) (((b)&0x80) == 0)
266
741k
#define LONG_FORM_LENGTH(b) ((b)&0x7f)
267
268
218M
#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
43.1M
{
321
43.1M
    void *thing;
322
323
43.1M
    if (poolp != NULL) {
324
        /*
325
         * Allocate from the pool.
326
         */
327
43.1M
        thing = PORT_ArenaAlloc(poolp, len);
328
43.1M
    } else {
329
        /*
330
         * Allocate generically.
331
         */
332
0
        thing = PORT_Alloc(len);
333
0
    }
334
335
43.1M
    return thing;
336
43.1M
}
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
30.5M
{
344
30.5M
    void *thing;
345
346
30.5M
    thing = sec_asn1d_alloc(poolp, len);
347
30.5M
    if (thing != NULL)
348
30.5M
        PORT_Memset(thing, 0, len);
349
30.5M
    return thing;
350
30.5M
}
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
901k
{
357
901k
    sec_asn1d_state *state, *new_state;
358
359
901k
    state = cx->current;
360
361
901k
    PORT_Assert(state == NULL || state->child == NULL);
362
363
901k
    if (state != NULL) {
364
766k
        PORT_Assert(state->our_mark == NULL);
365
766k
        state->our_mark = PORT_ArenaMark(cx->our_pool);
366
766k
    }
367
368
901k
    if (theTemplate == NULL) {
369
0
        PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
370
0
        goto loser;
371
0
    }
372
373
901k
    new_state = (sec_asn1d_state *)sec_asn1d_zalloc(cx->our_pool,
374
901k
                                                    sizeof(*new_state));
375
901k
    if (new_state == NULL) {
376
0
        goto loser;
377
0
    }
378
379
901k
    new_state->top = cx;
380
901k
    new_state->parent = state;
381
901k
    new_state->theTemplate = theTemplate;
382
901k
    new_state->place = notInUse;
383
901k
    if (dest != NULL)
384
800k
        new_state->dest = (char *)dest + theTemplate->offset;
385
386
901k
    if (state != NULL) {
387
766k
        new_state->depth = state->depth;
388
766k
        if (new_depth) {
389
744k
            if (++new_state->depth > SEC_ASN1D_MAX_DEPTH) {
390
45
                PORT_SetError(SEC_ERROR_BAD_DER);
391
45
                goto loser;
392
45
            }
393
744k
        }
394
766k
        state->child = new_state;
395
766k
    }
396
397
901k
    cx->current = new_state;
398
901k
    return new_state;
399
400
45
loser:
401
45
    cx->status = decodeError;
402
45
    if (state != NULL) {
403
45
        PORT_ArenaRelease(cx->our_pool, state->our_mark);
404
45
        state->our_mark = NULL;
405
45
    }
406
45
    return NULL;
407
901k
}
408
409
static void
410
sec_asn1d_scrub_state(sec_asn1d_state *state)
411
12.0M
{
412
    /*
413
     * Some default "scrubbing".
414
     * XXX right set of initializations?
415
     */
416
12.0M
    state->place = beforeIdentifier;
417
12.0M
    state->endofcontents = PR_FALSE;
418
12.0M
    state->indefinite = PR_FALSE;
419
12.0M
    state->missing = PR_FALSE;
420
12.0M
    PORT_Assert(state->consumed == 0);
421
12.0M
}
422
423
static void
424
sec_asn1d_notify_before(SEC_ASN1DecoderContext *cx, void *dest, int depth)
425
4.47M
{
426
4.47M
    if (cx->notify_proc == NULL)
427
4.47M
        return;
428
429
0
    cx->during_notify = PR_TRUE;
430
0
    (*cx->notify_proc)(cx->notify_arg, PR_TRUE, dest, depth);
431
0
    cx->during_notify = PR_FALSE;
432
0
}
433
434
static void
435
sec_asn1d_notify_after(SEC_ASN1DecoderContext *cx, void *dest, int depth)
436
4.44M
{
437
4.44M
    if (cx->notify_proc == NULL)
438
4.44M
        return;
439
440
0
    cx->during_notify = PR_TRUE;
441
0
    (*cx->notify_proc)(cx->notify_arg, PR_FALSE, dest, depth);
442
0
    cx->during_notify = PR_FALSE;
443
0
}
444
445
static sec_asn1d_state *
446
sec_asn1d_init_state_based_on_template(sec_asn1d_state *state)
447
5.34M
{
448
5.34M
    PRBool explicit, optional, universal;
449
5.34M
    unsigned char expect_tag_modifiers;
450
5.34M
    unsigned long encode_kind, under_kind;
451
5.34M
    unsigned long check_tag_mask, expect_tag_number;
452
453
    /* XXX Check that both of these tests are really needed/appropriate. */
454
5.34M
    if (state == NULL || state->top->status == decodeError)
455
0
        return state;
456
457
5.34M
    encode_kind = state->theTemplate->kind;
458
459
5.34M
    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
2.70k
        PORT_Assert(encode_kind == SEC_ASN1_SAVE);
467
2.70k
        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
0
            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
0
            if (state->dest == NULL)
481
0
                state->dest = state->parent->dest;
482
0
            else
483
0
                state->dest = (char *)state->dest - state->theTemplate->offset;
484
0
            state->theTemplate++;
485
0
            if (state->dest != NULL)
486
0
                state->dest = (char *)state->dest + state->theTemplate->offset;
487
0
            sec_asn1d_notify_before(state->top, state->dest, state->depth);
488
0
            encode_kind = state->theTemplate->kind;
489
0
            PORT_Assert((encode_kind & SEC_ASN1_SAVE) == 0);
490
2.70k
        } else {
491
2.70k
            sec_asn1d_scrub_state(state);
492
2.70k
            state->place = duringSaveEncoding;
493
2.70k
            state = sec_asn1d_push_state(state->top, SEC_AnyTemplate,
494
2.70k
                                         state->dest, PR_FALSE);
495
2.70k
            if (state != NULL)
496
2.70k
                state = sec_asn1d_init_state_based_on_template(state);
497
2.70k
            return state;
498
2.70k
        }
499
2.70k
    }
500
501
5.33M
    universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
502
5.33M
                    ? PR_TRUE
503
5.33M
                    : PR_FALSE;
504
505
5.33M
    explicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
506
5.33M
    encode_kind &= ~SEC_ASN1_EXPLICIT;
507
508
5.33M
    optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
509
5.33M
    encode_kind &= ~SEC_ASN1_OPTIONAL;
510
511
5.33M
    PORT_Assert(!(explicit && universal)); /* bad templates */
512
513
5.33M
    encode_kind &= ~SEC_ASN1_DYNAMIC;
514
5.33M
    encode_kind &= ~SEC_ASN1_MAY_STREAM;
515
516
5.33M
    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
4.01k
        state->place = beforeChoice;
528
4.01k
        return state;
529
4.01k
#endif
530
4.01k
    }
531
532
5.33M
    if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || (!universal && !explicit)) {
533
15.4k
        const SEC_ASN1Template *subt;
534
15.4k
        void *dest;
535
15.4k
        PRBool child_allocate;
536
537
15.4k
        PORT_Assert((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0);
538
539
15.4k
        sec_asn1d_scrub_state(state);
540
15.4k
        child_allocate = PR_FALSE;
541
542
15.4k
        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
10.6k
            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
10.6k
                PORT_Assert(encode_kind == SEC_ASN1_POINTER);
564
10.6k
            } 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
0
                PORT_Assert((encode_kind & ~SEC_ASN1_TAG_MASK) == SEC_ASN1_POINTER);
575
0
            }
576
10.6k
            if (!state->top->filter_only)
577
10.6k
                child_allocate = PR_TRUE;
578
10.6k
            dest = NULL;
579
10.6k
            state->place = afterPointer;
580
10.6k
        } else {
581
4.73k
            dest = state->dest;
582
4.73k
            if (encode_kind & SEC_ASN1_INLINE) {
583
                /* check that there are no extraneous bits */
584
4.68k
                PORT_Assert(encode_kind == SEC_ASN1_INLINE);
585
4.68k
                state->place = afterInline;
586
4.68k
            } else {
587
46
                state->place = afterImplicit;
588
46
            }
589
4.73k
        }
590
591
15.4k
        state->optional = optional;
592
15.4k
        subt = SEC_ASN1GetSubtemplate(state->theTemplate, state->dest, PR_FALSE);
593
15.4k
        state = sec_asn1d_push_state(state->top, subt, dest, PR_FALSE);
594
15.4k
        if (state == NULL)
595
0
            return NULL;
596
597
15.4k
        state->allocate = child_allocate;
598
599
15.4k
        if (universal) {
600
15.3k
            state = sec_asn1d_init_state_based_on_template(state);
601
15.3k
            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
15.3k
                PORT_Assert(!state->optional);
611
15.3k
                state->optional = optional;
612
15.3k
            }
613
15.3k
            return state;
614
15.3k
        }
615
616
46
        under_kind = state->theTemplate->kind;
617
46
        under_kind &= ~SEC_ASN1_MAY_STREAM;
618
5.31M
    } 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
6.04k
        under_kind = 0;
628
5.31M
    } else {
629
        /*
630
         * Nothing special; the underlying kind and the given encoding
631
         * information are the same.
632
         */
633
5.31M
        under_kind = encode_kind;
634
5.31M
    }
635
636
    /* XXX is this the right set of bits to test here? */
637
5.31M
    PORT_Assert((under_kind & (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_MAY_STREAM | SEC_ASN1_INLINE | SEC_ASN1_POINTER)) == 0);
638
639
5.31M
    if (encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) {
640
5.13M
        PORT_Assert(encode_kind == under_kind);
641
5.13M
        if (encode_kind & SEC_ASN1_SKIP) {
642
80.8k
            PORT_Assert(!optional);
643
80.8k
            PORT_Assert(encode_kind == SEC_ASN1_SKIP);
644
80.8k
            state->dest = NULL;
645
80.8k
        }
646
5.13M
        check_tag_mask = 0;
647
5.13M
        expect_tag_modifiers = 0;
648
5.13M
        expect_tag_number = 0;
649
5.13M
    } else {
650
187k
        check_tag_mask = SEC_ASN1_TAG_MASK;
651
187k
        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
187k
        expect_tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK;
659
660
187k
        switch (under_kind & SEC_ASN1_TAGNUM_MASK) {
661
18.9k
            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
18.9k
                PORT_Assert((under_kind & SEC_ASN1_GROUP) != 0);
667
            /* fallthru */
668
86.2k
            case SEC_ASN1_SEQUENCE:
669
86.2k
                expect_tag_modifiers |= SEC_ASN1_CONSTRUCTED;
670
86.2k
                break;
671
3.83k
            case SEC_ASN1_BIT_STRING:
672
6.88k
            case SEC_ASN1_BMP_STRING:
673
15.6k
            case SEC_ASN1_GENERALIZED_TIME:
674
19.2k
            case SEC_ASN1_IA5_STRING:
675
26.7k
            case SEC_ASN1_OCTET_STRING:
676
29.9k
            case SEC_ASN1_PRINTABLE_STRING:
677
33.1k
            case SEC_ASN1_T61_STRING:
678
36.1k
            case SEC_ASN1_UNIVERSAL_STRING:
679
45.6k
            case SEC_ASN1_UTC_TIME:
680
48.8k
            case SEC_ASN1_UTF8_STRING:
681
51.8k
            case SEC_ASN1_VISIBLE_STRING:
682
51.8k
                check_tag_mask &= ~SEC_ASN1_CONSTRUCTED;
683
51.8k
                break;
684
187k
        }
685
187k
    }
686
687
5.31M
    state->check_tag_mask = check_tag_mask;
688
5.31M
    state->expect_tag_modifiers = expect_tag_modifiers;
689
5.31M
    state->expect_tag_number = expect_tag_number;
690
5.31M
    state->underlying_kind = under_kind;
691
5.31M
    state->explicit = explicit;
692
5.31M
    state->optional = optional;
693
694
5.31M
    sec_asn1d_scrub_state(state);
695
696
5.31M
    return state;
697
5.31M
}
698
699
static sec_asn1d_state *
700
sec_asn1d_get_enclosing_construct(sec_asn1d_state *state)
701
63.0M
{
702
64.1M
    for (state = state->parent; state; state = state->parent) {
703
60.3M
        sec_asn1d_parse_place place = state->place;
704
60.3M
        if (place != afterImplicit &&
705
60.3M
            place != afterPointer &&
706
60.3M
            place != afterInline &&
707
60.3M
            place != afterSaveEncoding &&
708
60.3M
            place != duringSaveEncoding &&
709
60.3M
            place != duringChoice) {
710
711
            /* we've walked up the stack to a state that represents
712
            ** the enclosing construct.
713
            */
714
59.2M
            break;
715
59.2M
        }
716
60.3M
    }
717
63.0M
    return state;
718
63.0M
}
719
720
static PRBool
721
sec_asn1d_parent_allows_EOC(sec_asn1d_state *state)
722
4.30M
{
723
    /* get state of enclosing construct. */
724
4.30M
    state = sec_asn1d_get_enclosing_construct(state);
725
4.30M
    if (state) {
726
4.30M
        sec_asn1d_parse_place place = state->place;
727
        /* Is it one of the types that permits an unexpected EOC? */
728
4.30M
        int eoc_permitted =
729
4.30M
            (place == duringGroup ||
730
4.30M
             place == duringConstructedString ||
731
4.30M
             state->child->optional);
732
4.30M
        return (state->indefinite && eoc_permitted) ? PR_TRUE : PR_FALSE;
733
4.30M
    }
734
153
    return PR_FALSE;
735
4.30M
}
736
737
static unsigned long
738
sec_asn1d_parse_identifier(sec_asn1d_state *state,
739
                           const char *buf, unsigned long len)
740
7.62M
{
741
7.62M
    unsigned char byte;
742
7.62M
    unsigned char tag_number;
743
744
7.62M
    PORT_Assert(state->place == beforeIdentifier);
745
746
7.62M
    if (len == 0) {
747
4.71k
        state->top->status = needBytes;
748
4.71k
        return 0;
749
4.71k
    }
750
751
7.62M
    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
7.62M
    tag_number = byte & SEC_ASN1_TAGNUM_MASK;
761
762
7.62M
    if (IS_HIGH_TAG_NUMBER(tag_number)) {
763
14.0k
        state->place = duringIdentifier;
764
14.0k
        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
14.0k
        state->pending = 1;
771
7.60M
    } else {
772
7.60M
        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
660k
            state->place = duringEndOfContents;
783
660k
            state->pending = 2;
784
660k
            state->found_tag_number = 0;
785
660k
            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
660k
            if (state->optional)
791
102
                state->missing = PR_TRUE;
792
660k
            return 0;
793
660k
        }
794
6.94M
        state->place = afterIdentifier;
795
6.94M
        state->found_tag_number = tag_number;
796
6.94M
    }
797
6.96M
    state->found_tag_modifiers = byte & ~SEC_ASN1_TAGNUM_MASK;
798
799
6.96M
    return 1;
800
7.62M
}
801
802
static unsigned long
803
sec_asn1d_parse_more_identifier(sec_asn1d_state *state,
804
                                const char *buf, unsigned long len)
805
18.3k
{
806
18.3k
    unsigned char byte;
807
18.3k
    int count;
808
809
18.3k
    PORT_Assert(state->pending == 1);
810
18.3k
    PORT_Assert(state->place == duringIdentifier);
811
812
18.3k
    if (len == 0) {
813
4.51k
        state->top->status = needBytes;
814
4.51k
        return 0;
815
4.51k
    }
816
817
13.8k
    count = 0;
818
819
218M
    while (len && state->pending) {
820
218M
        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
757
            PORT_SetError(SEC_ERROR_BAD_DER);
826
757
            state->top->status = decodeError;
827
757
            return 0;
828
757
        }
829
830
218M
        state->found_tag_number <<= TAG_NUMBER_BITS;
831
832
218M
        byte = (unsigned char)buf[count++];
833
218M
        state->found_tag_number |= (byte & TAG_NUMBER_MASK);
834
835
218M
        len--;
836
218M
        if (LAST_TAG_NUMBER_BYTE(byte))
837
8.75k
            state->pending = 0;
838
218M
    }
839
840
13.0k
    if (state->pending == 0)
841
8.75k
        state->place = afterIdentifier;
842
843
13.0k
    return count;
844
13.8k
}
845
846
static void
847
sec_asn1d_confirm_identifier(sec_asn1d_state *state)
848
6.96M
{
849
6.96M
    PRBool match;
850
851
6.96M
    PORT_Assert(state->place == afterIdentifier);
852
853
6.96M
    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
6.96M
    if (match) {
855
6.84M
        state->place = beforeLength;
856
6.84M
    } else {
857
122k
        if (state->optional) {
858
13.6k
            state->missing = PR_TRUE;
859
13.6k
            state->place = afterEndOfContents;
860
108k
        } else {
861
108k
            PORT_SetError(SEC_ERROR_BAD_DER);
862
108k
            state->top->status = decodeError;
863
108k
        }
864
122k
    }
865
6.96M
}
866
867
static unsigned long
868
sec_asn1d_parse_length(sec_asn1d_state *state,
869
                       const char *buf, unsigned long len)
870
6.84M
{
871
6.84M
    unsigned char byte;
872
873
6.84M
    PORT_Assert(state->place == beforeLength);
874
875
6.84M
    if (len == 0) {
876
1.21k
        state->top->status = needBytes;
877
1.21k
        return 0;
878
1.21k
    }
879
880
    /*
881
     * The default/likely outcome.  It may get adjusted below.
882
     */
883
6.84M
    state->place = afterLength;
884
885
6.84M
    byte = (unsigned char)*buf;
886
887
6.84M
    if (LENGTH_IS_SHORT_FORM(byte)) {
888
6.10M
        state->contents_length = byte;
889
6.10M
    } else {
890
741k
        state->contents_length = 0;
891
741k
        state->pending = LONG_FORM_LENGTH(byte);
892
741k
        if (state->pending == 0) {
893
729k
            state->indefinite = PR_TRUE;
894
729k
        } else {
895
12.1k
            state->place = duringLength;
896
12.1k
        }
897
741k
    }
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
6.84M
    if (!state->indefinite &&
906
6.84M
        (state->underlying_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP))) {
907
6.08M
        state->found_tag_modifiers &= ~SEC_ASN1_CONSTRUCTED;
908
6.08M
    }
909
910
6.84M
    return 1;
911
6.84M
}
912
913
static unsigned long
914
sec_asn1d_parse_more_length(sec_asn1d_state *state,
915
                            const char *buf, unsigned long len)
916
12.2k
{
917
12.2k
    int count;
918
919
12.2k
    PORT_Assert(state->pending > 0);
920
12.2k
    PORT_Assert(state->place == duringLength);
921
922
12.2k
    if (len == 0) {
923
258
        state->top->status = needBytes;
924
258
        return 0;
925
258
    }
926
927
12.0k
    count = 0;
928
929
70.4k
    while (len && state->pending) {
930
58.5k
        if (HIGH_BITS(state->contents_length, 9) != 0) {
931
            /*
932
             * The given full content length overflows our container;
933
             * just give up.
934
             */
935
156
            PORT_SetError(SEC_ERROR_BAD_DER);
936
156
            state->top->status = decodeError;
937
156
            return 0;
938
156
        }
939
940
58.3k
        state->contents_length <<= 8;
941
58.3k
        state->contents_length |= (unsigned char)buf[count++];
942
943
58.3k
        len--;
944
58.3k
        state->pending--;
945
58.3k
    }
946
947
11.8k
    if (state->pending == 0)
948
11.7k
        state->place = afterLength;
949
950
11.8k
    return count;
951
12.0k
}
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
16.1M
{
965
16.1M
    PORT_Assert(remaining);
966
16.1M
    PORT_Assert(cx);
967
16.1M
    if (!remaining || !cx) {
968
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
969
0
        cx->status = decodeError;
970
0
        return PR_FALSE;
971
0
    }
972
16.1M
    if (*remaining < consumed) {
973
355
        PORT_SetError(SEC_ERROR_BAD_DER);
974
355
        cx->status = decodeError;
975
355
        return PR_FALSE;
976
355
    }
977
16.1M
    *remaining -= consumed;
978
16.1M
    return PR_TRUE;
979
16.1M
}
980
981
static void
982
sec_asn1d_prepare_for_contents(sec_asn1d_state *state)
983
6.84M
{
984
6.84M
    SECItem *item;
985
6.84M
    PLArenaPool *poolp;
986
6.84M
    unsigned long alloc_len;
987
6.84M
    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
6.84M
    parent = sec_asn1d_get_enclosing_construct(state);
1024
26.1M
    while (parent && parent->indefinite) {
1025
19.3M
        parent = sec_asn1d_get_enclosing_construct(parent);
1026
19.3M
    }
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
6.84M
    if (parent) {
1032
4.08M
        unsigned long remaining = parent->pending;
1033
4.08M
        parent = state;
1034
6.73M
        do {
1035
6.73M
            if (!sec_asn1d_check_and_subtract_length(
1036
6.73M
                    &remaining, parent->consumed, state->top) ||
1037
                /* If parent->indefinite is true, parent->contents_length is
1038
                 * zero and this is a no-op. */
1039
6.73M
                !sec_asn1d_check_and_subtract_length(
1040
6.73M
                    &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
6.73M
                (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
355
                return;
1047
355
            }
1048
6.73M
        } while ((parent = sec_asn1d_get_enclosing_construct(parent)) &&
1049
6.73M
                 parent->indefinite);
1050
4.08M
    }
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
6.84M
    if (state->allocate) {
1057
4.42M
        void *dest;
1058
1059
4.42M
        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
4.42M
        dest = sec_asn1d_zalloc(state->top->their_pool,
1065
4.42M
                                state->theTemplate->size);
1066
4.42M
        if (dest == NULL) {
1067
0
            state->top->status = decodeError;
1068
0
            return;
1069
0
        }
1070
4.42M
        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
4.42M
        if (state->parent->place == afterPointer) {
1080
2.64k
            void **placep;
1081
1082
2.64k
            placep = state->parent->dest;
1083
2.64k
            *placep = dest;
1084
2.64k
        }
1085
4.42M
    }
1086
1087
    /*
1088
     * Remember, length may be indefinite here!  In that case,
1089
     * both contents_length and pending will be zero.
1090
     */
1091
6.84M
    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
6.84M
    if (state->explicit) {
1099
315
        state->place = afterExplicit;
1100
315
        state = sec_asn1d_push_state(state->top,
1101
315
                                     SEC_ASN1GetSubtemplate(state->theTemplate,
1102
315
                                                            state->dest,
1103
315
                                                            PR_FALSE),
1104
315
                                     state->dest, PR_TRUE);
1105
315
        if (state != NULL) {
1106
315
            (void)sec_asn1d_init_state_based_on_template(state);
1107
315
        }
1108
315
        return;
1109
315
    }
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
6.84M
    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
14.2k
        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
14.2k
        if (state->contents_length != 0 || state->indefinite) {
1125
11.9k
            const SEC_ASN1Template *subt;
1126
1127
11.9k
            state->place = duringGroup;
1128
11.9k
            subt = SEC_ASN1GetSubtemplate(state->theTemplate, state->dest,
1129
11.9k
                                          PR_FALSE);
1130
11.9k
            state = sec_asn1d_push_state(state->top, subt, NULL, PR_TRUE);
1131
11.9k
            if (state != NULL) {
1132
11.9k
                if (!state->top->filter_only)
1133
11.9k
                    state->allocate = PR_TRUE; /* XXX propogate this? */
1134
                /*
1135
                 * Do the "before" field notification for next in group.
1136
                 */
1137
11.9k
                sec_asn1d_notify_before(state->top, state->dest, state->depth);
1138
11.9k
                (void)sec_asn1d_init_state_based_on_template(state);
1139
11.9k
            }
1140
11.9k
        } else {
1141
            /*
1142
             * A group of zero; we are done.
1143
             * Set state to afterGroup and let that code plant the NULL.
1144
             */
1145
2.35k
            state->place = afterGroup;
1146
2.35k
        }
1147
14.2k
        return;
1148
14.2k
    }
1149
1150
6.82M
    switch (state->underlying_kind) {
1151
24.2k
        case SEC_ASN1_SEQUENCE:
1152
            /*
1153
             * We need to push a child to handle the individual fields.
1154
             */
1155
24.2k
            state->place = duringSequence;
1156
24.2k
            state = sec_asn1d_push_state(state->top, state->theTemplate + 1,
1157
24.2k
                                         state->dest, PR_TRUE);
1158
24.2k
            if (state != NULL) {
1159
                /*
1160
                 * Do the "before" field notification.
1161
                 */
1162
24.2k
                sec_asn1d_notify_before(state->top, state->dest, state->depth);
1163
24.2k
                (void)sec_asn1d_init_state_based_on_template(state);
1164
24.2k
            }
1165
24.2k
            break;
1166
1167
0
        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
0
            PORT_Assert(0);
1176
0
            PORT_SetError(SEC_ERROR_BAD_DER); /* XXX */
1177
0
            state->top->status = decodeError;
1178
0
            break;
1179
1180
82
        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
82
            if (state->contents_length || state->indefinite) {
1186
79
                PORT_SetError(SEC_ERROR_BAD_DER);
1187
79
                state->top->status = decodeError;
1188
79
                break;
1189
79
            }
1190
3
            if (state->dest != NULL) {
1191
3
                item = (SECItem *)(state->dest);
1192
3
                item->data = NULL;
1193
3
                item->len = 0;
1194
3
            }
1195
3
            state->place = afterEndOfContents;
1196
3
            break;
1197
1198
460
        case SEC_ASN1_BMP_STRING:
1199
            /* Error if length is not divisable by 2 */
1200
460
            if (state->contents_length % 2) {
1201
3
                PORT_SetError(SEC_ERROR_BAD_DER);
1202
3
                state->top->status = decodeError;
1203
3
                break;
1204
3
            }
1205
            /* otherwise, handle as other string types */
1206
457
            goto regular_string_type;
1207
1208
487
        case SEC_ASN1_UNIVERSAL_STRING:
1209
            /* Error if length is not divisable by 4 */
1210
487
            if (state->contents_length % 4) {
1211
2
                PORT_SetError(SEC_ERROR_BAD_DER);
1212
2
                state->top->status = decodeError;
1213
2
                break;
1214
2
            }
1215
            /* otherwise, handle as other string types */
1216
485
            goto regular_string_type;
1217
1218
475k
        case SEC_ASN1_SKIP:
1219
6.78M
        case SEC_ASN1_ANY:
1220
6.78M
        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
6.78M
        regular_string_type:
1228
6.78M
        case SEC_ASN1_BIT_STRING:
1229
6.78M
        case SEC_ASN1_IA5_STRING:
1230
6.78M
        case SEC_ASN1_OCTET_STRING:
1231
6.79M
        case SEC_ASN1_PRINTABLE_STRING:
1232
6.79M
        case SEC_ASN1_T61_STRING:
1233
6.79M
        case SEC_ASN1_UTC_TIME:
1234
6.79M
        case SEC_ASN1_UTF8_STRING:
1235
6.79M
        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
6.79M
            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
6.79M
            alloc_len = state->contents_length;
1255
6.79M
            poolp = NULL; /* quiet compiler warnings about unused... */
1256
1257
6.79M
            if (item == NULL || state->top->filter_only) {
1258
475k
                if (item != NULL) {
1259
0
                    item->data = NULL;
1260
0
                    item->len = 0;
1261
0
                }
1262
475k
                alloc_len = 0;
1263
6.32M
            } 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
1.89M
                if (item->data == NULL) {
1274
1.89M
                    PORT_Assert(item->len == 0);
1275
1.89M
                    poolp = state->top->our_pool;
1276
1.89M
                } else {
1277
2.09k
                    alloc_len = 0;
1278
2.09k
                }
1279
4.42M
            } else {
1280
4.42M
                item->len = 0;
1281
4.42M
                item->data = NULL;
1282
4.42M
                poolp = state->top->their_pool;
1283
4.42M
            }
1284
1285
6.79M
            if (alloc_len || ((!state->indefinite) && (state->subitems_head != NULL))) {
1286
5.68M
                struct subitem *subitem;
1287
5.68M
                int len;
1288
1289
5.68M
                PORT_Assert(item);
1290
5.68M
                if (!item) {
1291
0
                    PORT_SetError(SEC_ERROR_BAD_DER);
1292
0
                    state->top->status = decodeError;
1293
0
                    return;
1294
0
                }
1295
5.68M
                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
5.68M
                if (state->subitems_head != NULL) {
1302
5.68M
                    PORT_Assert(state->underlying_kind == SEC_ASN1_ANY);
1303
5.68M
                    for (subitem = state->subitems_head;
1304
17.0M
                         subitem != NULL; subitem = subitem->next)
1305
11.3M
                        alloc_len += subitem->len;
1306
5.68M
                }
1307
1308
5.68M
                if (state->top->max_element_size > 0 &&
1309
5.68M
                    alloc_len > state->top->max_element_size) {
1310
3.78k
                    PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1311
3.78k
                    state->top->status = decodeError;
1312
3.78k
                    return;
1313
3.78k
                }
1314
1315
5.68M
                item->data = (unsigned char *)sec_asn1d_zalloc(poolp, alloc_len);
1316
5.68M
                if (item->data == NULL) {
1317
0
                    state->top->status = decodeError;
1318
0
                    break;
1319
0
                }
1320
1321
5.68M
                len = 0;
1322
5.68M
                for (subitem = state->subitems_head;
1323
17.0M
                     subitem != NULL; subitem = subitem->next) {
1324
11.3M
                    PORT_Memcpy(item->data + len, subitem->data, subitem->len);
1325
11.3M
                    len += subitem->len;
1326
11.3M
                }
1327
5.68M
                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
5.68M
                state->subitems_head = state->subitems_tail = NULL;
1335
5.68M
            }
1336
1337
6.79M
            if (state->contents_length == 0 && (!state->indefinite)) {
1338
                /*
1339
                 * A zero-length simple or constructed string; we are done.
1340
                 */
1341
5.61M
                state->place = afterEndOfContents;
1342
5.61M
            } else if (state->found_tag_modifiers & SEC_ASN1_CONSTRUCTED) {
1343
708k
                const SEC_ASN1Template *sub;
1344
1345
708k
                switch (state->underlying_kind) {
1346
622k
                    case SEC_ASN1_ANY:
1347
622k
                    case SEC_ASN1_ANY_CONTENTS:
1348
622k
                        sub = SEC_AnyTemplate;
1349
622k
                        break;
1350
1.04k
                    case SEC_ASN1_BIT_STRING:
1351
1.04k
                        sub = SEC_BitStringTemplate;
1352
1.04k
                        break;
1353
418
                    case SEC_ASN1_BMP_STRING:
1354
418
                        sub = SEC_BMPStringTemplate;
1355
418
                        break;
1356
0
                    case SEC_ASN1_GENERALIZED_TIME:
1357
0
                        sub = SEC_GeneralizedTimeTemplate;
1358
0
                        break;
1359
384
                    case SEC_ASN1_IA5_STRING:
1360
384
                        sub = SEC_IA5StringTemplate;
1361
384
                        break;
1362
980
                    case SEC_ASN1_OCTET_STRING:
1363
980
                        sub = SEC_OctetStringTemplate;
1364
980
                        break;
1365
529
                    case SEC_ASN1_PRINTABLE_STRING:
1366
529
                        sub = SEC_PrintableStringTemplate;
1367
529
                        break;
1368
545
                    case SEC_ASN1_T61_STRING:
1369
545
                        sub = SEC_T61StringTemplate;
1370
545
                        break;
1371
323
                    case SEC_ASN1_UNIVERSAL_STRING:
1372
323
                        sub = SEC_UniversalStringTemplate;
1373
323
                        break;
1374
2.86k
                    case SEC_ASN1_UTC_TIME:
1375
2.86k
                        sub = SEC_UTCTimeTemplate;
1376
2.86k
                        break;
1377
576
                    case SEC_ASN1_UTF8_STRING:
1378
576
                        sub = SEC_UTF8StringTemplate;
1379
576
                        break;
1380
376
                    case SEC_ASN1_VISIBLE_STRING:
1381
376
                        sub = SEC_VisibleStringTemplate;
1382
376
                        break;
1383
78.2k
                    case SEC_ASN1_SKIP:
1384
78.2k
                        sub = SEC_SkipTemplate;
1385
78.2k
                        break;
1386
0
                    default:            /* redundant given outer switch cases, but */
1387
0
                        PORT_Assert(0); /* the compiler does not seem to know that, */
1388
0
                        sub = NULL;     /* so just do enough to quiet it. */
1389
0
                        break;
1390
708k
                }
1391
1392
708k
                state->place = duringConstructedString;
1393
708k
                state = sec_asn1d_push_state(state->top, sub, item, PR_TRUE);
1394
708k
                if (state != NULL) {
1395
708k
                    state->substring = PR_TRUE; /* XXX propogate? */
1396
708k
                    (void)sec_asn1d_init_state_based_on_template(state);
1397
708k
                }
1398
708k
            } else if (state->indefinite) {
1399
                /*
1400
                 * An indefinite-length string *must* be constructed!
1401
                 */
1402
813
                PORT_SetError(SEC_ERROR_BAD_DER);
1403
813
                state->top->status = decodeError;
1404
473k
            } else {
1405
                /*
1406
                 * A non-zero-length simple string.
1407
                 */
1408
473k
                if (state->underlying_kind == SEC_ASN1_BIT_STRING)
1409
1.77k
                    state->place = beforeBitString;
1410
472k
                else
1411
472k
                    state->place = duringLeaf;
1412
473k
            }
1413
6.79M
            break;
1414
1415
6.79M
        default:
1416
            /*
1417
             * We are allocating for a simple leaf item.
1418
             */
1419
5.84k
            if (state->contents_length) {
1420
5.72k
                if (state->dest != NULL) {
1421
5.72k
                    item = (SECItem *)(state->dest);
1422
5.72k
                    item->len = 0;
1423
5.72k
                    if (state->top->max_element_size > 0 &&
1424
5.72k
                        state->contents_length > state->top->max_element_size) {
1425
395
                        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1426
395
                        state->top->status = decodeError;
1427
395
                        return;
1428
395
                    }
1429
1430
5.32k
                    if (state->top->filter_only) {
1431
0
                        item->data = NULL;
1432
5.32k
                    } else {
1433
5.32k
                        item->data = (unsigned char *)
1434
5.32k
                            sec_asn1d_zalloc(state->top->their_pool,
1435
5.32k
                                             state->contents_length);
1436
5.32k
                        if (item->data == NULL) {
1437
0
                            state->top->status = decodeError;
1438
0
                            return;
1439
0
                        }
1440
5.32k
                    }
1441
5.32k
                }
1442
5.32k
                state->place = duringLeaf;
1443
5.32k
            } else {
1444
                /*
1445
                 * An indefinite-length or zero-length item is not allowed.
1446
                 * (All legal cases of such were handled above.)
1447
                 */
1448
121
                PORT_SetError(SEC_ERROR_BAD_DER);
1449
121
                state->top->status = decodeError;
1450
121
            }
1451
6.82M
    }
1452
6.82M
}
1453
1454
static void
1455
sec_asn1d_free_child(sec_asn1d_state *state, PRBool error)
1456
7.61M
{
1457
7.61M
    if (state->child != NULL) {
1458
721k
        PORT_Assert(error || state->child->consumed == 0);
1459
721k
        PORT_Assert(state->our_mark != NULL);
1460
721k
        PORT_ArenaZRelease(state->top->our_pool, state->our_mark);
1461
721k
        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
0
        }
1471
721k
        state->child = NULL;
1472
721k
        state->our_mark = NULL;
1473
6.88M
    } 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
6.88M
        PORT_Assert(state->our_mark == NULL);
1482
6.88M
    }
1483
7.61M
    state->place = beforeEndOfContents;
1484
7.61M
}
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
1.17k
{
1500
1.17k
    sec_asn1d_state *child;
1501
1.17k
    unsigned long consumed;
1502
1.17k
    SECItem *item;
1503
1.17k
    void *dest;
1504
1505
1.17k
    child = state->child;
1506
1.17k
    PORT_Assert(child != NULL);
1507
1508
1.17k
    consumed = child->consumed;
1509
1.17k
    child->consumed = 0;
1510
1511
1.17k
    item = (SECItem *)(state->dest);
1512
1.17k
    PORT_Assert(item != NULL);
1513
1514
1.17k
    PORT_Assert(item->len == consumed);
1515
1516
    /*
1517
     * Free any grandchild.
1518
     */
1519
1.17k
    sec_asn1d_free_child(child, PR_FALSE);
1520
1521
    /*
1522
     * Notify after the SAVE field.
1523
     */
1524
1.17k
    sec_asn1d_notify_after(state->top, state->dest, state->depth);
1525
1526
    /*
1527
     * Adjust to get new dest and move forward.
1528
     */
1529
1.17k
    dest = (char *)state->dest - state->theTemplate->offset;
1530
1.17k
    state->theTemplate++;
1531
1.17k
    child->dest = (char *)dest + state->theTemplate->offset;
1532
1.17k
    child->theTemplate = state->theTemplate;
1533
1534
    /*
1535
     * Notify before the "real" field.
1536
     */
1537
1.17k
    PORT_Assert(state->depth == child->depth);
1538
1.17k
    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
1.17k
    state->place = afterSaveEncoding;
1544
1545
    /*
1546
     * We already have a child; "push" it by making it current.
1547
     */
1548
1.17k
    state->top->current = child;
1549
1550
    /*
1551
     * And initialize it so it is ready to parse.
1552
     */
1553
1.17k
    (void)sec_asn1d_init_state_based_on_template(child);
1554
1555
    /*
1556
     * Now parse that out of our data.
1557
     */
1558
1.17k
    if (SEC_ASN1DecoderUpdate(state->top,
1559
1.17k
                              (char *)item->data, item->len) != SECSuccess)
1560
1.06k
        return;
1561
108
    if (state->top->status == needBytes) {
1562
12
        return;
1563
12
    }
1564
1565
96
    PORT_Assert(state->top->current == state);
1566
96
    PORT_Assert(state->child == child);
1567
1568
    /*
1569
     * That should have consumed what we consumed before.
1570
     */
1571
96
    PORT_Assert(consumed == child->consumed);
1572
96
    child->consumed = 0;
1573
1574
    /*
1575
     * Done.
1576
     */
1577
96
    state->consumed += consumed;
1578
96
    child->place = notInUse;
1579
96
    state->place = afterEndOfContents;
1580
96
}
1581
1582
static unsigned long
1583
sec_asn1d_parse_leaf(sec_asn1d_state *state,
1584
                     const char *buf, unsigned long len)
1585
479k
{
1586
479k
    SECItem *item;
1587
479k
    unsigned long bufLen;
1588
1589
479k
    if (len == 0) {
1590
2.12k
        state->top->status = needBytes;
1591
2.12k
        return 0;
1592
2.12k
    }
1593
1594
477k
    if (state->pending < len)
1595
474k
        len = state->pending;
1596
1597
477k
    bufLen = len;
1598
1599
477k
    item = (SECItem *)(state->dest);
1600
477k
    if (item != NULL && item->data != NULL) {
1601
426k
        unsigned long offset;
1602
        /* Strip leading zeroes when target is unsigned integer */
1603
426k
        if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER   */
1604
426k
            item->len == 0 &&                             /* MSB       */
1605
426k
            item->type == siUnsignedInteger)              /* unsigned  */
1606
0
        {
1607
0
            while (len > 1 && buf[0] == 0) { /* leading 0 */
1608
0
                buf++;
1609
0
                len--;
1610
0
            }
1611
0
        }
1612
426k
        offset = item->len;
1613
426k
        if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
1614
            // The previous bit string must have no unused bits.
1615
531
            if (item->len & 0x7) {
1616
3
                PORT_SetError(SEC_ERROR_BAD_DER);
1617
3
                state->top->status = decodeError;
1618
3
                return 0;
1619
3
            }
1620
            // If this is a bit string, the length is bits, not bytes.
1621
528
            offset = item->len >> 3;
1622
528
        }
1623
426k
        if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
1624
528
            unsigned long len_in_bits;
1625
            // Protect against overflow during the bytes-to-bits conversion.
1626
528
            if (len >= (ULONG_MAX >> 3) + 1) {
1627
0
                PORT_SetError(SEC_ERROR_BAD_DER);
1628
0
                state->top->status = decodeError;
1629
0
                return 0;
1630
0
            }
1631
528
            len_in_bits = (len << 3) - state->bit_string_unused_bits;
1632
            // Protect against overflow when computing the total length in bits.
1633
528
            if (UINT_MAX - item->len < len_in_bits) {
1634
0
                PORT_SetError(SEC_ERROR_BAD_DER);
1635
0
                state->top->status = decodeError;
1636
0
                return 0;
1637
0
            }
1638
528
            item->len += len_in_bits;
1639
426k
        } else {
1640
426k
            if (UINT_MAX - item->len < len) {
1641
0
                PORT_SetError(SEC_ERROR_BAD_DER);
1642
0
                state->top->status = decodeError;
1643
0
                return 0;
1644
0
            }
1645
426k
            item->len += len;
1646
426k
        }
1647
426k
        PORT_Memcpy(item->data + offset, buf, len);
1648
426k
    }
1649
477k
    state->pending -= bufLen;
1650
477k
    if (state->pending == 0)
1651
475k
        state->place = beforeEndOfContents;
1652
1653
477k
    return bufLen;
1654
477k
}
1655
1656
static unsigned long
1657
sec_asn1d_parse_bit_string(sec_asn1d_state *state,
1658
                           const char *buf, unsigned long len)
1659
1.77k
{
1660
1.77k
    unsigned char byte;
1661
1662
    /*PORT_Assert (state->pending > 0); */
1663
1.77k
    PORT_Assert(state->place == beforeBitString);
1664
1665
1.77k
    if (state->pending == 0) {
1666
0
        if (state->dest != NULL) {
1667
0
            SECItem *item = (SECItem *)(state->dest);
1668
0
            item->data = NULL;
1669
0
            item->len = 0;
1670
0
            state->place = beforeEndOfContents;
1671
0
            return 0;
1672
0
        }
1673
0
    }
1674
1675
1.77k
    if (len == 0) {
1676
13
        state->top->status = needBytes;
1677
13
        return 0;
1678
13
    }
1679
1680
1.76k
    byte = (unsigned char)*buf;
1681
1.76k
    if (byte > 7) {
1682
16
        PORT_SetError(SEC_ERROR_BAD_DER);
1683
16
        state->top->status = decodeError;
1684
16
        return 0;
1685
16
    }
1686
1687
1.74k
    state->bit_string_unused_bits = byte;
1688
1.74k
    state->place = duringBitString;
1689
1.74k
    state->pending -= 1;
1690
1691
1.74k
    return 1;
1692
1.76k
}
1693
1694
static unsigned long
1695
sec_asn1d_parse_more_bit_string(sec_asn1d_state *state,
1696
                                const char *buf, unsigned long len)
1697
1.80k
{
1698
1.80k
    PORT_Assert(state->place == duringBitString);
1699
1.80k
    if (state->pending == 0) {
1700
        /* An empty bit string with some unused bits is invalid. */
1701
1.21k
        if (state->bit_string_unused_bits) {
1702
9
            PORT_SetError(SEC_ERROR_BAD_DER);
1703
9
            state->top->status = decodeError;
1704
1.20k
        } else {
1705
            /* An empty bit string with no unused bits is OK. */
1706
1.20k
            state->place = beforeEndOfContents;
1707
1.20k
        }
1708
1.21k
        return 0;
1709
1.21k
    }
1710
1711
593
    len = sec_asn1d_parse_leaf(state, buf, len);
1712
593
    return len;
1713
1.80k
}
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
18.8M
{
1724
18.8M
    struct subitem *thing;
1725
1726
18.8M
    thing = (struct subitem *)sec_asn1d_zalloc(state->top->our_pool,
1727
18.8M
                                               sizeof(struct subitem));
1728
18.8M
    if (thing == NULL) {
1729
0
        state->top->status = decodeError;
1730
0
        return NULL;
1731
0
    }
1732
1733
18.8M
    if (copy_data) {
1734
12.6M
        void *copy;
1735
12.6M
        copy = sec_asn1d_alloc(state->top->our_pool, len);
1736
12.6M
        if (copy == NULL) {
1737
0
            state->top->status = decodeError;
1738
0
            if (!state->top->our_pool)
1739
0
                PORT_Free(thing);
1740
0
            return NULL;
1741
0
        }
1742
12.6M
        PORT_Memcpy(copy, data, len);
1743
12.6M
        thing->data = copy;
1744
12.6M
    } else {
1745
6.27M
        thing->data = data;
1746
6.27M
    }
1747
18.8M
    thing->len = len;
1748
18.8M
    thing->next = NULL;
1749
1750
18.8M
    if (state->subitems_head == NULL) {
1751
6.31M
        PORT_Assert(state->subitems_tail == NULL);
1752
6.31M
        state->subitems_head = state->subitems_tail = thing;
1753
12.5M
    } else {
1754
12.5M
        state->subitems_tail->next = thing;
1755
12.5M
        state->subitems_tail = thing;
1756
12.5M
    }
1757
1758
18.8M
    return thing;
1759
18.8M
}
1760
1761
static void
1762
sec_asn1d_record_any_header(sec_asn1d_state *state,
1763
                            const char *buf,
1764
                            unsigned long len)
1765
12.6M
{
1766
12.6M
    SECItem *item;
1767
1768
12.6M
    item = (SECItem *)(state->dest);
1769
12.6M
    if (item != NULL && item->data != NULL) {
1770
0
        PORT_Assert(state->substring);
1771
0
        PORT_Memcpy(item->data + item->len, buf, len);
1772
0
        item->len += len;
1773
12.6M
    } else {
1774
12.6M
        sec_asn1d_add_to_subitems(state, buf, len, PR_TRUE);
1775
12.6M
    }
1776
12.6M
}
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
2.97M
{
1792
2.97M
    sec_asn1d_state *child;
1793
2.97M
    SECItem *item;
1794
2.97M
    unsigned long child_consumed;
1795
2.97M
    PRBool done;
1796
1797
2.97M
    PORT_Assert(state->place == duringConstructedString);
1798
2.97M
    PORT_Assert(state->child != NULL);
1799
1800
2.97M
    child = state->child;
1801
1802
2.97M
    child_consumed = child->consumed;
1803
2.97M
    child->consumed = 0;
1804
2.97M
    state->consumed += child_consumed;
1805
1806
2.97M
    done = PR_FALSE;
1807
1808
2.97M
    if (state->pending) {
1809
1.59k
        PORT_Assert(!state->indefinite);
1810
1.59k
        if (child_consumed > state->pending) {
1811
0
            PORT_SetError(SEC_ERROR_BAD_DER);
1812
0
            state->top->status = decodeError;
1813
0
            return;
1814
0
        }
1815
1816
1.59k
        state->pending -= child_consumed;
1817
1.59k
        if (state->pending == 0)
1818
1.00k
            done = PR_TRUE;
1819
2.97M
    } else {
1820
2.97M
        PRBool preallocatedString;
1821
2.97M
        sec_asn1d_state *temp_state;
1822
2.97M
        PORT_Assert(state->indefinite);
1823
1824
2.97M
        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
2.97M
        preallocatedString = PR_FALSE;
1895
2.97M
        temp_state = state;
1896
25.8M
        while (temp_state && item == temp_state->dest && temp_state->indefinite) {
1897
25.8M
            sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(temp_state);
1898
25.8M
            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
1.21M
                break;
1903
1.21M
            }
1904
24.6M
            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
649
                preallocatedString = PR_TRUE;
1908
649
                break;
1909
649
            }
1910
24.6M
            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
1.75M
                break;
1917
1.75M
            }
1918
22.8M
            temp_state = parent;
1919
22.8M
        }
1920
2.97M
        if (item != NULL && item->data != NULL && !preallocatedString) {
1921
            /*
1922
             * Save the string away for later concatenation.
1923
             */
1924
1.84M
            PORT_Assert(item->data != NULL);
1925
1.84M
            sec_asn1d_add_to_subitems(state, item->data, item->len, PR_FALSE);
1926
            /*
1927
             * Clear the child item for the next round.
1928
             */
1929
1.84M
            item->data = NULL;
1930
1.84M
            item->len = 0;
1931
1.84M
        }
1932
1933
        /*
1934
         * If our child was just our end-of-contents octets, we are done.
1935
         */
1936
2.97M
        if (child->endofcontents)
1937
655k
            done = PR_TRUE;
1938
2.97M
    }
1939
1940
    /*
1941
     * Stop or do the next one.
1942
     */
1943
2.97M
    if (done) {
1944
656k
        child->place = notInUse;
1945
656k
        state->place = afterConstructedString;
1946
2.31M
    } else {
1947
2.31M
        sec_asn1d_scrub_state(child);
1948
2.31M
        state->top->current = child;
1949
2.31M
    }
1950
2.97M
}
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
4.42M
{
1958
4.42M
    sec_asn1d_state *child;
1959
4.42M
    unsigned long child_consumed;
1960
1961
4.42M
    PORT_Assert(state->place == duringGroup);
1962
4.42M
    PORT_Assert(state->child != NULL);
1963
1964
4.42M
    child = state->child;
1965
1966
4.42M
    child_consumed = child->consumed;
1967
4.42M
    child->consumed = 0;
1968
4.42M
    state->consumed += child_consumed;
1969
1970
    /*
1971
     * If our child was just our end-of-contents octets, we are done.
1972
     */
1973
4.42M
    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
4.33k
        if (child->dest && !state->subitems_head) {
2001
0
            sec_asn1d_add_to_subitems(state, child->dest, 0, PR_FALSE);
2002
0
            child->dest = NULL;
2003
0
        }
2004
2005
4.33k
        child->place = notInUse;
2006
4.33k
        state->place = afterGroup;
2007
4.33k
        return;
2008
4.33k
    }
2009
2010
    /*
2011
     * Do the "after" field notification for next in group.
2012
     */
2013
4.42M
    sec_asn1d_notify_after(state->top, child->dest, child->depth);
2014
2015
    /*
2016
     * Save it away (unless we are not storing).
2017
     */
2018
4.42M
    if (child->dest != NULL) {
2019
4.42M
        void *dest;
2020
2021
4.42M
        dest = child->dest;
2022
4.42M
        dest = (char *)dest - child->theTemplate->offset;
2023
4.42M
        sec_asn1d_add_to_subitems(state, dest, 0, PR_FALSE);
2024
4.42M
        child->dest = NULL;
2025
4.42M
    }
2026
2027
    /*
2028
     * Account for those bytes; see if we are done.
2029
     */
2030
4.42M
    if (state->pending) {
2031
3.78M
        PORT_Assert(!state->indefinite);
2032
3.78M
        if (child_consumed > state->pending) {
2033
0
            PORT_SetError(SEC_ERROR_BAD_DER);
2034
0
            state->top->status = decodeError;
2035
0
            return;
2036
0
        }
2037
2038
3.78M
        state->pending -= child_consumed;
2039
3.78M
        if (state->pending == 0) {
2040
555
            child->place = notInUse;
2041
555
            state->place = afterGroup;
2042
555
            return;
2043
555
        }
2044
3.78M
    }
2045
2046
    /*
2047
     * Do the "before" field notification for next item in group.
2048
     */
2049
4.42M
    sec_asn1d_notify_before(state->top, child->dest, child->depth);
2050
2051
    /*
2052
     * Now we do the next one.
2053
     */
2054
4.42M
    sec_asn1d_scrub_state(child);
2055
2056
    /* Initialize child state from the template */
2057
4.42M
    sec_asn1d_init_state_based_on_template(child);
2058
2059
4.42M
    state->top->current = child;
2060
4.42M
}
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
15.0k
{
2070
15.0k
    sec_asn1d_state *child;
2071
15.0k
    unsigned long child_consumed;
2072
15.0k
    PRBool child_missing;
2073
2074
15.0k
    PORT_Assert(state->place == duringSequence);
2075
15.0k
    PORT_Assert(state->child != NULL);
2076
2077
15.0k
    child = state->child;
2078
2079
    /*
2080
     * Do the "after" field notification.
2081
     */
2082
15.0k
    sec_asn1d_notify_after(state->top, child->dest, child->depth);
2083
2084
15.0k
    child_missing = (PRBool)child->missing;
2085
15.0k
    child_consumed = child->consumed;
2086
15.0k
    child->consumed = 0;
2087
2088
    /*
2089
     * Take care of accounting.
2090
     */
2091
15.0k
    if (child_missing) {
2092
6.81k
        PORT_Assert(child->optional);
2093
8.28k
    } else {
2094
8.28k
        state->consumed += child_consumed;
2095
        /*
2096
         * Free any grandchild.
2097
         */
2098
8.28k
        sec_asn1d_free_child(child, PR_FALSE);
2099
8.28k
        if (state->pending) {
2100
4.44k
            PORT_Assert(!state->indefinite);
2101
4.44k
            if (child_consumed > state->pending) {
2102
24
                PORT_SetError(SEC_ERROR_BAD_DER);
2103
24
                state->top->status = decodeError;
2104
24
                return;
2105
24
            }
2106
4.42k
            state->pending -= child_consumed;
2107
4.42k
            if (state->pending == 0) {
2108
1.69k
                child->theTemplate++;
2109
1.84k
                while (child->theTemplate->kind != 0) {
2110
182
                    if ((child->theTemplate->kind & SEC_ASN1_OPTIONAL) == 0) {
2111
33
                        PORT_SetError(SEC_ERROR_BAD_DER);
2112
33
                        state->top->status = decodeError;
2113
33
                        return;
2114
33
                    }
2115
149
                    child->theTemplate++;
2116
149
                }
2117
1.66k
                child->place = notInUse;
2118
1.66k
                state->place = afterEndOfContents;
2119
1.66k
                return;
2120
1.69k
            }
2121
4.42k
        }
2122
8.28k
    }
2123
2124
    /*
2125
     * Move forward.
2126
     */
2127
13.3k
    child->theTemplate++;
2128
13.3k
    if (child->theTemplate->kind == 0) {
2129
        /*
2130
         * We are done with this sequence.
2131
         */
2132
2.40k
        child->place = notInUse;
2133
2.40k
        if (state->pending) {
2134
488
            PORT_SetError(SEC_ERROR_BAD_DER);
2135
488
            state->top->status = decodeError;
2136
1.91k
        } 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
615
            if (state->indefinite && child->endofcontents) {
2149
52
                PORT_Assert(child_consumed == 2);
2150
52
                if (child_consumed != 2) {
2151
0
                    PORT_SetError(SEC_ERROR_BAD_DER);
2152
0
                    state->top->status = decodeError;
2153
52
                } else {
2154
52
                    state->consumed += child_consumed;
2155
52
                    state->place = afterEndOfContents;
2156
52
                }
2157
563
            } else {
2158
563
                PORT_SetError(SEC_ERROR_BAD_DER);
2159
563
                state->top->status = decodeError;
2160
563
            }
2161
1.30k
        } 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
1.30k
            state->place = beforeEndOfContents;
2167
1.30k
        }
2168
10.9k
    } else {
2169
10.9k
        unsigned char child_found_tag_modifiers = 0;
2170
10.9k
        unsigned long child_found_tag_number = 0;
2171
2172
        /*
2173
         * Reset state and push.
2174
         */
2175
10.9k
        if (state->dest != NULL)
2176
10.9k
            child->dest = (char *)state->dest + child->theTemplate->offset;
2177
2178
        /*
2179
         * Do the "before" field notification.
2180
         */
2181
10.9k
        sec_asn1d_notify_before(state->top, child->dest, child->depth);
2182
2183
10.9k
        if (child_missing) { /* if previous child was missing, copy the tag data we already have */
2184
5.72k
            child_found_tag_modifiers = child->found_tag_modifiers;
2185
5.72k
            child_found_tag_number = child->found_tag_number;
2186
5.72k
        }
2187
10.9k
        state->top->current = child;
2188
10.9k
        child = sec_asn1d_init_state_based_on_template(child);
2189
10.9k
        if (child_missing && child) {
2190
5.72k
            child->place = afterIdentifier;
2191
5.72k
            child->found_tag_modifiers = child_found_tag_modifiers;
2192
5.72k
            child->found_tag_number = child_found_tag_number;
2193
5.72k
            child->consumed = child_consumed;
2194
5.72k
            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
0
                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
0
                if (child_found_tag_modifiers >= SEC_ASN1_HIGH_TAG_NUMBER) {
2212
0
                    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
2213
0
                    state->top->status = decodeError;
2214
0
                } else {
2215
0
                    identifier = (unsigned char)(child_found_tag_modifiers | child_found_tag_number);
2216
0
                    sec_asn1d_record_any_header(child, (char *)&identifier, 1);
2217
0
                }
2218
0
            }
2219
5.72k
        }
2220
10.9k
    }
2221
13.3k
}
2222
2223
static void
2224
sec_asn1d_concat_substrings(sec_asn1d_state *state)
2225
656k
{
2226
656k
    PORT_Assert(state->place == afterConstructedString);
2227
2228
656k
    if (state->subitems_head != NULL) {
2229
583k
        struct subitem *substring;
2230
583k
        unsigned long alloc_len, item_len;
2231
583k
        unsigned char *where;
2232
583k
        SECItem *item;
2233
583k
        PRBool is_bit_string;
2234
2235
583k
        item_len = 0;
2236
583k
        is_bit_string = (state->underlying_kind == SEC_ASN1_BIT_STRING)
2237
583k
                            ? PR_TRUE
2238
583k
                            : PR_FALSE;
2239
2240
583k
        substring = state->subitems_head;
2241
3.13M
        while (substring != NULL) {
2242
            /*
2243
             * All bit-string substrings except the last one should be
2244
             * a clean multiple of 8 bits.
2245
             */
2246
2.55M
            if (is_bit_string && (substring->next != NULL) && (substring->len & 0x7)) {
2247
4
                PORT_SetError(SEC_ERROR_BAD_DER);
2248
4
                state->top->status = decodeError;
2249
4
                return;
2250
4
            }
2251
2.55M
            item_len += substring->len;
2252
2.55M
            substring = substring->next;
2253
2.55M
        }
2254
2255
583k
        if (is_bit_string) {
2256
331
            alloc_len = ((item_len + 7) >> 3);
2257
583k
        } 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
583k
            if (state->underlying_kind == SEC_ASN1_ANY && state->indefinite)
2264
582k
                item_len += 2;
2265
583k
            alloc_len = item_len;
2266
583k
        }
2267
2268
583k
        if (state->top->max_element_size > 0 &&
2269
583k
            alloc_len > state->top->max_element_size) {
2270
0
            PORT_SetError(SEC_ERROR_OUTPUT_LEN);
2271
0
            state->top->status = decodeError;
2272
0
            return;
2273
0
        }
2274
2275
583k
        item = (SECItem *)(state->dest);
2276
583k
        PORT_Assert(item != NULL);
2277
583k
        PORT_Assert(item->data == NULL);
2278
583k
        item->data = (unsigned char *)sec_asn1d_zalloc(state->top->their_pool,
2279
583k
                                                       alloc_len);
2280
583k
        if (item->data == NULL) {
2281
0
            state->top->status = decodeError;
2282
0
            return;
2283
0
        }
2284
583k
        item->len = item_len;
2285
2286
583k
        where = item->data;
2287
583k
        substring = state->subitems_head;
2288
3.13M
        while (substring != NULL) {
2289
2.55M
            if (is_bit_string)
2290
769
                item_len = (substring->len + 7) >> 3;
2291
2.55M
            else
2292
2.55M
                item_len = substring->len;
2293
2.55M
            PORT_Memcpy(where, substring->data, item_len);
2294
2.55M
            where += item_len;
2295
2.55M
            substring = substring->next;
2296
2.55M
        }
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
583k
        state->subitems_head = state->subitems_tail = NULL;
2304
583k
    }
2305
2306
656k
    state->place = afterEndOfContents;
2307
656k
}
2308
2309
static void
2310
sec_asn1d_concat_group(sec_asn1d_state *state)
2311
7.24k
{
2312
7.24k
    const void ***placep;
2313
2314
7.24k
    PORT_Assert(state->place == afterGroup);
2315
2316
7.24k
    placep = (const void ***)state->dest;
2317
7.24k
    PORT_Assert(state->subitems_head == NULL || placep != NULL);
2318
7.24k
    if (placep != NULL) {
2319
7.24k
        struct subitem *item;
2320
7.24k
        const void **group;
2321
7.24k
        int count;
2322
2323
7.24k
        count = 0;
2324
7.24k
        item = state->subitems_head;
2325
1.62M
        while (item != NULL) {
2326
1.61M
            PORT_Assert(item->next != NULL || item == state->subitems_tail);
2327
1.61M
            count++;
2328
1.61M
            item = item->next;
2329
1.61M
        }
2330
2331
7.24k
        group = (const void **)sec_asn1d_zalloc(state->top->their_pool,
2332
7.24k
                                                (count + 1) * (sizeof(void *)));
2333
7.24k
        if (group == NULL) {
2334
0
            state->top->status = decodeError;
2335
0
            return;
2336
0
        }
2337
2338
7.24k
        *placep = group;
2339
2340
7.24k
        item = state->subitems_head;
2341
1.62M
        while (item != NULL) {
2342
1.61M
            *group++ = item->data;
2343
1.61M
            item = item->next;
2344
1.61M
        }
2345
7.24k
        *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
7.24k
        state->subitems_head = state->subitems_tail = NULL;
2353
7.24k
    }
2354
2355
7.24k
    state->place = afterEndOfContents;
2356
7.24k
}
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
1.08k
{
2365
    /*
2366
     * There is absolutely supposed to be a child there.
2367
     */
2368
1.08k
    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
1.08k
    state->missing = state->child->missing;
2375
1.08k
    if (state->missing) {
2376
16
        state->found_tag_number = state->child->found_tag_number;
2377
16
        state->found_tag_modifiers = state->child->found_tag_modifiers;
2378
16
        state->endofcontents = state->child->endofcontents;
2379
16
    }
2380
2381
    /*
2382
     * Add in number of bytes consumed by child.
2383
     * (Only EXPLICIT should have already consumed bytes itself.)
2384
     */
2385
1.08k
    PORT_Assert(state->place == afterExplicit || state->consumed == 0);
2386
1.08k
    state->consumed += state->child->consumed;
2387
2388
    /*
2389
     * Subtract from bytes pending; this only applies to a definite-length
2390
     * EXPLICIT field.
2391
     */
2392
1.08k
    if (state->pending) {
2393
160
        PORT_Assert(!state->indefinite);
2394
160
        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
160
        if (state->pending != state->child->consumed) {
2401
153
            if (state->pending < state->child->consumed) {
2402
0
                PORT_SetError(SEC_ERROR_BAD_DER);
2403
0
                state->top->status = decodeError;
2404
0
                return;
2405
0
            }
2406
            /*
2407
             * Okay, this is a hack.  It *should* be an error whether
2408
             * pending is too big or too small, but it turns out that
2409
             * we had a bug in our *old* DER encoder that ended up
2410
             * counting an explicit header twice in the case where
2411
             * the underlying type was an ANY.  So, because we cannot
2412
             * prevent receiving these (our own certificate server can
2413
             * send them to us), we need to be lenient and accept them.
2414
             * To do so, we need to pretend as if we read all of the
2415
             * bytes that the header said we would find, even though
2416
             * we actually came up short.
2417
             */
2418
153
            state->consumed += (state->pending - state->child->consumed);
2419
153
        }
2420
160
        state->pending = 0;
2421
160
    }
2422
2423
    /*
2424
     * Indicate that we are done with child.
2425
     */
2426
1.08k
    state->child->consumed = 0;
2427
2428
    /*
2429
     * And move on to final state.
2430
     * (Technically everybody could move to afterEndOfContents except
2431
     * for an indefinite-length EXPLICIT; for simplicity though we assert
2432
     * that but let the end-of-contents code do the real determination.)
2433
     */
2434
1.08k
    PORT_Assert(state->place == afterExplicit || (!state->indefinite));
2435
1.08k
    state->place = beforeEndOfContents;
2436
1.08k
}
2437
2438
static void
2439
sec_asn1d_prepare_for_end_of_contents(sec_asn1d_state *state)
2440
479k
{
2441
479k
    PORT_Assert(state->place == beforeEndOfContents);
2442
2443
479k
    if (state->indefinite) {
2444
1.30k
        state->place = duringEndOfContents;
2445
1.30k
        state->pending = 2;
2446
478k
    } else {
2447
478k
        state->place = afterEndOfContents;
2448
478k
    }
2449
479k
}
2450
2451
static unsigned long
2452
sec_asn1d_parse_end_of_contents(sec_asn1d_state *state,
2453
                                const char *buf, unsigned long len)
2454
662k
{
2455
662k
    unsigned int i;
2456
2457
662k
    PORT_Assert(state->pending <= 2);
2458
662k
    PORT_Assert(state->place == duringEndOfContents);
2459
2460
662k
    if (len == 0) {
2461
258
        state->top->status = needBytes;
2462
258
        return 0;
2463
258
    }
2464
2465
662k
    if (state->pending < len)
2466
660k
        len = state->pending;
2467
2468
1.98M
    for (i = 0; i < len; i++) {
2469
1.32M
        if (buf[i] != 0) {
2470
            /*
2471
             * We expect to find only zeros; if not, just give up.
2472
             */
2473
523
            PORT_SetError(SEC_ERROR_BAD_DER);
2474
523
            state->top->status = decodeError;
2475
523
            return 0;
2476
523
        }
2477
1.32M
    }
2478
2479
661k
    state->pending -= len;
2480
2481
661k
    if (state->pending == 0) {
2482
661k
        state->place = afterEndOfContents;
2483
        /* These end-of-contents octets either terminate a SEQUENCE, a GROUP,
2484
         * or a constructed string. The SEQUENCE case is unique in that the
2485
         * state parses its own end-of-contents octets and therefore should not
2486
         * have its `endofcontents` flag set. We identify the SEQUENCE case by
2487
         * checking whether the child state's template is pointing at a
2488
         * template terminator (see `sec_asn1d_next_in_sequence`).
2489
         */
2490
661k
        if (state->child && state->child->theTemplate->kind == 0) {
2491
1.25k
            state->endofcontents = PR_FALSE;
2492
660k
        } else {
2493
660k
            state->endofcontents = PR_TRUE;
2494
660k
        }
2495
661k
    }
2496
2497
661k
    return len;
2498
662k
}
2499
2500
static void
2501
sec_asn1d_pop_state(sec_asn1d_state *state)
2502
7.42M
{
2503
#if 0  /* XXX I think this should always be handled explicitly by parent? */
2504
    /*
2505
     * Account for our child.
2506
     */
2507
    if (state->child != NULL) {
2508
    state->consumed += state->child->consumed;
2509
    if (state->pending) {
2510
        PORT_Assert (!state->indefinite);
2511
        if (state->child->consumed > state->pending) {
2512
        PORT_SetError (SEC_ERROR_BAD_DER);
2513
        state->top->status = decodeError;
2514
        } else {
2515
        state->pending -= state->child->consumed;
2516
        }
2517
    }
2518
    state->child->consumed = 0;
2519
    }
2520
#endif /* XXX */
2521
2522
    /*
2523
     * Free our child.
2524
     */
2525
7.42M
    sec_asn1d_free_child(state, PR_FALSE);
2526
2527
    /*
2528
     * Just make my parent be the current state.  It will then clean
2529
     * up after me and free me (or reuse me).
2530
     */
2531
7.42M
    state->top->current = state->parent;
2532
7.42M
}
2533
2534
static sec_asn1d_state *
2535
sec_asn1d_before_choice(sec_asn1d_state *state)
2536
4.01k
{
2537
4.01k
    sec_asn1d_state *child;
2538
2539
4.01k
    if (state->allocate) {
2540
0
        void *dest;
2541
2542
0
        dest = sec_asn1d_zalloc(state->top->their_pool, state->theTemplate->size);
2543
0
        if ((void *)NULL == dest) {
2544
0
            state->top->status = decodeError;
2545
0
            return (sec_asn1d_state *)NULL;
2546
0
        }
2547
2548
0
        state->dest = (char *)dest + state->theTemplate->offset;
2549
0
    }
2550
2551
4.01k
    child = sec_asn1d_push_state(state->top, state->theTemplate + 1,
2552
4.01k
                                 (char *)state->dest - state->theTemplate->offset,
2553
4.01k
                                 PR_FALSE);
2554
4.01k
    if ((sec_asn1d_state *)NULL == child) {
2555
0
        return (sec_asn1d_state *)NULL;
2556
0
    }
2557
2558
4.01k
    sec_asn1d_scrub_state(child);
2559
4.01k
    child = sec_asn1d_init_state_based_on_template(child);
2560
4.01k
    if ((sec_asn1d_state *)NULL == child) {
2561
0
        return (sec_asn1d_state *)NULL;
2562
0
    }
2563
2564
4.01k
    child->optional = PR_TRUE;
2565
2566
4.01k
    state->place = duringChoice;
2567
2568
4.01k
    return child;
2569
4.01k
}
2570
2571
static sec_asn1d_state *
2572
sec_asn1d_during_choice(sec_asn1d_state *state)
2573
7.01k
{
2574
7.01k
    sec_asn1d_state *child = state->child;
2575
2576
7.01k
    PORT_Assert((sec_asn1d_state *)NULL != child);
2577
2578
7.01k
    if (child->missing) {
2579
6.89k
        unsigned char child_found_tag_modifiers = 0;
2580
6.89k
        unsigned long child_found_tag_number = 0;
2581
6.89k
        void *dest;
2582
2583
6.89k
        state->consumed += child->consumed;
2584
2585
6.89k
        if (child->endofcontents) {
2586
            /* This choice is probably the first item in a GROUP
2587
            ** (e.g. SET_OF) that was indefinite-length encoded.
2588
            ** We're actually at the end of that GROUP.
2589
            ** We look up the stack to be sure that we find
2590
            ** a state with indefinite length encoding before we
2591
            ** find a state (like a SEQUENCE) that is definite.
2592
            */
2593
0
            child->place = notInUse;
2594
0
            state->place = afterChoice;
2595
0
            state->endofcontents = PR_TRUE; /* propagate this up */
2596
0
            if (sec_asn1d_parent_allows_EOC(state))
2597
0
                return state;
2598
0
            PORT_SetError(SEC_ERROR_BAD_DER);
2599
0
            state->top->status = decodeError;
2600
0
            return NULL;
2601
0
        }
2602
2603
6.89k
        dest = (char *)child->dest - child->theTemplate->offset;
2604
6.89k
        child->theTemplate++;
2605
2606
6.89k
        if (0 == child->theTemplate->kind) {
2607
            /* Ran out of choices */
2608
3.39k
            PORT_SetError(SEC_ERROR_BAD_DER);
2609
3.39k
            state->top->status = decodeError;
2610
3.39k
            return (sec_asn1d_state *)NULL;
2611
3.39k
        }
2612
3.50k
        child->dest = (char *)dest + child->theTemplate->offset;
2613
2614
        /* cargo'd from next_in_sequence innards */
2615
3.50k
        if (state->pending) {
2616
0
            PORT_Assert(!state->indefinite);
2617
0
            if (child->consumed > state->pending) {
2618
0
                PORT_SetError(SEC_ERROR_BAD_DER);
2619
0
                state->top->status = decodeError;
2620
0
                return NULL;
2621
0
            }
2622
0
            state->pending -= child->consumed;
2623
0
            if (0 == state->pending) {
2624
                /* XXX uh.. not sure if I should have stopped this
2625
                 * from happening before. */
2626
0
                PORT_Assert(0);
2627
0
                PORT_SetError(SEC_ERROR_BAD_DER);
2628
0
                state->top->status = decodeError;
2629
0
                return (sec_asn1d_state *)NULL;
2630
0
            }
2631
0
        }
2632
2633
3.50k
        child->consumed = 0;
2634
3.50k
        sec_asn1d_scrub_state(child);
2635
2636
        /* move it on top again */
2637
3.50k
        state->top->current = child;
2638
2639
3.50k
        child_found_tag_modifiers = child->found_tag_modifiers;
2640
3.50k
        child_found_tag_number = child->found_tag_number;
2641
2642
3.50k
        child = sec_asn1d_init_state_based_on_template(child);
2643
3.50k
        if ((sec_asn1d_state *)NULL == child) {
2644
0
            return (sec_asn1d_state *)NULL;
2645
0
        }
2646
2647
        /* copy our findings to the new top */
2648
3.50k
        child->found_tag_modifiers = child_found_tag_modifiers;
2649
3.50k
        child->found_tag_number = child_found_tag_number;
2650
2651
3.50k
        child->optional = PR_TRUE;
2652
3.50k
        child->place = afterIdentifier;
2653
2654
3.50k
        return child;
2655
3.50k
    }
2656
117
    if ((void *)NULL != state->dest) {
2657
        /* Store the enum */
2658
117
        int *which = (int *)state->dest;
2659
117
        *which = (int)child->theTemplate->size;
2660
117
    }
2661
2662
117
    child->place = notInUse;
2663
2664
117
    state->place = afterChoice;
2665
117
    return state;
2666
7.01k
}
2667
2668
static void
2669
sec_asn1d_after_choice(sec_asn1d_state *state)
2670
117
{
2671
117
    state->consumed += state->child->consumed;
2672
117
    state->child->consumed = 0;
2673
117
    state->place = afterEndOfContents;
2674
117
    sec_asn1d_pop_state(state);
2675
117
}
2676
2677
unsigned long
2678
sec_asn1d_uinteger(SECItem *src)
2679
0
{
2680
0
    unsigned long value;
2681
0
    int len;
2682
2683
0
    if (src->len > 5 || (src->len > 4 && src->data[0] == 0))
2684
0
        return 0;
2685
2686
0
    value = 0;
2687
0
    len = src->len;
2688
0
    while (len) {
2689
0
        value <<= 8;
2690
0
        value |= src->data[--len];
2691
0
    }
2692
0
    return value;
2693
0
}
2694
2695
SECStatus
2696
SEC_ASN1DecodeInteger(SECItem *src, unsigned long *value)
2697
0
{
2698
0
    unsigned long v;
2699
0
    unsigned int i;
2700
2701
0
    if (src == NULL) {
2702
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
2703
0
        return SECFailure;
2704
0
    }
2705
2706
0
    if (src->len > sizeof(unsigned long)) {
2707
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
2708
0
        return SECFailure;
2709
0
    }
2710
2711
0
    if (src->data == NULL) {
2712
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
2713
0
        return SECFailure;
2714
0
    }
2715
2716
0
    if (src->data[0] & 0x80)
2717
0
        v = -1; /* signed and negative - start with all 1's */
2718
0
    else
2719
0
        v = 0;
2720
2721
0
    for (i = 0; i < src->len; i++) {
2722
        /* shift in next byte */
2723
0
        v <<= 8;
2724
0
        v |= src->data[i];
2725
0
    }
2726
0
    *value = v;
2727
0
    return SECSuccess;
2728
0
}
2729
2730
#ifdef DEBUG_ASN1D_STATES
2731
static void
2732
dump_states(SEC_ASN1DecoderContext *cx)
2733
{
2734
    sec_asn1d_state *state;
2735
    int bufsize = 256;
2736
    char kindBuf[bufsize];
2737
2738
    for (state = cx->current; state->parent; state = state->parent) {
2739
        ;
2740
    }
2741
2742
    for (; state; state = state->child) {
2743
        int i;
2744
        for (i = 0; i < state->depth; i++) {
2745
            printf("  ");
2746
        }
2747
2748
        i = formatKind(state->theTemplate->kind, kindBuf, bufsize);
2749
        printf("%s: tmpl kind %s",
2750
               (state == cx->current) ? "STATE" : "State",
2751
               kindBuf);
2752
        printf(" %s", (state->place <= notInUse) ? place_names[state->place] : "(undefined)");
2753
        if (!i)
2754
            printf(", expect 0x%02lx",
2755
                   state->expect_tag_number | state->expect_tag_modifiers);
2756
2757
        printf("%s%s%s %lu\n",
2758
               state->indefinite ? ", indef" : "",
2759
               state->missing ? ", miss" : "",
2760
               state->endofcontents ? ", EOC" : "",
2761
               state->pending);
2762
    }
2763
2764
    return;
2765
}
2766
#endif /* DEBUG_ASN1D_STATES */
2767
2768
SECStatus
2769
SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
2770
                      const char *buf, unsigned long len)
2771
135k
{
2772
135k
    sec_asn1d_state *state = NULL;
2773
135k
    unsigned long consumed;
2774
135k
    SEC_ASN1EncodingPart what;
2775
2776
135k
    if (cx->status == needBytes)
2777
134k
        cx->status = keepGoing;
2778
2779
45.4M
    while (cx->status == keepGoing) {
2780
45.4M
        state = cx->current;
2781
45.4M
        what = SEC_ASN1_Contents;
2782
45.4M
        consumed = 0;
2783
#ifdef DEBUG_ASN1D_STATES
2784
        printf("\nPLACE = %s, next byte = 0x%02x, %p[%lu]\n",
2785
               (state->place <= notInUse) ? place_names[state->place] : "(undefined)",
2786
               len ? (unsigned int)((unsigned char *)buf)[consumed] : 0,
2787
               buf, consumed);
2788
        dump_states(cx);
2789
#endif /* DEBUG_ASN1D_STATES */
2790
45.4M
        switch (state->place) {
2791
7.62M
            case beforeIdentifier:
2792
7.62M
                consumed = sec_asn1d_parse_identifier(state, buf, len);
2793
7.62M
                what = SEC_ASN1_Identifier;
2794
7.62M
                break;
2795
18.3k
            case duringIdentifier:
2796
18.3k
                consumed = sec_asn1d_parse_more_identifier(state, buf, len);
2797
18.3k
                what = SEC_ASN1_Identifier;
2798
18.3k
                break;
2799
6.96M
            case afterIdentifier:
2800
6.96M
                sec_asn1d_confirm_identifier(state);
2801
6.96M
                break;
2802
6.84M
            case beforeLength:
2803
6.84M
                consumed = sec_asn1d_parse_length(state, buf, len);
2804
6.84M
                what = SEC_ASN1_Length;
2805
6.84M
                break;
2806
12.2k
            case duringLength:
2807
12.2k
                consumed = sec_asn1d_parse_more_length(state, buf, len);
2808
12.2k
                what = SEC_ASN1_Length;
2809
12.2k
                break;
2810
6.84M
            case afterLength:
2811
6.84M
                sec_asn1d_prepare_for_contents(state);
2812
6.84M
                break;
2813
1.77k
            case beforeBitString:
2814
1.77k
                consumed = sec_asn1d_parse_bit_string(state, buf, len);
2815
1.77k
                break;
2816
1.80k
            case duringBitString:
2817
1.80k
                consumed = sec_asn1d_parse_more_bit_string(state, buf, len);
2818
1.80k
                break;
2819
2.97M
            case duringConstructedString:
2820
2.97M
                sec_asn1d_next_substring(state);
2821
2.97M
                break;
2822
4.42M
            case duringGroup:
2823
4.42M
                sec_asn1d_next_in_group(state);
2824
4.42M
                break;
2825
478k
            case duringLeaf:
2826
478k
                consumed = sec_asn1d_parse_leaf(state, buf, len);
2827
478k
                break;
2828
1.17k
            case duringSaveEncoding:
2829
1.17k
                sec_asn1d_reuse_encoding(state);
2830
1.17k
                if (cx->status == decodeError) {
2831
                    /* recursive call has already popped all states from stack.
2832
                    ** Bail out quickly.
2833
                    */
2834
1.06k
                    return SECFailure;
2835
1.06k
                }
2836
108
                if (cx->status == needBytes) {
2837
                    /* recursive call wanted more data. Fatal. Clean up below. */
2838
12
                    PORT_SetError(SEC_ERROR_BAD_DER);
2839
12
                    cx->status = decodeError;
2840
12
                }
2841
108
                break;
2842
15.0k
            case duringSequence:
2843
15.0k
                sec_asn1d_next_in_sequence(state);
2844
15.0k
                break;
2845
656k
            case afterConstructedString:
2846
656k
                sec_asn1d_concat_substrings(state);
2847
656k
                break;
2848
164
            case afterExplicit:
2849
186
            case afterImplicit:
2850
657
            case afterInline:
2851
1.08k
            case afterPointer:
2852
1.08k
                sec_asn1d_absorb_child(state);
2853
1.08k
                break;
2854
7.24k
            case afterGroup:
2855
7.24k
                sec_asn1d_concat_group(state);
2856
7.24k
                break;
2857
96
            case afterSaveEncoding:
2858
                /* SEC_ASN1DecoderUpdate has called itself recursively to
2859
                ** decode SAVEd encoded data, and now is done decoding that.
2860
                ** Return to the calling copy of SEC_ASN1DecoderUpdate.
2861
                */
2862
96
                return SECSuccess;
2863
479k
            case beforeEndOfContents:
2864
479k
                sec_asn1d_prepare_for_end_of_contents(state);
2865
479k
                break;
2866
662k
            case duringEndOfContents:
2867
662k
                consumed = sec_asn1d_parse_end_of_contents(state, buf, len);
2868
662k
                what = SEC_ASN1_EndOfContents;
2869
662k
                break;
2870
7.42M
            case afterEndOfContents:
2871
7.42M
                sec_asn1d_pop_state(state);
2872
7.42M
                break;
2873
4.01k
            case beforeChoice:
2874
4.01k
                state = sec_asn1d_before_choice(state);
2875
4.01k
                break;
2876
7.01k
            case duringChoice:
2877
7.01k
                state = sec_asn1d_during_choice(state);
2878
7.01k
                break;
2879
117
            case afterChoice:
2880
117
                sec_asn1d_after_choice(state);
2881
117
                break;
2882
0
            case notInUse:
2883
0
            default:
2884
                /* This is not an error, but rather a plain old BUG! */
2885
0
                PORT_Assert(0);
2886
0
                PORT_SetError(SEC_ERROR_BAD_DER);
2887
0
                cx->status = decodeError;
2888
0
                break;
2889
45.4M
        }
2890
2891
45.4M
        if (cx->status == decodeError)
2892
119k
            break;
2893
2894
        /* We should not consume more than we have.  */
2895
45.3M
        PORT_Assert(consumed <= len);
2896
45.3M
        if (consumed > len) {
2897
0
            PORT_SetError(SEC_ERROR_BAD_DER);
2898
0
            cx->status = decodeError;
2899
0
            break;
2900
0
        }
2901
2902
        /* It might have changed, so we have to update our local copy.  */
2903
45.3M
        state = cx->current;
2904
2905
        /* If it is NULL, we have popped all the way to the top.  */
2906
45.3M
        if (state == NULL) {
2907
1.66k
            PORT_Assert(consumed == 0);
2908
#if 0 /* XXX I want this here, but it seems that we have situations (like \
2909
       * downloading a pkcs7 cert chain from some issuers) that give us a \
2910
       * length which is greater than the entire encoding.  So, we cannot \
2911
       * have this be an error.                                           \
2912
       */
2913
        if (len > 0) {
2914
        PORT_SetError (SEC_ERROR_BAD_DER);
2915
        cx->status = decodeError;
2916
        } else
2917
#endif
2918
1.66k
            cx->status = allDone;
2919
1.66k
            break;
2920
45.3M
        } else if (state->theTemplate->kind == SEC_ASN1_SKIP_REST) {
2921
2
            cx->status = allDone;
2922
2
            break;
2923
2
        }
2924
2925
45.3M
        if (consumed == 0)
2926
30.3M
            continue;
2927
2928
        /*
2929
         * The following check is specifically looking for an ANY
2930
         * that is *not* also an INNER, because we need to save aside
2931
         * all bytes in that case -- the contents parts will get
2932
         * handled like all other contents, and the end-of-contents
2933
         * bytes are added by the concat code, but the outer header
2934
         * bytes need to get saved too, so we do them explicitly here.
2935
         */
2936
14.9M
        if (state->underlying_kind == SEC_ASN1_ANY && !cx->filter_only && (what == SEC_ASN1_Identifier || what == SEC_ASN1_Length)) {
2937
12.6M
            sec_asn1d_record_any_header(state, buf, consumed);
2938
12.6M
        }
2939
2940
        /*
2941
         * We had some number of good, accepted bytes.  If the caller
2942
         * has registered to see them, pass them along.
2943
         */
2944
14.9M
        if (state->top->filter_proc != NULL) {
2945
0
            int depth;
2946
2947
0
            depth = state->depth;
2948
0
            if (what == SEC_ASN1_EndOfContents && !state->indefinite) {
2949
0
                depth--;
2950
0
                PORT_Assert(depth == sec_asn1d_get_enclosing_construct(state)->depth);
2951
0
            }
2952
0
            (*state->top->filter_proc)(state->top->filter_arg,
2953
0
                                       buf, consumed, depth, what);
2954
0
        }
2955
2956
14.9M
        state->consumed += consumed;
2957
14.9M
        buf += consumed;
2958
14.9M
        len -= consumed;
2959
14.9M
    }
2960
2961
134k
    if (cx->status == decodeError) {
2962
291k
        while (state != NULL) {
2963
171k
            sec_asn1d_free_child(state, PR_TRUE);
2964
171k
            state = state->parent;
2965
171k
        }
2966
#ifdef SEC_ASN1D_FREE_ON_ERROR /*                                           \
2967
                                * XXX This does not work because we can     \
2968
                                * end up leaving behind dangling pointers   \
2969
                                * to stuff that was allocated.  In order    \
2970
                                * to make this really work (which would     \
2971
                                * be a good thing, I think), we need to     \
2972
                                * keep track of every place/pointer that    \
2973
                                * was allocated and make sure to NULL it    \
2974
                                * out before we then free back to the mark. \
2975
                                */
2976
        if (cx->their_pool != NULL) {
2977
            PORT_Assert(cx->their_mark != NULL);
2978
            PORT_ArenaRelease(cx->their_pool, cx->their_mark);
2979
            cx->their_mark = NULL;
2980
        }
2981
#endif
2982
119k
        return SECFailure;
2983
119k
    }
2984
2985
#if 0 /* XXX This is what I want, but cannot have because it seems we    \
2986
       * have situations (like when downloading a pkcs7 cert chain from  \
2987
       * some issuers) that give us a total length which is greater than \
2988
       * the entire encoding.  So, we have to allow allDone to have a    \
2989
       * remaining length greater than zero.  I wanted to catch internal \
2990
       * bugs with this, noticing when we do not have the right length.  \
2991
       * Oh well.                                                        \
2992
       */
2993
    PORT_Assert (len == 0
2994
         && (cx->status == needBytes || cx->status == allDone));
2995
#else
2996
14.7k
    PORT_Assert((len == 0 && cx->status == needBytes) || cx->status == allDone);
2997
14.7k
#endif
2998
14.7k
    return SECSuccess;
2999
134k
}
3000
3001
SECStatus
3002
SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx)
3003
134k
{
3004
134k
    SECStatus rv;
3005
3006
134k
    if (!cx || cx->status == needBytes) {
3007
13.0k
        if (0 == PORT_GetError()) {
3008
            /* don't clobber a real reason for the failure like bad password
3009
             * or invalid algorithm */
3010
0
            PORT_SetError(SEC_ERROR_BAD_DER);
3011
0
        }
3012
13.0k
        rv = SECFailure;
3013
121k
    } else {
3014
121k
        rv = SECSuccess;
3015
121k
    }
3016
3017
    /*
3018
     * XXX anything else that needs to be finished?
3019
     */
3020
3021
134k
    if (cx) {
3022
134k
        PORT_FreeArena(cx->our_pool, PR_TRUE);
3023
134k
    }
3024
3025
134k
    return rv;
3026
134k
}
3027
3028
SEC_ASN1DecoderContext *
3029
SEC_ASN1DecoderStart(PLArenaPool *their_pool, void *dest,
3030
                     const SEC_ASN1Template *theTemplate)
3031
134k
{
3032
134k
    PLArenaPool *our_pool;
3033
134k
    SEC_ASN1DecoderContext *cx;
3034
3035
134k
    our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
3036
134k
    if (our_pool == NULL)
3037
0
        return NULL;
3038
3039
134k
    cx = (SEC_ASN1DecoderContext *)PORT_ArenaZAlloc(our_pool, sizeof(*cx));
3040
134k
    if (cx == NULL) {
3041
0
        PORT_FreeArena(our_pool, PR_FALSE);
3042
0
        return NULL;
3043
0
    }
3044
3045
134k
    cx->our_pool = our_pool;
3046
134k
    if (their_pool != NULL) {
3047
134k
        cx->their_pool = their_pool;
3048
#ifdef SEC_ASN1D_FREE_ON_ERROR
3049
        cx->their_mark = PORT_ArenaMark(their_pool);
3050
#endif
3051
134k
    }
3052
3053
134k
    cx->status = needBytes;
3054
3055
134k
    if (sec_asn1d_push_state(cx, theTemplate, dest, PR_FALSE) == NULL || sec_asn1d_init_state_based_on_template(cx->current) == NULL) {
3056
        /*
3057
         * Trouble initializing (probably due to failed allocations)
3058
         * requires that we just give up.
3059
         */
3060
0
        PORT_FreeArena(our_pool, PR_FALSE);
3061
0
        return NULL;
3062
0
    }
3063
3064
134k
    return cx;
3065
134k
}
3066
3067
void
3068
SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx,
3069
                             SEC_ASN1WriteProc fn, void *arg,
3070
                             PRBool only)
3071
0
{
3072
    /* check that we are "between" fields here */
3073
0
    PORT_Assert(cx->during_notify);
3074
3075
0
    cx->filter_proc = fn;
3076
0
    cx->filter_arg = arg;
3077
0
    cx->filter_only = only;
3078
0
}
3079
3080
void
3081
SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx)
3082
0
{
3083
    /* check that we are "between" fields here */
3084
0
    PORT_Assert(cx->during_notify);
3085
3086
0
    cx->filter_proc = NULL;
3087
0
    cx->filter_arg = NULL;
3088
0
    cx->filter_only = PR_FALSE;
3089
0
}
3090
3091
void
3092
SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
3093
                             SEC_ASN1NotifyProc fn, void *arg)
3094
0
{
3095
0
    cx->notify_proc = fn;
3096
0
    cx->notify_arg = arg;
3097
0
}
3098
3099
void
3100
SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx)
3101
0
{
3102
0
    cx->notify_proc = NULL;
3103
0
    cx->notify_arg = NULL; /* not necessary; just being clean */
3104
0
}
3105
3106
void
3107
SEC_ASN1DecoderSetMaximumElementSize(SEC_ASN1DecoderContext *cx,
3108
                                     unsigned long max_size)
3109
134k
{
3110
134k
    cx->max_element_size = max_size;
3111
134k
}
3112
3113
void
3114
SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error)
3115
0
{
3116
0
    PORT_Assert(cx);
3117
0
    PORT_SetError(error);
3118
0
    cx->status = decodeError;
3119
0
}
3120
3121
SECStatus
3122
SEC_ASN1Decode(PLArenaPool *poolp, void *dest,
3123
               const SEC_ASN1Template *theTemplate,
3124
               const char *buf, long len)
3125
134k
{
3126
134k
    SEC_ASN1DecoderContext *dcx;
3127
134k
    SECStatus urv, frv;
3128
3129
134k
    dcx = SEC_ASN1DecoderStart(poolp, dest, theTemplate);
3130
134k
    if (dcx == NULL)
3131
0
        return SECFailure;
3132
3133
    /* In one-shot mode, there's no possibility of streaming data beyond the
3134
     * length of len */
3135
134k
    SEC_ASN1DecoderSetMaximumElementSize(dcx, len);
3136
3137
134k
    urv = SEC_ASN1DecoderUpdate(dcx, buf, len);
3138
134k
    frv = SEC_ASN1DecoderFinish(dcx);
3139
3140
134k
    if (urv != SECSuccess)
3141
119k
        return urv;
3142
3143
14.7k
    return frv;
3144
134k
}
3145
3146
SECStatus
3147
SEC_ASN1DecodeItem(PLArenaPool *poolp, void *dest,
3148
                   const SEC_ASN1Template *theTemplate,
3149
                   const SECItem *src)
3150
134k
{
3151
134k
    return SEC_ASN1Decode(poolp, dest, theTemplate,
3152
134k
                          (const char *)src->data, src->len);
3153
134k
}
3154
3155
#ifdef DEBUG_ASN1D_STATES
3156
void
3157
sec_asn1d_Assert(const char *s, const char *file, PRIntn ln)
3158
{
3159
    printf("Assertion failed, \"%s\", file %s, line %d\n", s, file, ln);
3160
    fflush(stdout);
3161
}
3162
#endif
3163
3164
/*
3165
 * Generic templates for individual/simple items and pointers to
3166
 * and sets of same.
3167
 *
3168
 * If you need to add a new one, please note the following:
3169
 *   - For each new basic type you should add *four* templates:
3170
 *  one plain, one PointerTo, one SequenceOf and one SetOf.
3171
 *   - If the new type can be constructed (meaning, it is a
3172
 *  *string* type according to BER/DER rules), then you should
3173
 *  or-in SEC_ASN1_MAY_STREAM to the type in the basic template.
3174
 *  See the definition of the OctetString template for an example.
3175
 *   - It may not be obvious, but these are in *alphabetical*
3176
 *  order based on the SEC_ASN1_XXX name; so put new ones in
3177
 *  the appropriate place.
3178
 */
3179
3180
const SEC_ASN1Template SEC_SequenceOfAnyTemplate[] = {
3181
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }
3182
};
3183
3184
#if 0
3185
3186
const SEC_ASN1Template SEC_PointerToBitStringTemplate[] = {
3187
    { SEC_ASN1_POINTER, 0, SEC_BitStringTemplate }
3188
};
3189
3190
const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[] = {
3191
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_BitStringTemplate }
3192
};
3193
3194
const SEC_ASN1Template SEC_SetOfBitStringTemplate[] = {
3195
    { SEC_ASN1_SET_OF, 0, SEC_BitStringTemplate }
3196
};
3197
3198
const SEC_ASN1Template SEC_PointerToBMPStringTemplate[] = {
3199
    { SEC_ASN1_POINTER, 0, SEC_BMPStringTemplate }
3200
};
3201
3202
const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[] = {
3203
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_BMPStringTemplate }
3204
};
3205
3206
const SEC_ASN1Template SEC_SetOfBMPStringTemplate[] = {
3207
    { SEC_ASN1_SET_OF, 0, SEC_BMPStringTemplate }
3208
};
3209
3210
const SEC_ASN1Template SEC_PointerToBooleanTemplate[] = {
3211
    { SEC_ASN1_POINTER, 0, SEC_BooleanTemplate }
3212
};
3213
3214
const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[] = {
3215
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_BooleanTemplate }
3216
};
3217
3218
const SEC_ASN1Template SEC_SetOfBooleanTemplate[] = {
3219
    { SEC_ASN1_SET_OF, 0, SEC_BooleanTemplate }
3220
};
3221
3222
#endif
3223
3224
const SEC_ASN1Template SEC_EnumeratedTemplate[] = {
3225
    { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) }
3226
};
3227
3228
const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[] = {
3229
    { SEC_ASN1_POINTER, 0, SEC_EnumeratedTemplate }
3230
};
3231
3232
#if 0
3233
3234
const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[] = {
3235
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_EnumeratedTemplate }
3236
};
3237
3238
#endif
3239
3240
const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[] = {
3241
    { SEC_ASN1_SET_OF, 0, SEC_EnumeratedTemplate }
3242
};
3243
3244
const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[] = {
3245
    { SEC_ASN1_POINTER, 0, SEC_GeneralizedTimeTemplate }
3246
};
3247
3248
#if 0
3249
3250
const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[] = {
3251
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_GeneralizedTimeTemplate }
3252
};
3253
3254
const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[] = {
3255
    { SEC_ASN1_SET_OF, 0, SEC_GeneralizedTimeTemplate }
3256
};
3257
3258
const SEC_ASN1Template SEC_PointerToIA5StringTemplate[] = {
3259
    { SEC_ASN1_POINTER, 0, SEC_IA5StringTemplate }
3260
};
3261
3262
const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[] = {
3263
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_IA5StringTemplate }
3264
};
3265
3266
const SEC_ASN1Template SEC_SetOfIA5StringTemplate[] = {
3267
    { SEC_ASN1_SET_OF, 0, SEC_IA5StringTemplate }
3268
};
3269
3270
const SEC_ASN1Template SEC_PointerToIntegerTemplate[] = {
3271
    { SEC_ASN1_POINTER, 0, SEC_IntegerTemplate }
3272
};
3273
3274
const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[] = {
3275
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_IntegerTemplate }
3276
};
3277
3278
const SEC_ASN1Template SEC_SetOfIntegerTemplate[] = {
3279
    { SEC_ASN1_SET_OF, 0, SEC_IntegerTemplate }
3280
};
3281
3282
const SEC_ASN1Template SEC_PointerToNullTemplate[] = {
3283
    { SEC_ASN1_POINTER, 0, SEC_NullTemplate }
3284
};
3285
3286
const SEC_ASN1Template SEC_SequenceOfNullTemplate[] = {
3287
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_NullTemplate }
3288
};
3289
3290
const SEC_ASN1Template SEC_SetOfNullTemplate[] = {
3291
    { SEC_ASN1_SET_OF, 0, SEC_NullTemplate }
3292
};
3293
3294
const SEC_ASN1Template SEC_PointerToObjectIDTemplate[] = {
3295
    { SEC_ASN1_POINTER, 0, SEC_ObjectIDTemplate }
3296
};
3297
3298
#endif
3299
3300
const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[] = {
3301
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_ObjectIDTemplate }
3302
};
3303
3304
#if 0
3305
3306
const SEC_ASN1Template SEC_SetOfObjectIDTemplate[] = {
3307
    { SEC_ASN1_SET_OF, 0, SEC_ObjectIDTemplate }
3308
};
3309
3310
const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[] = {
3311
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_OctetStringTemplate }
3312
};
3313
3314
const SEC_ASN1Template SEC_SetOfOctetStringTemplate[] = {
3315
    { SEC_ASN1_SET_OF, 0, SEC_OctetStringTemplate }
3316
};
3317
3318
#endif
3319
3320
const SEC_ASN1Template SEC_PrintableStringTemplate[] = {
3321
    { SEC_ASN1_PRINTABLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
3322
};
3323
3324
#if 0
3325
3326
const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[] = {
3327
    { SEC_ASN1_POINTER, 0, SEC_PrintableStringTemplate }
3328
};
3329
3330
const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[] = {
3331
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_PrintableStringTemplate }
3332
};
3333
3334
const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[] = {
3335
    { SEC_ASN1_SET_OF, 0, SEC_PrintableStringTemplate }
3336
};
3337
3338
#endif
3339
3340
const SEC_ASN1Template SEC_T61StringTemplate[] = {
3341
    { SEC_ASN1_T61_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
3342
};
3343
3344
#if 0
3345
3346
const SEC_ASN1Template SEC_PointerToT61StringTemplate[] = {
3347
    { SEC_ASN1_POINTER, 0, SEC_T61StringTemplate }
3348
};
3349
3350
const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[] = {
3351
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_T61StringTemplate }
3352
};
3353
3354
const SEC_ASN1Template SEC_SetOfT61StringTemplate[] = {
3355
    { SEC_ASN1_SET_OF, 0, SEC_T61StringTemplate }
3356
};
3357
3358
#endif
3359
3360
const SEC_ASN1Template SEC_UniversalStringTemplate[] = {
3361
    { SEC_ASN1_UNIVERSAL_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
3362
};
3363
3364
#if 0
3365
3366
const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[] = {
3367
    { SEC_ASN1_POINTER, 0, SEC_UniversalStringTemplate }
3368
};
3369
3370
const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[] = {
3371
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_UniversalStringTemplate }
3372
};
3373
3374
const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[] = {
3375
    { SEC_ASN1_SET_OF, 0, SEC_UniversalStringTemplate }
3376
};
3377
3378
const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[] = {
3379
    { SEC_ASN1_POINTER, 0, SEC_UTCTimeTemplate }
3380
};
3381
3382
const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[] = {
3383
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_UTCTimeTemplate }
3384
};
3385
3386
const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[] = {
3387
    { SEC_ASN1_SET_OF, 0, SEC_UTCTimeTemplate }
3388
};
3389
3390
const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[] = {
3391
    { SEC_ASN1_POINTER, 0, SEC_UTF8StringTemplate }
3392
};
3393
3394
const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[] = {
3395
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_UTF8StringTemplate }
3396
};
3397
3398
const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[] = {
3399
    { SEC_ASN1_SET_OF, 0, SEC_UTF8StringTemplate }
3400
};
3401
3402
#endif
3403
3404
const SEC_ASN1Template SEC_VisibleStringTemplate[] = {
3405
    { SEC_ASN1_VISIBLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
3406
};
3407
3408
#if 0
3409
3410
const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[] = {
3411
    { SEC_ASN1_POINTER, 0, SEC_VisibleStringTemplate }
3412
};
3413
3414
const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[] = {
3415
    { SEC_ASN1_SEQUENCE_OF, 0, SEC_VisibleStringTemplate }
3416
};
3417
3418
const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[] = {
3419
    { SEC_ASN1_SET_OF, 0, SEC_VisibleStringTemplate }
3420
};
3421
3422
#endif
3423
3424
/*
3425
 * Template for skipping a subitem.
3426
 *
3427
 * Note that it only makes sense to use this for decoding (when you want
3428
 * to decode something where you are only interested in one or two of
3429
 * the fields); you cannot encode a SKIP!
3430
 */
3431
const SEC_ASN1Template SEC_SkipTemplate[] = {
3432
    { SEC_ASN1_SKIP }
3433
};
3434
3435
/* These functions simply return the address of the above-declared templates.
3436
** This is necessary for Windows DLLs.  Sigh.
3437
*/
3438
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_EnumeratedTemplate)
3439
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToEnumeratedTemplate)
3440
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfAnyTemplate)
3441
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfObjectIDTemplate)
3442
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SkipTemplate)
3443
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UniversalStringTemplate)
3444
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PrintableStringTemplate)
3445
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_T61StringTemplate)
3446
SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToGeneralizedTimeTemplate)