[git] GnuPG - branch, master, updated. gnupg-2.1.0-beta442-17-g74c7ab5

by Werner Koch cvs at cvs.gnupg.org
Tue Jun 24 13:46:40 CEST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  74c7ab5fa636c7721dd7529d5bbfce70a47e5550 (commit)
       via  6295b6675ebd3385c6d173690fdab6df6c31d3d8 (commit)
       via  dce1dad23dba1936e6b17bec548f4307e4f39cf1 (commit)
       via  2c8e00137a340d04f0836f75e138dd85f8c9eff7 (commit)
       via  f4fcaa29367daacfe0ca209fa83dfa8640ace276 (commit)
       via  d6ca407a27877174c10adfae9dc601bea996cf27 (commit)
      from  3f17b74aa57ac1ea2f3aa93dec4889778a21afeb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 74c7ab5fa636c7721dd7529d5bbfce70a47e5550
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jun 24 13:46:52 2014 +0200

    doc: Add note regarding gpg-preset-passphrase and --max-cache-ttl.
    
    --
    GnuPG-bug-id: 1615

diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index bfb1d93..c3dfd82 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -372,13 +372,16 @@ seconds.  The default is 1800 seconds.
 @opindex max-cache-ttl
 Set the maximum time a cache entry is valid to @var{n} seconds.  After
 this time a cache entry will be expired even if it has been accessed
-recently.  The default is 2 hours (7200 seconds).
+recently or has been set using @command{gpg-preset-passphrase}.  The
+default is 2 hours (7200 seconds).
 
 @item --max-cache-ttl-ssh @var{n}
 @opindex max-cache-ttl-ssh
-Set the maximum time a cache entry used for SSH keys is valid to @var{n}
-seconds.  After this time a cache entry will be expired even if it has
-been accessed recently.  The default is 2 hours (7200 seconds).
+Set the maximum time a cache entry used for SSH keys is valid to
+ at var{n} seconds.  After this time a cache entry will be expired even
+if it has been accessed recently or has been set using
+ at command{gpg-preset-passphrase}.  The default is 2 hours (7200
+seconds).
 
 @item --enforce-passphrase-constraints
 @opindex enforce-passphrase-constraints
diff --git a/doc/tools.texi b/doc/tools.texi
index 32ab1e4..030f269 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -1060,10 +1060,11 @@ may not be used and the passphrases for the to be used keys are given at
 machine startup.
 
 Passphrases set with this utility don't expire unless the
- at option{--forget} option is used to explicitly clear them from the cache
---- or @command{gpg-agent} is either restarted or reloaded (by sending a
-SIGHUP to it).  It is necessary to allow this passphrase presetting by
-starting @command{gpg-agent} with the
+ at option{--forget} option is used to explicitly clear them from the
+cache --- or @command{gpg-agent} is either restarted or reloaded (by
+sending a SIGHUP to it).  Nite that the maximum cache time as set with
+ at option{--max-cache-ttl} is still honored.  It is necessary to allow
+this passphrase presetting by starting @command{gpg-agent} with the
 @option{--allow-preset-passphrase}.
 
 @menu

commit 6295b6675ebd3385c6d173690fdab6df6c31d3d8
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jun 24 12:21:54 2014 +0200

    doc: Improve the description of gpg's --export commands.
    
    --
    GnuPG-bug-id: 1655

diff --git a/doc/gpg.texi b/doc/gpg.texi
index 101f51e..9a6782a 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -408,8 +408,8 @@ removed first. In batch mode the key must be specified by fingerprint.
 @opindex export
 Either export all keys from all keyrings (default keyrings and those
 registered via option @option{--keyring}), or if at least one name is given,
-those of the given name. The new keyring is written to STDOUT or to the
-file given with option @option{--output}. Use together with
+those of the given name. The exported keys are written to STDOUT or to the
+file given with option @option{--output}.  Use together with
 @option{--armor} to mail those keys.
 
 @item --send-keys @code{key IDs}
