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

Generated by: LCOV version 1.11