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