[svn] ksba - r318 - in trunk: . src tests

svn author wk cvs at cvs.gnupg.org
Thu Jul 15 19:53:04 CEST 2010


Author: wk
Date: 2010-07-15 19:53:02 +0200 (Thu, 15 Jul 2010)
New Revision: 318

Modified:
   trunk/NEWS
   trunk/src/ChangeLog
   trunk/src/ber-decoder.c
   trunk/src/ber-decoder.h
   trunk/src/cert.c
   trunk/src/cms-parser.c
   trunk/src/crl.c
   trunk/src/dn.c
   trunk/tests/ChangeLog
   trunk/tests/t-cms-parser.c
Log:
Fixed parsing bug.


Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/src/ChangeLog	2010-07-15 17:53:02 UTC (rev 318)
@@ -1,3 +1,13 @@
+2010-07-15  Werner Koch  <wk at g10code.com>
+
+	* cms-parser.c (create_and_run_decoder): Add arg flags.
+	(_ksba_cms_parse_enveloped_data_part_1): Handle NDEF recipientInfo
+	sets.
+
+	* ber-decoder.h (BER_DECODER_FLAG_FAST_STOP): New.
+	* ber-decoder.c (_ksba_ber_decoder_decode): Add arg FLAGS.
+	(decoder_next): Implement fast stop hack.
+
 2010-05-06  Werner Koch  <wk at g10code.com>
 
 	* gen-help.c, gen-help.h: New.

Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/tests/ChangeLog	2010-07-15 17:53:02 UTC (rev 318)
@@ -1,3 +1,8 @@
+2010-07-15  Werner Koch  <wk at g10code.com>
+
+	* t-cms-parser.c (dummy_writer_cb): New.
+	(one_file): Use the dummy writer.
+
 2010-01-22  Werner Koch  <wk at g10code.com>
 
 	* cert-basic.c (getenv) [__MINGW32CE__]: Add dummy.

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/NEWS	2010-07-15 17:53:02 UTC (rev 318)
@@ -3,9 +3,11 @@
 
  * Support for WindowsCE.
 
- * Builds cleaning from SVN even when cross-compiling.
+ * Builds cleanly from SVN even when cross-compiling.
 
+ * Fixed a CMS parsing bug exhibited by Lotus Notes.
 
+
 Noteworthy changes in version 1.0.7 (2009-07-03)
 ------------------------------------------------
 

Modified: trunk/src/ber-decoder.c
===================================================================
--- trunk/src/ber-decoder.c	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/src/ber-decoder.c	2010-07-15 17:53:02 UTC (rev 318)
@@ -68,10 +68,11 @@
      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. */
+     activated. */
   unsigned long outer_sequence_length;
-  int ignore_garbage;  /* Set to indicate that garpage should be
+  int ignore_garbage;  /* Set to indicate that garbage should be
                           ignored. */
+  int fast_stop;       /* Yet another hack.  */
 
   int first_tag_seen;  /* Indicates whether the first tag of a decoder
                           run has been read. */
@@ -596,7 +597,7 @@
           if (ds->cur.node->flags.in_array)
             fputs ("  This is in an array!\n", stderr);
           if (ds->cur.went_up)
-            fputs ("  And we going up!\n", stderr);
+            fputs ("  And we are going up!\n", stderr);
         }
       ds->cur.in_seq_of = 0;
 
@@ -772,6 +773,19 @@
   DECODER_STATE ds = d->ds;
   int debug = d->debug;
 