@@ -424,14 +424,30 @@ or changed by you.  If no key IDs are given, @command{gpg} does nothing.
 @itemx --export-secret-subkeys
 @opindex export-secret-keys
 @opindex export-secret-subkeys
-Same as @option{--export}, but exports the secret keys instead.  This is
-normally not very useful and a security risk.  The second form of the
-command has the special property to render the secret part of the
-primary key useless; this is a GNU extension to OpenPGP and other
-implementations can not be expected to successfully import such a key.
+Same as @option{--export}, but exports the secret keys instead.  The
+exported keys are written to STDOUT or to the file given with option
+ at option{--output}.  This command is often used along with the option
+ at option{--armor} to allow easy printing of the key for paper backup;
+however the external tool @command{paperkey} does a better job for
+creating backups on paper.  Note that exporting a secret key can be a
+security risk if the exported keys are send over an insecure channel.
+
+The second form of the command has the special property to render the
+secret part of the primary key useless; this is a GNU extension to
+OpenPGP and other implementations can not be expected to successfully
+import such a key.  Its intended use is to generated a full key with
+an additional signing subkey on a dedicated machine and then using
+this command to export the key without the primary key to the main
+machine.
+
+ at ifset gpgtwoone
+GnuPG may ask you to enter the passphrase for the key.  This is
+required because the internal protection method of the secret key is
+different from the one specified by the OpenPGP protocol.
+ at end ifset
 @ifclear gpgtwoone
-See the option @option{--simple-sk-checksum} if you want to import such
-an exported key with an older OpenPGP implementation.
+See the option @option{--simple-sk-checksum} if you want to import an
+exported secret key into ancient OpenPGP implementations.
 @end ifclear
 
 @item --import

commit dce1dad23dba1936e6b17bec548f4307e4f39cf1
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jun 24 11:47:51 2014 +0200

    Register DCO for Stefan Tomanek.
    
    --

diff --git a/AUTHORS b/AUTHORS
index f64d17f..8358faf 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -171,6 +171,9 @@ Jonas Borgström <jonas at borgstrom.se>
 Kyle Butt <kylebutt at gmail.com>
 2013-05-29:CAAODAYLbCtqOG6msLLL0UTdASKWT6u2ptxsgUQ1JpusBESBoNQ at mail.gmail.com:
 
+Stefan Tomanek <tomanek at internet-sicherheit.de>
+2014-01-30:20140129234449.GY30808 at zirkel.wertarbyte.de:
+
 Werner Koch <wk at gnupg.org>
 2013-03-29:87620ahchj.fsf at vigenere.g10code.de:
 

commit 2c8e00137a340d04f0836f75e138dd85f8c9eff7
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jun 23 16:09:34 2014 +0200

    doc: Add conditionals for GnuPG-1

diff --git a/doc/gpg.texi b/doc/gpg.texi
index c8fae3a..101f51e 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -2316,9 +2316,11 @@ available, but the MIT release is a good common baseline.
 
 This option implies @option{--rfc1991 --disable-mdc
 --no-force-v4-certs --escape-from-lines --force-v3-sigs
---allow-weak-digest-algos --cipher-algo IDEA --digest-algo
-MD5--compress-algo ZIP}. It also disables @option{--textmode} when
-encrypting.
+ at ifclear gpgone
+--allow-weak-digest-algos
+ at end ifclear
+--cipher-algo IDEA --digest-algo MD5 --compress-algo ZIP}.
+It also disables @option{--textmode} when encrypting.
 
 @item --pgp6
 @opindex pgp6
@@ -2774,12 +2776,13 @@ necessary to get as much data as possible out of the corrupt message.
 However, be aware that a MDC protection failure may also mean that the
 message was tampered with intentionally by an attacker.
 
