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