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