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