+ at ifclear gpgone
 @item --allow-weak-digest-algos
 @opindex allow-weak-digest-algos
 Signatures made with the broken MD5 algorithm are normally rejected
 with an ``invalid digest algorithm'' message.  This option allows the
 verification of signatures made with such weak algorithms.
-
+ at end ifclear
 
 @item --no-default-keyring
 @opindex no-default-keyring

commit f4fcaa29367daacfe0ca209fa83dfa8640ace276
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Jun 20 14:54:01 2014 +0200

    gpg: Make export of ECC keys work again.
    
    * agent/cvt-openpgp.c (convert_to_openpgp): Use the curve name instead
    of the curve parameters.
    * g10/export.c (canon_pubkey_algo): Rename to ...
    (canon_pk_algo): this.  Support ECC.
    (transfer_format_to_openpgp): Expect curve name.

diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
index 7f4afd4..1b4c9d5 100644
--- a/agent/cvt-openpgp.c
+++ b/agent/cvt-openpgp.c
@@ -1142,6 +1142,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
   const char *algoname;
   int npkey, nskey;
   gcry_mpi_t array[10];
+  gcry_sexp_t curve = NULL;
   char protect_iv[16];
   char salt[8];
   unsigned long s2k_count;
@@ -1200,13 +1201,26 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
     }
   else if (!strcmp (name, "ecc"))
     {
-      /* FIXME: We need to use the curve parameter.  */
+      gcry_buffer_t iob;
+      char iobbuf[32];
+
       algoname = "ecc"; /* Decide later by checking the usage.  */
-      npkey = 6;
-      nskey = 7;
-      err = gcry_sexp_extract_param (list, NULL, "pabgnqd",
-                                     array+0, array+1, array+2, array+3,
-                                     array+4, array+5, array+6, NULL);
+      npkey = 1;
+      nskey = 2;
+      iob.data = iobbuf;
+      iob.size = sizeof iobbuf - 1;
+      iob.off = 0;
+      iob.len = 0;
+      err = gcry_sexp_extract_param (list, NULL, "&'curve'/qd",
+                                     &iob, array+0, array+1, NULL);
+      if (!err)
+        {
+          assert (iob.len < sizeof iobbuf -1);
+          iobbuf[iob.len] = 0;
+          err = gcry_sexp_build (&curve, NULL, "(curve %s)", iobbuf);
+
+          gcry_log_debugsxp ("at 1", curve);
+        }
     }
   else if (!strcmp (name, "ecdsa"))
     {
@@ -1231,9 +1245,12 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
     }
   xfree (name);
-  gcry_sexp_release (list);
+  gcry_sexp_release (list); list = NULL;
   if (err)
-    return err;
+    {
+      gcry_sexp_release (curve);
+      return err;
+    }
 
   gcry_create_nonce (protect_iv, sizeof protect_iv);
   gcry_create_nonce (salt, sizeof salt);
@@ -1282,9 +1299,10 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
                                "(openpgp-private-key\n"
                                " (version 1:4)\n"
                                " (algo %s)\n"
-                               " %S\n"
+                               " %S%S\n"
                                " (protection sha1 aes %b 1:3 sha1 %b %s))\n",
                                algoname,
+                               curve,
                                tmpkey,
                                (int)sizeof protect_iv, protect_iv,
                                (int)sizeof salt, salt,
@@ -1297,6 +1315,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
 
   for (i=0; i < DIM (array); i++)
     gcry_mpi_release (array[i]);
+  gcry_sexp_release (curve);
 
   return err;
 }
diff --git a/g10/export.c b/g10/export.c
index 9aa012e..acf38a7 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -1,6 +1,7 @@
 /* export.c - Export keys in the OpenPGP defined format.
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
  *               2005, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2014  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -338,8 +339,8 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
 /* Return a canonicalized public key algoithms.  This is used to
    compare different flavors of algorithms (e.g. ELG and ELG_E are
    considered the same).  */
