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