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