LCOV - code coverage report
Current view: top level - src - ber-decoder.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 336 632 53.2 %
Date: 2016-12-01 18:28:20 Functions: 21 30 70.0 %

          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             : }

Generated by: LCOV version 1.11