-static int
-canon_pubkey_algo (int algo)
+static enum gcry_pk_algos
+canon_pk_algo (enum gcry_pk_algos algo)
 {
   switch (algo)
     {
@@ -348,6 +349,9 @@ canon_pubkey_algo (int algo)
     case GCRY_PK_RSA_S: return GCRY_PK_RSA;
     case GCRY_PK_ELG:
     case GCRY_PK_ELG_E: return GCRY_PK_ELG;
+    case GCRY_PK_ECC:
+    case GCRY_PK_ECDSA:
+    case GCRY_PK_ECDH: return GCRY_PK_ECC;
     default: return algo;
     }
 }
@@ -362,12 +366,13 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
   gpg_error_t err;
   gcry_sexp_t top_list;
   gcry_sexp_t list = NULL;
+  char *curve = NULL;
   const char *value;
   size_t valuelen;
   char *string;
   int  idx;
   int  is_v4, is_protected;
-  int  pubkey_algo;
+  enum gcry_pk_algos pk_algo;
   int  protect_algo = 0;
   char iv[16];
   int  ivlen = 0;
@@ -375,11 +380,13 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
   int  s2k_algo = 0;
   byte s2k_salt[8];
   u32  s2k_count = 0;
+  int  is_ecdh = 0;
   size_t npkey, nskey;
   gcry_mpi_t skey[10];  /* We support up to 9 parameters.  */
   int skeyidx = 0;
   struct seckey_info *ski;
 
+  /* gcry_log_debugsxp ("transferkey", s_pgp); */
   top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0);
   if (!top_list)
     goto bad_seckey;
@@ -445,6 +452,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
       xfree (string);
     }
 
+  /* Parse the gcrypt PK algo and check that it is okay.  */
   gcry_sexp_release (list);
   list = gcry_sexp_find_token (top_list, "algo", 0);
   if (!list)
@@ -452,15 +460,52 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
   string = gcry_sexp_nth_string (list, 1);
   if (!string)
     goto bad_seckey;
-  pubkey_algo = gcry_pk_map_name (string);
-  xfree (string);
-
-  if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
-      || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
+  pk_algo = gcry_pk_map_name (string);
+  xfree (string); string = NULL;
+  if (gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
+      || gcry_pk_algo_info (pk_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey)
       || !npkey || npkey >= nskey || nskey > PUBKEY_MAX_NSKEY)
     goto bad_seckey;
-  pubkey_algo = map_pk_gcry_to_openpgp (pubkey_algo);
 
+  /* Check that the pubkey algo matches the one from the public key.  */
+  switch (canon_pk_algo (pk_algo))
+    {
+    case GCRY_PK_RSA:
+      if (!is_RSA (pk->pubkey_algo))
+        pk_algo = 0;  /* Does not match.  */
+      break;
+    case GCRY_PK_DSA:
+      if (!is_DSA (pk->pubkey_algo))
+        pk_algo = 0;  /* Does not match.  */
+      break;
+    case GCRY_PK_ELG:
+      if (!is_ELGAMAL (pk->pubkey_algo))
+        pk_algo = 0;  /* Does not match.  */
+      break;
+    case GCRY_PK_ECC:
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+        ;
+      else if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+        is_ecdh = 1;
+      else if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
+        ;
+      else
+        pk_algo = 0;  /* Does not match.  */
+      /* For ECC we do not have the domain parameters thus fix our info.  */
+      npkey = 1;
+      nskey = 2;
+      break;
+    default:
+      pk_algo = 0;   /* Oops.  */
+      break;
+    }
+  if (!pk_algo)
+    {
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      goto leave;
+    }
+
+  /* Parse the key parameters.  */
   gcry_sexp_release (list);
   list = gcry_sexp_find_token (top_list, "skey", 0);
   if (!list)
@@ -509,7 +554,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
 
   gcry_sexp_release (list); list = NULL;
 
-  /* We have no need for the CSUM valuel thus we don't parse it.  */
+  /* We have no need for the CSUM value thus we don't parse it.  */
   /* list = gcry_sexp_find_token (top_list, "csum", 0); */
   /* if (list) */
   /*   { */
