Sophie

Sophie

distrib > Mandriva > 2006.0 > i586 > by-pkgid > 14f3ae5052a970556dbb2559da958d3d > files > 3

libksba-0.9.11-2.1.20060mdk.src.rpm

--- src/ber-decoder.c
+++ src/ber-decoder.c
@@ -61,6 +61,19 @@
   AsnNode root;   /* of the expanded parse tree */
   DECODER_STATE ds;
   int bypass;
+  
+  /* Because some certificates actually come with trailing garbage, we
+     use a hack to ignore this garbage.  This hack is enabled for data
+     starting with a fixed length sequence and this variable takes the
+     length of this sequence.  If it is 0, the hack is not
+     acticated. */
+  unsigned long outer_sequence_length;
+  int ignore_garbage;  /* Set to indicate that garpage should be
+                         ignored. */
+  int first_tag_seen;  /* Indicates whether the first tag of a decoder
+                          run has been read. */
+  
+  
   int honor_module_end; 
   int debug;
   int use_image;
@@ -750,7 +763,7 @@
 decoder_next (BerDecoder d)
 {
   struct tag_info ti;
-  AsnNode node;
+  AsnNode node=NULL;
   gpg_error_t err;
   DECODER_STATE ds = d->ds;
   int debug = d->debug;
@@ -758,6 +771,17 @@
   err = _ksba_ber_read_tl (d->reader, &ti);
   if (err)
     {
+      /* This is our actual hack to cope with some trailing garbage:
+         Only if we get an premature EOF and we know that we have read
+         the complete certificate we change the error to EOF.  This
+         won't help with all kinds of garbage but it fixes the case
+         where just one byte is appended.  This is for example the
+         case with current Siemens certificates.  This approach seems
+         to be the least intrusive one. */
+      if (gpg_err_code (err) == GPG_ERR_BAD_BER
+          && d->ignore_garbage
+          && ti.err_string && !strcmp (ti.err_string, "premature EOF"))
+        err = gpg_error (GPG_ERR_EOF);
       return err;
     }
 
@@ -770,8 +794,8 @@
     {
       if (!d->image.buf)
         {
-          /* we need some extra bytes to store the stuff we read ahead
-             at the end of the module which is later pushed back */
+          /* We need some extra bytes to store the stuff we read ahead
+             at the end of the module which is later pushed back. */
           d->image.length = ti.length + 100;
           d->image.used = 0;
           d->image.buf = xtrymalloc (d->image.length);
@@ -850,7 +874,14 @@
                             ds->idx? ds->stack[ds->idx-1].length:-1,
                             ds->cur.nread,
                             ti.is_constructed? "con":"pri");
-
+                  if (d->outer_sequence_length
+                      && ds->idx == 1
+                      && ds->cur.nread == d->outer_sequence_length)
+                  {
+                    if (debug)
+                      fprintf (stderr, "  Need to stop now\n");
+                    d->ignore_garbage = 1;
+                  }
                   if ( ds->idx
                        && !ds->stack[ds->idx-1].ndef_length
                        && (ds->cur.nread
@@ -879,7 +910,7 @@
                       && (ds->cur.nread
                           >= ds->stack[ds->idx-1].length));
                   
-              if (ti.is_constructed)
+              if (ti.is_constructed && (ti.length || ti.ndef))
                 {
                   /* prepare for the next level */
                   ds->cur.length = ti.length;
@@ -1084,9 +1115,12 @@
       int n, c;
 
       node = d->val.node;
-      if (node && d->use_image)
+      /* Fixme: USE_IMAGE is only not used with the ber-dump utility
+         and thus of no big use.  We should remove the other code
+         paths and dump ber-dump.c. */
+      if (d->use_image)
         {
-          if (!d->val.is_endtag)
+          if (node && !d->val.is_endtag)
             { /* We don't have nodes for the end tag - so don't store it */
               node->off = (ksba_reader_tell (d->reader)
                            - d->val.nhdr - startoff);