+  if (d->ignore_garbage && d->fast_stop)
+    {
+      /* I am not anymore sure why we have this ignore_garbage
+         machinery: The whole decoder needs and overhaul; it seems not
+         to honor the length specification and runs for longer than
+         expected. 
+
+         This here is another hack to not eat up an end tag - this is
+         required in in some cases and in theory should be used always
+         but we want to avoid any regression, thus this flag.  */
+      return gpg_error (GPG_ERR_EOF);
+    }
+
   err = _ksba_ber_read_tl (d->reader, &ti);
   if (err)
     {
@@ -1112,6 +1126,7 @@
 
 gpg_error_t
 _ksba_ber_decoder_decode (BerDecoder d, const char *start_name,
+                          unsigned int flags,
                           AsnNode *r_root,
                           unsigned char **r_image, size_t *r_imagelen)
 {
@@ -1135,6 +1150,7 @@
   d->honor_module_end = 1;
   d->use_image = 1;
   d->image.buf = NULL;
+  d->fast_stop = !!(flags & BER_DECODER_FLAG_FAST_STOP);
 
   startoff = ksba_reader_tell (d->reader);
 

Modified: trunk/src/ber-decoder.h
===================================================================
--- trunk/src/ber-decoder.h	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/src/ber-decoder.h	2010-07-15 17:53:02 UTC (rev 318)
@@ -33,10 +33,12 @@
 
 gpg_error_t _ksba_ber_decoder_dump (BerDecoder d, FILE *fp);
 gpg_error_t _ksba_ber_decoder_decode (BerDecoder d, const char *start_name,
+                                      unsigned int flags,
                                       AsnNode *r_root,
                                       unsigned char **r_image,
                                       size_t *r_imagelen);
 
+#define BER_DECODER_FLAG_FAST_STOP 1
 
 
 #endif /*BER_DECODER_H*/

Modified: trunk/src/cert.c
===================================================================
--- trunk/src/cert.c	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/src/cert.c	2010-07-15 17:53:02 UTC (rev 318)
@@ -288,7 +288,7 @@
   if (err)
      goto leave;
 
-  err = _ksba_ber_decoder_decode (decoder, "TMTTv2.Certificate",
+  err = _ksba_ber_decoder_decode (decoder, "TMTTv2.Certificate", 0,
                                   &cert->root, &cert->image, &cert->imagelen);
   if (!err)
       cert->initialized = 1;

Modified: trunk/src/cms-parser.c
===================================================================
--- trunk/src/cms-parser.c	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/src/cms-parser.c	2010-07-15 17:53:02 UTC (rev 318)
@@ -71,6 +71,7 @@
 /* Create a new decoder and run it for the given element */
 static gpg_error_t
 create_and_run_decoder (ksba_reader_t reader, const char *elem_name,
+                        unsigned int flags,
                         AsnNode *r_root,
                         unsigned char **r_image, size_t *r_imagelen)
 {
@@ -105,7 +106,7 @@
       return err;
     }
   
-  err = _ksba_ber_decoder_decode (decoder, elem_name,
+  err = _ksba_ber_decoder_decode (decoder, elem_name, flags,
                                   r_root, r_image, r_imagelen);
   
   _ksba_ber_decoder_release (decoder);
@@ -335,7 +336,7 @@
           return err;
         }
 
-      /* Note: the tag may eithe denote a constructed or a primitve
+      /* Note: the tag may either denote a constructed or a primitve
          object.  Actually this should match the use of NDEF header
          but we don't ceck that */
       if ( ti.class == CLASS_CONTEXT && ti.tag == 0 )
@@ -746,6 +747,7 @@
 
       err = create_and_run_decoder (cms->reader, 
                                     "CryptographicMessageSyntax.SignerInfo",
+                                    0,
                                     &si->root, &si->image, &si->imagelen);
       /* The signerInfo might be an empty set in the case of a certs-only
          signature.  Thus we have to allow for EOF here */
@@ -844,29 +846,74 @@
     return gpg_error (GPG_ERR_INV_CMS_OBJ); 
 
   vtend = &cms->recp_info;
-  while (ti.length)
+  if (ti.ndef)
     {
-      size_t off1, off2;
+      for (;;)
+        {
+          struct tag_info ti2;
 
-      off1 = ksba_reader_tell (cms->reader);
-      vt = xtrycalloc (1, sizeof *vt);
-      if (!vt)
-        return gpg_error (GPG_ERR_ENOMEM);
+          err = _ksba_ber_read_tl (cms->reader, &ti2);
+          if (err)
+            return err;
 
-      err = create_and_run_decoder (cms->reader,
-                                    "CryptographicMessageSyntax.KeyTransRecipientInfo",
-                                    &vt->root, &vt->image, &vt->imagelen);
-      if (err)
-        return err;
+          if (!ti2.class && !ti2.tag)
+            break; /* End tag found: ready.  */
 
-      *vtend = vt;
-      vtend = &vt->next;
+          /* Not an end tag:  Push it back and run the decoder.  */
+          err = ksba_reader_unread (cms->reader, ti2.buf, ti2.nhdr);
+          if (err)
+            return err;
+          
+          vt = xtrycalloc (1, sizeof *vt);
+          if (!vt)
+            return gpg_error_from_syserror ();
+          
+          err = create_and_run_decoder
+            (cms->reader,
+             "CryptographicMessageSyntax.KeyTransRecipientInfo",
+             BER_DECODER_FLAG_FAST_STOP,
+             &vt->root, &vt->image, &vt->imagelen);
+          if (err)
+            {
+              xfree (vt);
+              return err;
+            }
+          
+          *vtend = vt;
+          vtend = &vt->next;
+        }
+    }
+  else
+    {
+      while (ti.length)
+        {
+          size_t off1, off2;
+          
+          off1 = ksba_reader_tell (cms->reader);
+          vt = xtrycalloc (1, sizeof *vt);
+          if (!vt)
+            return gpg_error_from_syserror ();
+          
+          err = create_and_run_decoder
+            (cms->reader,
+             "CryptographicMessageSyntax.KeyTransRecipientInfo",
+             0,
+             &vt->root, &vt->image, &vt->imagelen);
+          if (err)
+            {
+              xfree (vt);
+              return err;
+            }
+          
+          *vtend = vt;
+          vtend = &vt->next;
 
-      off2 = ksba_reader_tell (cms->reader);
-      if ( (off2 - off1) > ti.length )
-        ti.length = 0;
-      else
-        ti.length -= off2 - off1;
+          off2 = ksba_reader_tell (cms->reader);
+          if ( (off2 - off1) > ti.length )
+            ti.length = 0;
+          else
+            ti.length -= off2 - off1;
+        }
     }
 
   /* Now for the encryptedContentInfo */

Modified: trunk/src/crl.c
===================================================================
--- trunk/src/crl.c	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/src/crl.c	2010-07-15 17:53:02 UTC (rev 318)
@@ -714,7 +714,7 @@
       return err;
     }
   
-  err = _ksba_ber_decoder_decode (decoder, elem_name,
+  err = _ksba_ber_decoder_decode (decoder, elem_name, 0,
                                   r_root, r_image, r_imagelen);
   
   _ksba_ber_decoder_release (decoder);

Modified: trunk/src/dn.c
===================================================================
--- trunk/src/dn.c	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/src/dn.c	2010-07-15 17:53:02 UTC (rev 318)
@@ -722,7 +722,7 @@
       return err;
     }
   
-  err = _ksba_ber_decoder_decode (decoder, elem_name,
+  err = _ksba_ber_decoder_decode (decoder, elem_name, 0,
                                   r_root, r_image, r_imagelen);
   
   _ksba_ber_decoder_release (decoder);

Modified: trunk/tests/t-cms-parser.c
===================================================================
--- trunk/tests/t-cms-parser.c	2010-05-06 12:29:31 UTC (rev 317)
+++ trunk/tests/t-cms-parser.c	2010-07-15 17:53:02 UTC (rev 318)
@@ -36,13 +36,24 @@
   (void)length;
 }
 
+static int
+dummy_writer_cb (void *cb_value, const void *buffer, size_t count)
+{
+  (void)cb_value;
+  (void)buffer;
+  (void)count;
+  return 0;
+}
 
+
+
 static void
 one_file (const char *fname)
 {
   gpg_error_t err;
   FILE *fp;
   ksba_reader_t r;
+  ksba_writer_t w;
   ksba_cms_t cms;
   int i;
   const char *algoid;
@@ -67,6 +78,13 @@
     fail_if_err (err);
   err = ksba_reader_set_file (r, fp);
   fail_if_err (err);
+  /* Also create a writer so that cms.c won't return an error when
+     writing processed content.  */
+  err = ksba_writer_new (&w);
+  if (err)
+    fail_if_err (err);
+  err = ksba_writer_set_cb (w, dummy_writer_cb, NULL);
+  fail_if_err (err);
 
   switch (ksba_cms_identify (r))
     {
@@ -84,7 +102,7 @@
   if (err)
     fail_if_err (err);
 
-  err = ksba_cms_set_reader_writer (cms, r, NULL);
+  err = ksba_cms_set_reader_writer (cms, r, w);
   fail_if_err (err);
 
   err = ksba_cms_parse (cms, &stopreason);





More information about the Gnupg-commits mailing list