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