Line data Source code
1 : /* ber-decoder.c - Basic Encoding Rules Decoder
2 : * Copyright (C) 2001, 2004, 2006, 2012, 2015 g10 Code GmbH
3 : *
4 : * This file is part of KSBA.
5 : *
6 : * KSBA is free software; you can redistribute it and/or modify
7 : * it under the terms of either
8 : *
9 : * - the GNU Lesser General Public License as published by the Free
10 : * Software Foundation; either version 3 of the License, or (at
11 : * your option) any later version.
12 : *
13 : * or
14 : *
15 : * - the GNU General Public License as published by the Free
16 : * Software Foundation; either version 2 of the License, or (at
17 : * your option) any later version.
18 : *
19 : * or both in parallel, as here.
20 : *
21 : * KSBA is distributed in the hope that it will be useful, but WITHOUT
22 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 : * License for more details.
25 : *
26 : * You should have received a copies of the GNU General Public License
27 : * and the GNU Lesser General Public License along with this program;
28 : * if not, see <http://www.gnu.org/licenses/>.
29 : */
30 :
31 : #include <config.h>
32 : #include <stdio.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 : #include <assert.h>
36 : #include "util.h"
37 :
38 : #include "util.h"
39 : #include "ksba.h"
40 : #include "asn1-func.h"
41 : #include "ber-decoder.h"
42 : #include "ber-help.h"
43 :
44 :
45 : struct decoder_state_item_s {
46 : AsnNode node;
47 : int went_up;
48 : int in_seq_of;
49 : int in_any; /* actually in a constructed any */
50 : int again;
51 : int next_tag;
52 : int length; /* length of the value */
53 : int ndef_length; /* the length is of indefinite length */
54 : int nread; /* number of value bytes processed */
55 : };
56 : typedef struct decoder_state_item_s DECODER_STATE_ITEM;
57 :
58 : struct decoder_state_s {
59 : DECODER_STATE_ITEM cur; /* current state */
60 : int stacksize;
61 : int idx;
62 : DECODER_STATE_ITEM stack[1];
63 : };
64 : typedef struct decoder_state_s *DECODER_STATE;
65 :
66 :
67 : /* Context for a decoder. */
68 : struct ber_decoder_s
69 : {
70 : AsnNode module; /* the ASN.1 structure */
71 : ksba_reader_t reader;
72 : const char *last_errdesc; /* string with the error description */
73 : int non_der; /* set if the encoding is not DER conform */
74 : AsnNode root; /* of the expanded parse tree */
75 : DECODER_STATE ds;
76 : int bypass;
77 :
78 : /* Because some certificates actually come with trailing garbage, we
79 : use a hack to ignore this garbage. This hack is enabled for data
80 : starting with a fixed length sequence and this variable takes the
81 : length of this sequence. If it is 0, the hack is not
82 : activated. */
83 : unsigned long outer_sequence_length;
84 : int ignore_garbage; /* Set to indicate that garbage should be
85 : ignored. */
86 : int fast_stop; /* Yet another hack. */
87 :
88 : int first_tag_seen; /* Indicates whether the first tag of a decoder
89 : run has been read. */
90 :
91 : int honor_module_end;
92 : int debug;
93 : int use_image;
94 : struct
95 : {
96 : unsigned char *buf;
97 : size_t used;
98 : size_t length;
99 : } image;
100 : struct
101 : {
102 : int primitive; /* current value is a primitive one */
103 : size_t length; /* length of the primitive one */
104 : int nhdr; /* length of the header */
105 : int tag;
106 : int is_endtag;
107 : AsnNode node; /* NULL or matching node */
108 : } val;
109 : };
110 :
111 :
112 :
113 : /* Evaluate with overflow check: A1 + A2 > B */
114 : static inline int
115 301 : sum_a1_a2_gt_b (size_t a1, size_t a2, size_t b)
116 : {
117 301 : size_t sum = a1 + a2;
118 301 : return (sum < a1 || sum > b);
119 : }
120 :
121 : /* Evaluate with overflow check: A1 + A2 >= B */
122 : static inline int
123 302 : sum_a1_a2_ge_b (size_t a1, size_t a2, size_t b)
124 : {
125 302 : size_t sum = a1 + a2;
126 302 : return (sum < a1 || sum >= b);
127 : }
128 :
129 :
130 :
131 : static DECODER_STATE
132 9 : new_decoder_state (void)
133 : {
134 : DECODER_STATE ds;
135 :
136 9 : ds = xmalloc (sizeof (*ds) + 99*sizeof(DECODER_STATE_ITEM));
137 9 : ds->stacksize = 100;
138 9 : ds->idx = 0;
139 9 : ds->cur.node = NULL;
140 9 : ds->cur.went_up = 0;
141 9 : ds->cur.in_seq_of = 0;
142 9 : ds->cur.in_any = 0;
143 9 : ds->cur.again = 0;
144 9 : ds->cur.next_tag = 0;
145 9 : ds->cur.length = 0;
146 9 : ds->cur.ndef_length = 1;
147 9 : ds->cur.nread = 0;
148 9 : return ds;
149 : }
150 :
151 : static void
152 9 : release_decoder_state (DECODER_STATE ds)
153 : {
154 9 : xfree (ds);
155 9 : }
156 :
157 : static void
158 0 : dump_decoder_state (DECODER_STATE ds)
159 : {
160 : int i;
161 :
162 0 : for (i=0; i < ds->idx; i++)
163 : {
164 0 : fprintf (stderr," ds stack[%d] (", i);
165 0 : if (ds->stack[i].node)
166 0 : _ksba_asn_node_dump (ds->stack[i].node, stderr);
167 : else
168 0 : fprintf (stderr, "Null");
169 0 : fprintf (stderr,") %s%d (%d)%s\n",
170 0 : ds->stack[i].ndef_length? "ndef ":"",
171 : ds->stack[i].length,
172 : ds->stack[i].nread,
173 0 : ds->stack[i].in_seq_of? " in_seq_of":"");
174 : }
175 0 : }
176 :
177 : /* Push ITEM onto the stack */
178 : static gpg_error_t
179 141 : push_decoder_state (DECODER_STATE ds)
180 : {
181 141 : if (ds->idx >= ds->stacksize)
182 : {
183 0 : fprintf (stderr, "ksba: ber-decoder: stack overflow!\n");
184 0 : return gpg_error (GPG_ERR_LIMIT_REACHED);
185 : }
186 141 : ds->stack[ds->idx++] = ds->cur;
187 141 : return 0;
188 : }
189 :
190 : static gpg_error_t
191 141 : pop_decoder_state (DECODER_STATE ds)
192 : {
193 141 : if (!ds->idx)
194 : {
195 0 : fprintf (stderr, "ksba: ber-decoder: stack underflow!\n");
196 0 : return gpg_error (GPG_ERR_INTERNAL);
197 : }
198 141 : ds->cur = ds->stack[--ds->idx];
199 141 : return 0;
200 : }
201 :
202 :
203 :
204 : static int
205 0 : set_error (BerDecoder d, AsnNode node, const char *text)
206 : {
207 0 : fprintf (stderr,"ksba: ber-decoder: node `%s': %s\n",
208 : node? node->name:"?", text);
209 0 : d->last_errdesc = text;
210 0 : return gpg_error (GPG_ERR_BAD_BER);
211 : }
212 :
213 :
214 : static int
215 0 : eof_or_error (BerDecoder d, int premature)
216 : {
217 : gpg_error_t err;
218 :
219 0 : err = ksba_reader_error (d->reader);
220 0 : if (err)
221 : {
222 0 : set_error (d, NULL, "read error");
223 0 : return err;
224 : }
225 0 : if (premature)
226 0 : return set_error (d, NULL, "premature EOF");
227 0 : return gpg_error (GPG_ERR_EOF);
228 : }
229 :
230 : static const char *
231 0 : universal_tag_name (unsigned long no)
232 : {
233 : static const char * const names[31] = {
234 : "[End Tag]",
235 : "BOOLEAN",
236 : "INTEGER",
237 : "BIT STRING",
238 : "OCTECT STRING",
239 : "NULL",
240 : "OBJECT IDENTIFIER",
241 : "ObjectDescriptor",
242 : "EXTERNAL",
243 : "REAL",
244 : "ENUMERATED",
245 : "EMBEDDED PDV",
246 : "UTF8String",
247 : "RELATIVE-OID",
248 : "[UNIVERSAL 14]",
249 : "[UNIVERSAL 15]",
250 : "SEQUENCE",
251 : "SET",
252 : "NumericString",
253 : "PrintableString",
254 : "TeletexString",
255 : "VideotexString",
256 : "IA5String",
257 : "UTCTime",
258 : "GeneralizedTime",
259 : "GraphicString",
260 : "VisibleString",
261 : "GeneralString",
262 : "UniversalString",
263 : "CHARACTER STRING",
264 : "BMPString"
265 : };
266 :
267 0 : return no < DIM(names)? names[no]:NULL;
268 : }
269 :
270 :
271 : static void
272 0 : dump_tlv (const struct tag_info *ti, FILE *fp)
273 : {
274 0 : const char *tagname = NULL;
275 :
276 0 : if (ti->class == CLASS_UNIVERSAL)
277 0 : tagname = universal_tag_name (ti->tag);
278 :
279 0 : if (tagname)
280 0 : fputs (tagname, fp);
281 : else
282 0 : fprintf (fp, "[%s %lu]",
283 0 : ti->class == CLASS_UNIVERSAL? "UNIVERSAL" :
284 0 : ti->class == CLASS_APPLICATION? "APPLICATION" :
285 0 : ti->class == CLASS_CONTEXT? "CONTEXT-SPECIFIC" : "PRIVATE",
286 : ti->tag);
287 0 : fprintf (fp, " %c hdr=%lu len=",
288 0 : ti->is_constructed? 'c':'p',
289 : (unsigned long)ti->nhdr);
290 0 : if (ti->ndef)
291 0 : fputs ("ndef", fp);
292 : else
293 0 : fprintf (fp, "%lu", ti->length);
294 0 : }
295 :
296 :
297 : static void
298 58 : clear_help_flags (AsnNode node)
299 : {
300 : AsnNode p;
301 :
302 613 : for (p=node; p; p = _ksba_asn_walk_tree (node, p))
303 : {
304 555 : if (p->type == TYPE_TAG)
305 : {
306 24 : p->flags.tag_seen = 0;
307 : }
308 555 : p->flags.skip_this = 0;
309 : }
310 :
311 58 : }
312 :
313 : static void
314 49 : prepare_copied_tree (AsnNode node)
315 : {
316 : AsnNode p;
317 :
318 49 : clear_help_flags (node);
319 262 : for (p=node; p; p = _ksba_asn_walk_tree (node, p))
320 213 : p->off = -1;
321 :
322 49 : }
323 :
324 : static void
325 9 : fixup_type_any (AsnNode node)
326 : {
327 : AsnNode p;
328 :
329 402 : for (p=node; p; p = _ksba_asn_walk_tree (node, p))
330 : {
331 393 : if (p->type == TYPE_ANY && p->off != -1)
332 50 : p->type = p->actual_type;
333 : }
334 9 : }
335 :
336 :
337 :
338 : BerDecoder
339 9 : _ksba_ber_decoder_new (void)
340 : {
341 : BerDecoder d;
342 :
343 9 : d = xtrycalloc (1, sizeof *d);
344 9 : if (!d)
345 0 : return NULL;
346 :
347 9 : return d;
348 : }
349 :
350 : void
351 9 : _ksba_ber_decoder_release (BerDecoder d)
352 : {
353 9 : xfree (d);
354 9 : }
355 :
356 : /**
357 : * _ksba_ber_decoder_set_module:
358 : * @d: Decoder object
359 : * @module: ASN.1 Parse tree
360 : *
361 : * Initialize the decoder with the ASN.1 module. Note, that this is a
362 : * shallow copy of the module. Hmmm: What about ref-counting of
363 : * AsnNodes?
364 : *
365 : * Return value: 0 on success or an error code
366 : **/
367 : gpg_error_t
368 9 : _ksba_ber_decoder_set_module (BerDecoder d, ksba_asn_tree_t module)
369 : {
370 9 : if (!d || !module)
371 0 : return gpg_error (GPG_ERR_INV_VALUE);
372 9 : if (d->module)
373 0 : return gpg_error (GPG_ERR_CONFLICT); /* module already set */
374 :
375 9 : d->module = module->parse_tree;
376 9 : return 0;
377 : }
378 :
379 :
380 : gpg_error_t
381 9 : _ksba_ber_decoder_set_reader (BerDecoder d, ksba_reader_t r)
382 : {
383 9 : if (!d || !r)
384 0 : return gpg_error (GPG_ERR_INV_VALUE);
385 9 : if (d->reader)
386 0 : return gpg_error (GPG_ERR_CONFLICT); /* reader already set */
387 :
388 9 : d->reader = r;
389 9 : return 0;
390 : }
391 :
392 :
393 : /**********************************************
394 : *********** decoding machinery *************
395 : **********************************************/
396 :
397 : /* Read one byte, return that byte or -1 on error or EOF. */
398 : static int
399 0 : read_byte (ksba_reader_t reader)
400 : {
401 : unsigned char buf;
402 : size_t nread;
403 : int rc;
404 :
405 : do
406 0 : rc = ksba_reader_read (reader, &buf, 1, &nread);
407 0 : while (!rc && !nread);
408 0 : return rc? -1: buf;
409 : }
410 :
411 : /* Read COUNT bytes into buffer. BUFFER may be NULL to skip over
412 : COUNT bytes. Return 0 on success or -1 on error. */
413 : static int
414 160 : read_buffer (ksba_reader_t reader, char *buffer, size_t count)
415 : {
416 : size_t nread;
417 :
418 160 : if (buffer)
419 : {
420 471 : while (count)
421 : {
422 151 : if (ksba_reader_read (reader, buffer, count, &nread))
423 0 : return -1;
424 151 : buffer += nread;
425 151 : count -= nread;
426 : }
427 : }
428 : else
429 : {
430 : char dummy[256];
431 : size_t n;
432 :
433 0 : while (count)
434 : {
435 0 : n = count > DIM(dummy) ? DIM(dummy): count;
436 0 : if (ksba_reader_read (reader, dummy, n, &nread))
437 0 : return -1;
438 0 : count -= nread;
439 : }
440 : }
441 160 : return 0;
442 : }
443 :
444 : /* Return 0 for no match, 1 for a match and 2 for an ANY match of an
445 : constructed type */
446 : static int
447 358 : cmp_tag (AsnNode node, const struct tag_info *ti)
448 : {
449 358 : if (node->flags.class != ti->class)
450 : {
451 0 : if (node->flags.class == CLASS_UNIVERSAL && node->type == TYPE_ANY)
452 0 : return ti->is_constructed? 2:1;
453 0 : return 0;
454 : }
455 358 : if (node->type == TYPE_TAG)
456 : {
457 12 : return_val_if_fail (node->valuetype == VALTYPE_ULONG, 0);
458 12 : return node->value.v_ulong == ti->tag;
459 : }
460 346 : if (node->type == ti->tag)
461 201 : return 1;
462 145 : if (ti->class == CLASS_UNIVERSAL)
463 : {
464 145 : if (node->type == TYPE_SEQUENCE_OF && ti->tag == TYPE_SEQUENCE)
465 21 : return 1;
466 124 : if (node->type == TYPE_SET_OF && ti->tag == TYPE_SET)
467 41 : return 1;
468 83 : if (node->type == TYPE_ANY)
469 50 : return _ksba_asn_is_primitive (ti->tag)? 1:2;
470 : }
471 :
472 33 : return 0;
473 : }
474 :
475 : /* Find the node in the tree ROOT corresponding to TI and return that
476 : node. Returns NULL if the node was not found */
477 : static AsnNode
478 6 : find_anchor_node (AsnNode root, const struct tag_info *ti)
479 : {
480 6 : AsnNode node = root;
481 :
482 15 : while (node)
483 : {
484 9 : if (cmp_tag (node, ti))
485 : {
486 6 : return node; /* found */
487 : }
488 :
489 3 : if (node->down)
490 3 : node = node->down;
491 0 : else if (node == root)
492 0 : return NULL; /* not found */
493 0 : else if (node->right)
494 0 : node = node->right;
495 : else
496 : { /* go up and right */
497 : do
498 : {
499 0 : while (node->left && node->left->right == node)
500 0 : node = node->left;
501 0 : node = node->left;
502 :
503 0 : if (!node || node == root)
504 0 : return NULL; /* back at the root -> not found */
505 : }
506 0 : while (!node->right);
507 0 : node = node->right;
508 : }
509 : }
510 :
511 0 : return NULL;
512 : }
513 :
514 : static int
515 344 : match_der (AsnNode root, const struct tag_info *ti,
516 : DECODER_STATE ds, AsnNode *retnode, int debug)
517 : {
518 : int rc;
519 : AsnNode node;
520 :
521 344 : *retnode = NULL;
522 344 : node = ds->cur.node;
523 344 : if (!node)
524 : {
525 6 : if (debug)
526 0 : fputs (" looking for anchor\n", stderr);
527 6 : node = find_anchor_node (root, ti);
528 6 : if (!node)
529 0 : fputs (" anchor node not found\n", stderr);
530 : }
531 338 : else if (ds->cur.again)
532 : {
533 0 : if (debug)
534 0 : fputs (" doing last again\n", stderr);
535 0 : ds->cur.again = 0;
536 : }
537 338 : else if (_ksba_asn_is_primitive (node->type) || node->type == TYPE_ANY
538 239 : || node->type == TYPE_SIZE || node->type == TYPE_DEFAULT )
539 : {
540 102 : if (debug)
541 0 : fputs (" primitive type - get next\n", stderr);
542 204 : if (node->right)
543 99 : node = node->right;
544 3 : else if (!node->flags.in_choice)
545 : {
546 0 : if (node->flags.is_implicit)
547 : {
548 0 : if (debug)
549 0 : fputs (" node was implicit - advancing\n", stderr);
550 0 : while (node->left && node->left->right == node)
551 0 : node = node->left;
552 0 : node = node->left; /* this is the up pointer */
553 0 : if (node)
554 0 : node = node->right;
555 : }
556 : else
557 0 : node = NULL;
558 : }
559 : else /* in choice */
560 : {
561 3 : if (debug)
562 0 : fputs (" going up after choice - get next\n", stderr);
563 9 : while (node->left && node->left->right == node)
564 3 : node = node->left;
565 3 : node = node->left; /* this is the up pointer */
566 3 : if (node)
567 3 : node = node->right;
568 : }
569 : }
570 236 : else if (node->type == TYPE_SEQUENCE_OF || node->type == TYPE_SET_OF)
571 : {
572 92 : if (debug)
573 : {
574 0 : fprintf (stderr, " prepare for seq/set_of (%d %d) ",
575 : ds->cur.length, ds->cur.nread);
576 0 : fprintf (stderr, " cur: ("); _ksba_asn_node_dump (node, stderr);
577 0 : fprintf (stderr, ")\n");
578 0 : if (ds->cur.node->flags.in_array)
579 0 : fputs (" This is in an array!\n", stderr);
580 0 : if (ds->cur.went_up)
581 0 : fputs (" And we are going up!\n", stderr);
582 : }
583 269 : if ((ds->cur.went_up && !ds->cur.node->flags.in_array) ||
584 170 : (ds->idx && ds->cur.nread >= ds->stack[ds->idx-1].length))
585 : {
586 7 : if (debug)
587 0 : fprintf (stderr, " advancing\n");
588 14 : if (node->right)
589 0 : node = node->right;
590 : else
591 : {
592 : for (;;)
593 : {
594 16 : while (node->left && node->left->right == node)
595 0 : node = node->left;
596 8 : node = node->left; /* this is the up pointer */
597 8 : if (!node)
598 1 : break;
599 7 : if (node->right)
600 : {
601 6 : node = node->right;
602 6 : break;
603 : }
604 1 : }
605 : }
606 : }
607 85 : else if (ds->cur.node->flags.in_array
608 73 : && ds->cur.went_up)
609 : {
610 32 : if (debug)
611 0 : fputs (" Reiterating\n", stderr);
612 32 : node = _ksba_asn_insert_copy (node);
613 64 : if (node)
614 32 : prepare_copied_tree (node);
615 : }
616 : else
617 53 : node = node->down;
618 : }
619 : else /* constructed */
620 : {
621 144 : if (debug)
622 : {
623 0 : fprintf (stderr, " prepare for constructed (%d %d) ",
624 : ds->cur.length, ds->cur.nread);
625 0 : fprintf (stderr, " cur: ("); _ksba_asn_node_dump (node, stderr);
626 0 : fprintf (stderr, ")\n");
627 0 : if (ds->cur.node->flags.in_array)
628 0 : fputs (" This is in an array!\n", stderr);
629 0 : if (ds->cur.went_up)
630 0 : fputs (" And we are going up!\n", stderr);
631 : }
632 144 : ds->cur.in_seq_of = 0;
633 :
634 144 : if (ds->cur.node->flags.in_array
635 78 : && ds->cur.went_up)
636 : {
637 17 : if (debug)
638 0 : fputs (" Reiterating this\n", stderr);
639 17 : node = _ksba_asn_insert_copy (node);
640 34 : if (node)
641 17 : prepare_copied_tree (node);
642 : }
643 127 : else if (ds->cur.went_up || ds->cur.next_tag || ds->cur.node->flags.skip_this)
644 : {
645 54 : if (node->right)
646 27 : node = node->right;
647 : else
648 : {
649 : for (;;)
650 : {
651 0 : while (node->left && node->left->right == node)
652 0 : node = node->left;
653 0 : node = node->left; /* this is the up pointer */
654 0 : if (!node)
655 0 : break;
656 0 : if (node->right)
657 : {
658 0 : node = node->right;
659 0 : break;
660 : }
661 0 : }
662 : }
663 : }
664 : else
665 100 : node = node->down;
666 :
667 : }
668 344 : if (!node)
669 1 : return -1;
670 343 : ds->cur.node = node;
671 343 : ds->cur.went_up = 0;
672 343 : ds->cur.next_tag = 0;
673 :
674 343 : if (debug)
675 : {
676 0 : fprintf (stderr, " Expect ("); _ksba_asn_node_dump (node,stderr); fprintf (stderr, ")\n");
677 : }
678 :
679 343 : if (node->flags.skip_this)
680 : {
681 3 : if (debug)
682 0 : fprintf (stderr, " skipping this\n");
683 3 : return 1;
684 : }
685 :
686 340 : if (node->type == TYPE_SIZE)
687 : {
688 0 : if (debug)
689 0 : fprintf (stderr, " skipping size tag\n");
690 0 : return 1;
691 : }
692 340 : if (node->type == TYPE_DEFAULT)
693 : {
694 3 : if (debug)
695 0 : fprintf (stderr, " skipping default tag\n");
696 3 : return 1;
697 : }
698 :
699 337 : if (node->flags.is_implicit)
700 : {
701 0 : if (debug)
702 0 : fprintf (stderr, " dummy accept for implicit tag\n");
703 0 : return 1; /* again */
704 : }
705 :
706 337 : if ( (rc=cmp_tag (node, ti)))
707 : {
708 301 : *retnode = node;
709 301 : return rc==2? 4:3;
710 : }
711 :
712 36 : if (node->type == TYPE_CHOICE)
713 : {
714 12 : if (debug)
715 0 : fprintf (stderr, " testing choice...\n");
716 12 : for (node = node->down; node; node = node->right)
717 : {
718 12 : if (debug)
719 : {
720 0 : fprintf (stderr, " %s (", node->flags.skip_this? "skip":" cmp");
721 0 : _ksba_asn_node_dump (node, stderr);
722 0 : fprintf (stderr, ")\n");
723 : }
724 :
725 12 : if (!node->flags.skip_this && cmp_tag (node, ti) == 1)
726 : {
727 12 : if (debug)
728 : {
729 0 : fprintf (stderr, " choice match <"); dump_tlv (ti, stderr);
730 0 : fprintf (stderr, ">\n");
731 : }
732 : /* mark the remaining as done */
733 18 : for (node=node->right; node; node = node->right)
734 6 : node->flags.skip_this = 1;
735 12 : return 1;
736 : }
737 0 : node->flags.skip_this = 1;
738 :
739 : }
740 0 : node = ds->cur.node; /* reset */
741 : }
742 :
743 24 : if (node->flags.in_choice)
744 : {
745 0 : if (debug)
746 0 : fprintf (stderr, " skipping non matching choice\n");
747 0 : return 1;
748 : }
749 :
750 24 : if (node->flags.is_optional)
751 : {
752 6 : if (debug)
753 0 : fprintf (stderr, " skipping optional element\n");
754 6 : if (node->type == TYPE_TAG)
755 6 : ds->cur.next_tag = 1;
756 6 : return 1;
757 : }
758 :
759 18 : if (node->flags.has_default)
760 : {
761 18 : if (debug)
762 0 : fprintf (stderr, " use default value\n");
763 18 : if (node->type == TYPE_TAG)
764 0 : ds->cur.next_tag = 1;
765 18 : *retnode = node;
766 18 : return 2;
767 : }
768 :
769 0 : return -1;
770 : }
771 :
772 :
773 : static gpg_error_t
774 9 : decoder_init (BerDecoder d, const char *start_name)
775 : {
776 9 : d->ds = new_decoder_state ();
777 :
778 9 : d->root = _ksba_asn_expand_tree (d->module, start_name);
779 9 : clear_help_flags (d->root);
780 9 : d->bypass = 0;
781 9 : if (d->debug)
782 0 : fprintf (stderr, "DECODER_INIT for `%s'\n", start_name? start_name: "[root]");
783 9 : return 0;
784 : }
785 :
786 : static void
787 9 : decoder_deinit (BerDecoder d)
788 : {
789 9 : release_decoder_state (d->ds);
790 9 : d->ds = NULL;
791 9 : d->val.node = NULL;
792 9 : if (d->debug)
793 0 : fprintf (stderr, "DECODER_DEINIT\n");
794 9 : }
795 :
796 :
797 : static gpg_error_t
798 310 : decoder_next (BerDecoder d)
799 : {
800 : struct tag_info ti;
801 310 : AsnNode node = NULL;
802 : gpg_error_t err;
803 310 : DECODER_STATE ds = d->ds;
804 310 : int debug = d->debug;
805 :
806 310 : if (d->ignore_garbage && d->fast_stop)
807 : {
808 : /* I am not anymore sure why we have this ignore_garbage
809 : machinery: The whole decoder needs and overhaul; it seems not
810 : to honor the length specification and runs for longer than
811 : expected.
812 :
813 : This here is another hack to not eat up an end tag - this is
814 : required in in some cases and in theory should be used always
815 : but we want to avoid any regression, thus this flag. */
816 0 : return gpg_error (GPG_ERR_EOF);
817 : }
818 :
819 310 : err = _ksba_ber_read_tl (d->reader, &ti);
820 310 : if (err)
821 : {
822 8 : if (debug)
823 0 : fprintf (stderr, "ber_read_tl error: %s (%s)\n",
824 0 : gpg_strerror (err), ti.err_string? ti.err_string:"");
825 : /* This is our actual hack to cope with some trailing garbage:
826 : Only if we get an premature EOF and we know that we have read
827 : the complete certificate we change the error to EOF. This
828 : won't help with all kinds of garbage but it fixes the case
829 : where just one byte is appended. This is for example the
830 : case with current Siemens certificates. This approach seems
831 : to be the least intrusive one. */
832 8 : if (gpg_err_code (err) == GPG_ERR_BAD_BER
833 0 : && d->ignore_garbage
834 0 : && ti.err_string && !strcmp (ti.err_string, "premature EOF"))
835 0 : err = gpg_error (GPG_ERR_EOF);
836 8 : return err;
837 : }
838 :
839 302 : if (debug)
840 : {
841 0 : fprintf (stderr, "ReadTLV <");
842 0 : dump_tlv (&ti, stderr);
843 0 : fprintf (stderr, ">\n");
844 : }
845 :
846 : /* Check whether the trailing garbage hack is required. */
847 302 : if (!d->first_tag_seen)
848 : {
849 6 : d->first_tag_seen = 1;
850 6 : if (ti.tag == TYPE_SEQUENCE && ti.length && !ti.ndef)
851 6 : d->outer_sequence_length = ti.length;
852 : }
853 :
854 : /* Store stuff in the image buffer. */
855 302 : if (d->use_image)
856 : {
857 302 : if (!d->image.buf)
858 : {
859 : /* We need some extra bytes to store the stuff we read ahead
860 : at the end of the module which is later pushed back. */
861 6 : d->image.used = 0;
862 6 : d->image.length = ti.length + 100;
863 6 : if (d->image.length < ti.length)
864 0 : return gpg_error (GPG_ERR_BAD_BER);
865 6 : d->image.buf = xtrymalloc (d->image.length);
866 6 : if (!d->image.buf)
867 0 : return gpg_error (GPG_ERR_ENOMEM);
868 : }
869 :
870 302 : if (sum_a1_a2_ge_b (ti.nhdr, d->image.used, d->image.length))
871 0 : return set_error (d, NULL, "image buffer too short to store the tag");
872 :
873 302 : memcpy (d->image.buf + d->image.used, ti.buf, ti.nhdr);
874 302 : d->image.used += ti.nhdr;
875 : }
876 :
877 :
878 302 : if (!d->bypass)
879 : {
880 : int again, endtag;
881 :
882 : do
883 : {
884 344 : again = endtag = 0;
885 688 : switch ( ds->cur.in_any? 4
886 1020 : : (ti.class == CLASS_UNIVERSAL && !ti.tag)? (endtag=1,5)
887 344 : : match_der (d->root, &ti, ds, &node, debug))
888 : {
889 : case -1:
890 1 : if (debug)
891 : {
892 0 : fprintf (stderr, " FAIL <");
893 0 : dump_tlv (&ti, stderr);
894 0 : fprintf (stderr, ">\n");
895 : }
896 1 : if (d->honor_module_end)
897 : {
898 : /* We must push back the stuff we already read */
899 1 : ksba_reader_unread (d->reader, ti.buf, ti.nhdr);
900 1 : return gpg_error (GPG_ERR_EOF);
901 : }
902 : else
903 0 : d->bypass = 1;
904 0 : break;
905 : case 0:
906 0 : if (debug)
907 0 : fputs (" End of description\n", stderr);
908 0 : d->bypass = 1;
909 0 : break;
910 : case 1: /* again */
911 24 : if (debug)
912 0 : fprintf (stderr, " Again\n");
913 24 : again = 1;
914 24 : break;
915 : case 2: /* Use default value + again */
916 18 : if (debug)
917 0 : fprintf (stderr, " Using default\n");
918 18 : again = 1;
919 18 : break;
920 : case 4: /* Match of ANY on a constructed type */
921 0 : if (debug)
922 0 : fprintf (stderr, " ANY");
923 0 : ds->cur.in_any = 1;
924 : case 3: /* match */
925 : case 5: /* end tag */
926 301 : if (debug)
927 : {
928 0 : fprintf (stderr, " Match <");
929 0 : dump_tlv (&ti, stderr);
930 0 : fprintf (stderr, ">\n");
931 : }
932 : /* Increment by the header length */
933 301 : ds->cur.nread += ti.nhdr;
934 :
935 301 : if (!ti.is_constructed)
936 160 : ds->cur.nread += ti.length;
937 :
938 301 : ds->cur.went_up = 0;
939 : do
940 : {
941 360 : if (debug)
942 0 : fprintf (stderr, " (length %d nread %d) %s\n",
943 0 : ds->idx? ds->stack[ds->idx-1].length:-1,
944 : ds->cur.nread,
945 0 : ti.is_constructed? "con":"pri");
946 360 : if (d->outer_sequence_length
947 360 : && ds->idx == 1
948 23 : && ds->cur.nread == d->outer_sequence_length)
949 : {
950 6 : if (debug)
951 0 : fprintf (stderr, " Need to stop now\n");
952 6 : d->ignore_garbage = 1;
953 : }
954 :
955 360 : if ( ds->idx
956 354 : && !ds->stack[ds->idx-1].ndef_length
957 708 : && (ds->cur.nread
958 354 : > ds->stack[ds->idx-1].length))
959 : {
960 0 : fprintf (stderr, "ksba: ERROR: object length field "
961 : "%d octects too large\n",
962 0 : ds->cur.nread - ds->cur.length);
963 0 : ds->cur.nread = ds->cur.length;
964 : }
965 360 : if ( ds->idx
966 354 : && (endtag
967 354 : || (!ds->stack[ds->idx-1].ndef_length
968 708 : && (ds->cur.nread
969 354 : >= ds->stack[ds->idx-1].length))))
970 : {
971 141 : int n = ds->cur.nread;
972 141 : err = pop_decoder_state (ds);
973 141 : if (err)
974 0 : return err;
975 141 : ds->cur.nread += n;
976 141 : ds->cur.went_up++;
977 : }
978 360 : endtag = 0;
979 : }
980 360 : while ( ds->idx
981 348 : && !ds->stack[ds->idx-1].ndef_length
982 696 : && (ds->cur.nread
983 708 : >= ds->stack[ds->idx-1].length));
984 :
985 301 : if (ti.is_constructed && (ti.length || ti.ndef))
986 : {
987 : /* prepare for the next level */
988 141 : ds->cur.length = ti.length;
989 141 : ds->cur.ndef_length = ti.ndef;
990 141 : err = push_decoder_state (ds);
991 141 : if (err)
992 0 : return err;
993 141 : ds->cur.length = 0;
994 141 : ds->cur.ndef_length = 0;
995 141 : ds->cur.nread = 0;
996 : }
997 301 : if (debug)
998 0 : fprintf (stderr, " (length %d nread %d) end\n",
999 0 : ds->idx? ds->stack[ds->idx-1].length:-1,
1000 : ds->cur.nread);
1001 301 : break;
1002 : default:
1003 0 : never_reached ();
1004 0 : abort ();
1005 : break;
1006 : }
1007 : }
1008 343 : while (again);
1009 : }
1010 :
1011 301 : d->val.primitive = !ti.is_constructed;
1012 301 : d->val.length = ti.length;
1013 301 : d->val.nhdr = ti.nhdr;
1014 301 : d->val.tag = ti.tag; /* kludge to fix TYPE_ANY probs */
1015 301 : d->val.is_endtag = (ti.class == CLASS_UNIVERSAL && !ti.tag);
1016 301 : d->val.node = d->bypass? NULL : node;
1017 301 : if (debug)
1018 0 : dump_decoder_state (ds);
1019 :
1020 301 : return 0;
1021 : }
1022 :
1023 : static gpg_error_t
1024 0 : decoder_skip (BerDecoder d)
1025 : {
1026 0 : if (d->val.primitive)
1027 : {
1028 0 : if (read_buffer (d->reader, NULL, d->val.length))
1029 0 : return eof_or_error (d, 1);
1030 : }
1031 0 : return 0;
1032 : }
1033 :
1034 :
1035 :
1036 : /* Calculate the distance between the 2 nodes */
1037 : static int
1038 0 : distance (AsnNode root, AsnNode node)
1039 : {
1040 0 : int n=0;
1041 :
1042 0 : while (node && node != root)
1043 : {
1044 0 : while (node->left && node->left->right == node)
1045 0 : node = node->left;
1046 0 : node = node->left;
1047 0 : n++;
1048 : }
1049 :
1050 0 : return n;
1051 : }
1052 :
1053 :
1054 : /**
1055 : * _ksba_ber_decoder_dump:
1056 : * @d: Decoder object
1057 : *
1058 : * Dump a textual representation of the encoding to the given stream.
1059 : *
1060 : * Return value:
1061 : **/
1062 : gpg_error_t
1063 0 : _ksba_ber_decoder_dump (BerDecoder d, FILE *fp)
1064 : {
1065 : gpg_error_t err;
1066 0 : int depth = 0;
1067 : AsnNode node;
1068 0 : unsigned char *buf = NULL;
1069 0 : size_t buflen = 0;
1070 :
1071 0 : if (!d)
1072 0 : return gpg_error (GPG_ERR_INV_VALUE);
1073 :
1074 : #ifdef HAVE_GETENV
1075 0 : d->debug = !!getenv("KSBA_DEBUG_BER_DECODER");
1076 : #else
1077 : d->debug = 0;
1078 : #endif
1079 0 : d->use_image = 0;
1080 0 : d->image.buf = NULL;
1081 0 : err = decoder_init (d, NULL);
1082 0 : if (err)
1083 0 : return err;
1084 :
1085 0 : while (!(err = decoder_next (d)))
1086 : {
1087 0 : node = d->val.node;
1088 0 : if (node)
1089 0 : depth = distance (d->root, node);
1090 :
1091 0 : fprintf (fp, "%4lu %4lu:%*s",
1092 0 : ksba_reader_tell (d->reader) - d->val.nhdr,
1093 : (unsigned long)d->val.length,
1094 : depth*2, "");
1095 0 : if (node)
1096 0 : _ksba_asn_node_dump (node, fp);
1097 : else
1098 0 : fputs ("[No matching node]", fp);
1099 :
1100 0 : if (node && d->val.primitive)
1101 0 : {
1102 : size_t n;
1103 : int i, c;
1104 : char *p;
1105 :
1106 0 : if (!buf || buflen < d->val.length)
1107 : {
1108 0 : xfree (buf);
1109 0 : buflen = d->val.length + 100;
1110 0 : if (buflen < d->val.length)
1111 0 : err = gpg_error (GPG_ERR_BAD_BER); /* Overflow */
1112 : else
1113 : {
1114 0 : buf = xtrymalloc (buflen);
1115 0 : if (!buf)
1116 0 : err = gpg_error_from_syserror ();
1117 : }
1118 : }
1119 :
1120 0 : for (n=0; !err && n < d->val.length; n++)
1121 : {
1122 0 : if ( (c=read_byte (d->reader)) == -1)
1123 0 : err = eof_or_error (d, 1);
1124 0 : buf[n] = c;
1125 : }
1126 0 : if (err)
1127 0 : break;
1128 0 : fputs (" (", fp);
1129 0 : p = NULL;
1130 0 : switch (node->type)
1131 : {
1132 : case TYPE_OBJECT_ID:
1133 0 : p = ksba_oid_to_str (buf, n);
1134 0 : break;
1135 : default:
1136 0 : for (i=0; i < n && i < 20; i++)
1137 0 : fprintf (fp,"%02x", buf[i]);
1138 0 : if (i < n)
1139 0 : fputs ("..more..", fp);
1140 0 : break;
1141 : }
1142 0 : if (p)
1143 : {
1144 0 : fputs (p, fp);
1145 0 : xfree (p);
1146 : }
1147 0 : fputs (")\n", fp);
1148 : }
1149 : else
1150 : {
1151 0 : err = decoder_skip (d);
1152 0 : putc ('\n', fp);
1153 : }
1154 0 : if (err)
1155 0 : break;
1156 :
1157 : }
1158 0 : if (gpg_err_code (err) == GPG_ERR_EOF)
1159 0 : err = 0;
1160 :
1161 0 : decoder_deinit (d);
1162 0 : xfree (buf);
1163 0 : return err;
1164 : }
1165 :
1166 :
1167 :
1168 :
1169 : gpg_error_t
1170 9 : _ksba_ber_decoder_decode (BerDecoder d, const char *start_name,
1171 : unsigned int flags,
1172 : AsnNode *r_root,
1173 : unsigned char **r_image, size_t *r_imagelen)
1174 : {
1175 : gpg_error_t err;
1176 : AsnNode node;
1177 9 : unsigned char *buf = NULL;
1178 9 : size_t buflen = 0;
1179 : unsigned long startoff;
1180 :
1181 9 : if (!d)
1182 0 : return gpg_error (GPG_ERR_INV_VALUE);
1183 :
1184 9 : if (r_root)
1185 9 : *r_root = NULL;
1186 :
1187 : #ifdef HAVE_GETENV
1188 9 : d->debug = !!getenv("KSBA_DEBUG_BER_DECODER");
1189 : #else
1190 : d->debug = 0;
1191 : #endif
1192 9 : d->honor_module_end = 1;
1193 9 : d->use_image = 1;
1194 9 : d->image.buf = NULL;
1195 9 : d->fast_stop = !!(flags & BER_DECODER_FLAG_FAST_STOP);
1196 :
1197 9 : startoff = ksba_reader_tell (d->reader);
1198 :
1199 9 : err = decoder_init (d, start_name);
1200 9 : if (err)
1201 0 : return err;
1202 :
1203 319 : while (!(err = decoder_next (d)))
1204 : {
1205 301 : node = d->val.node;
1206 : /* Fixme: USE_IMAGE is only not used with the ber-dump utility
1207 : and thus of no big use. We should remove the other code
1208 : paths and dump ber-dump.c. */
1209 301 : if (d->use_image)
1210 : {
1211 301 : if (node && !d->val.is_endtag)
1212 : { /* We don't have nodes for the end tag - so don't store it */
1213 602 : node->off = (ksba_reader_tell (d->reader)
1214 301 : - d->val.nhdr - startoff);
1215 301 : node->nhdr = d->val.nhdr;
1216 301 : node->len = d->val.length;
1217 301 : if (node->type == TYPE_ANY)
1218 50 : node->actual_type = d->val.tag;
1219 : }
1220 301 : if (sum_a1_a2_gt_b (d->image.used, d->val.length, d->image.length))
1221 0 : err = set_error(d, NULL, "TLV length too large");
1222 301 : else if (d->val.primitive)
1223 : {
1224 320 : if( read_buffer (d->reader,
1225 160 : d->image.buf + d->image.used, d->val.length))
1226 0 : err = eof_or_error (d, 1);
1227 : else
1228 : {
1229 160 : size_t sum = d->image.used + d->val.length;
1230 160 : if (sum < d->image.used)
1231 0 : err = gpg_error (GPG_ERR_BAD_BER);
1232 : else
1233 160 : d->image.used = sum;
1234 : }
1235 : }
1236 : }
1237 0 : else if (node && d->val.primitive)
1238 0 : {
1239 : size_t n;
1240 : int c;
1241 :
1242 0 : if (!buf || buflen < d->val.length)
1243 : {
1244 0 : xfree (buf);
1245 0 : buflen = d->val.length + 100;
1246 0 : if (buflen < d->val.length)
1247 0 : err = gpg_error (GPG_ERR_BAD_BER);
1248 : else
1249 : {
1250 0 : buf = xtrymalloc (buflen);
1251 0 : if (!buf)
1252 0 : err = gpg_error_from_syserror ();
1253 : }
1254 : }
1255 :
1256 0 : for (n=0; !err && n < d->val.length; n++)
1257 : {
1258 0 : if ( (c=read_byte (d->reader)) == -1)
1259 0 : err = eof_or_error (d, 1);
1260 0 : buf[n] = c;
1261 : }
1262 0 : if (err)
1263 0 : break;
1264 :
1265 0 : switch (node->type)
1266 : {
1267 : default:
1268 0 : _ksba_asn_set_value (node, VALTYPE_MEM, buf, n);
1269 0 : break;
1270 : }
1271 : }
1272 : else
1273 : {
1274 0 : err = decoder_skip (d);
1275 : }
1276 301 : if (err)
1277 0 : break;
1278 : }
1279 9 : if (gpg_err_code (err) == GPG_ERR_EOF)
1280 9 : err = 0;
1281 :
1282 9 : if (err)
1283 0 : xfree (d->image.buf);
1284 :
1285 9 : if (r_root && !err)
1286 : {
1287 9 : if (!d->image.buf)
1288 : { /* Not even the first node available - return eof */
1289 3 : _ksba_asn_release_nodes (d->root);
1290 3 : d->root = NULL;
1291 3 : err = gpg_error (GPG_ERR_EOF);
1292 : }
1293 :
1294 9 : fixup_type_any (d->root);
1295 9 : *r_root = d->root;
1296 9 : d->root = NULL;
1297 9 : *r_image = d->image.buf;
1298 9 : d->image.buf = NULL;
1299 9 : *r_imagelen = d->image.used;
1300 9 : if (d->debug)
1301 : {
1302 0 : fputs ("Value Tree:\n", stderr);
1303 0 : _ksba_asn_node_dump_all (*r_root, stderr);
1304 : }
1305 : }
1306 :
1307 9 : decoder_deinit (d);
1308 9 : xfree (buf);
1309 9 : return err;
1310 : }
|