@@ -523,6 +568,14 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
   /*   desired_csum = 0; */
   /* gcry_sexp_release (list); list = NULL; */
 
+  /* Get the curve name if any,  */
+  list = gcry_sexp_find_token (top_list, "curve", 0);
+  if (list)
+    {
+      curve = gcry_sexp_nth_string (list, 1);
+      gcry_sexp_release (list); list = NULL;
+    }
+
   gcry_sexp_release (top_list); top_list = NULL;
 
   /* log_debug ("XXX is_v4=%d\n", is_v4); */
@@ -559,57 +612,49 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
     }
 
   /* We need to change the received parameters for ECC algorithms.
-     The transfer format has all parameters but OpenPGP defines that
-     only the OID of the curve is to be used.  */
-  if (pubkey_algo == PUBKEY_ALGO_ECDSA
-      || pubkey_algo == PUBKEY_ALGO_EDDSA
-      || pubkey_algo == PUBKEY_ALGO_ECDH)
+     The transfer format has the curve name and the parameters
+     separate.  We put them all into the SKEY array.  */
+  if (canon_pk_algo (pk_algo) == GCRY_PK_ECC)
     {
-      gcry_sexp_t s_pubkey;
-      const char *curvename, *curveoidstr;
-      gcry_mpi_t mpi;
-
-      /* We build an S-expression with the public key parameters and
-         ask Libgcrypt to return the matching curve name.  */
-      if (npkey != 6 || !skey[0] || !skey[1] || !skey[2]
-          || !skey[3] || !skey[4] || !skey[5]
-          || !skey[6] || skey[7])
+      const char *oidstr;
+
+      /* Assert that all required parameters are available.  We also
+         check that the array does not contain more parameters than
+         needed (this was used by some beta versions of 2.1.  */
+      if (!curve || !skey[0] || !skey[1] || skey[2])
         {
           err = gpg_error (GPG_ERR_INTERNAL);
           goto leave;
         }
-      err = gcry_sexp_build (&s_pubkey, NULL,
-                             "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
-                             skey[0], skey[1], skey[2], skey[3], skey[4]);
-      if (err)
-        goto leave;
-      curvename = gcry_pk_get_curve (s_pubkey, 0, NULL);
-      gcry_sexp_release (s_pubkey);
-      curveoidstr = openpgp_curve_to_oid (curvename, NULL);
-      if (!curveoidstr)
+
+      oidstr = openpgp_curve_to_oid (curve, NULL);
+      if (!oidstr)
         {
-          log_error ("no OID known for curve '%s'\n", curvename);
-          err = gpg_error (GPG_ERR_UNKNOWN_NAME);
+          log_error ("no OID known for curve '%s'\n", curve);
+          err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
           goto leave;
         }
-      err = openpgp_oid_from_str (curveoidstr, &mpi);
+      /* Put the curve's OID into into the MPI array.  This requires
+         that we shift Q and D.  For ECDH also insert the KDF parms. */
+      if (is_ecdh)
+        {
+          skey[4] = NULL;
+          skey[3] = skey[1];
+          skey[2] = gcry_mpi_copy (pk->pkey[2]);
+        }
+      else
+        {
+          skey[3] = NULL;
+          skey[2] = skey[1];
+        }
+      skey[1] = skey[0];
+      skey[0] = NULL;
+      err = openpgp_oid_from_str (oidstr, skey + 0);
       if (err)
         goto leave;
-
-      /* Now replace the curve parameters by the OID and shift the
-         rest of the parameters.  */
-      gcry_mpi_release (skey[0]);
-      skey[0] = mpi;
-      for (idx=1; idx <= 4; idx++)
-        gcry_mpi_release (skey[idx]);
-      skey[1] = skey[5];
-      skey[2] = skey[6];
-      for (idx=3; idx <= 6; idx++)
-        skey[idx] = NULL;
-
       /* Fixup the NPKEY and NSKEY to match OpenPGP reality.  */
-      npkey = 2;
-      nskey = 3;
+      npkey = 2 + is_ecdh;
+      nskey = 3 + is_ecdh;
 
       /* for (idx=0; skey[idx]; idx++) */
       /*   { */
@@ -634,11 +679,6 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
       err = gpg_error (GPG_ERR_INV_DATA);
       goto leave;
     }
