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