-  if (canon_pubkey_algo (pubkey_algo) != canon_pubkey_algo (pk->pubkey_algo))
-    {
-      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
-      goto leave;
-    }
   err = openpgp_cipher_test_algo (protect_algo);
   if (err)
     goto leave;
@@ -695,6 +735,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
   /* That's it.  */
 
  leave:
+  gcry_free (curve);
   gcry_sexp_release (list);
   gcry_sexp_release (top_list);
   for (idx=0; idx < skeyidx; idx++)

commit d6ca407a27877174c10adfae9dc601bea996cf27
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Jun 20 10:39:26 2014 +0200

    gpg: Avoid infinite loop in uncompressing garbled packets.
    
    * g10/compress.c (do_uncompress): Limit the number of extra FF bytes.
    --
    
    A packet like (a3 01 5b ff) leads to an infinite loop.  Using
    --max-output won't help if it is a partial packet.  This patch
    actually fixes a regression introduced on 1999-05-31 (c34c6769).
    Actually it would be sufficient to stuff just one extra 0xff byte.
    Given that this problem popped up only after 15 years, I feel safer to
    allow for a very few FF bytes.
    
    Thanks to Olivier Levillain and Florian Maury for their detailed
    report.

diff --git a/g10/compress.c b/g10/compress.c
index 6e412e9..0a6e09d 100644
--- a/g10/compress.c
+++ b/g10/compress.c
@@ -164,7 +164,8 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
 	       IOBUF a, size_t *ret_len )
 {
     int zrc;
-    int rc=0;
+    int rc = 0;
+    int leave = 0;
     size_t n;
     int nread, count;
     int refill = !zs->avail_in;
@@ -182,13 +183,14 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
 	    nread = iobuf_read( a, zfx->inbuf + n, count );
 	    if( nread == -1 ) nread = 0;
 	    n += nread;
-	    /* If we use the undocumented feature to suppress
-	     * the zlib header, we have to give inflate an
-	     * extra dummy byte to read */
-	    if( nread < count && zfx->algo == 1 ) {
-		*(zfx->inbuf + n) = 0xFF; /* is it really needed ? */
-		zfx->algo1hack = 1;
+	    /* Algo 1 has no zlib header which requires us to to give
+	     * inflate an extra dummy byte to read. To be on the safe
+	     * side we allow for up to 4 ff bytes.  */
+	    if( nread < count && zfx->algo == 1 && zfx->algo1hack < 4) {
+		*(zfx->inbuf + n) = 0xFF;
+		zfx->algo1hack++;
 		n++;
+                leave = 1;
 	    }
 	    zs->avail_in = n;
 	}
@@ -208,7 +210,8 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
 	    else
 		log_fatal("zlib inflate problem: rc=%d\n", zrc );
 	}
-    } while( zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR );
+    } while (zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR
+             && !leave);
 
     *ret_len = zfx->outbufsize - zs->avail_out;
     if( DBG_FILTER )

-----------------------------------------------------------------------

Summary of changes:
 AUTHORS             |    3 +
 agent/cvt-openpgp.c |   37 ++++++++++---
 doc/gpg-agent.texi  |   11 ++--
 doc/gpg.texi        |   45 ++++++++++-----
 doc/tools.texi      |    9 +--
 g10/compress.c      |   19 ++++---
 g10/export.c        |  151 ++++++++++++++++++++++++++++++++-------------------
 7 files changed, 182 insertions(+), 93 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list