[git] GnuPG - branch, key-storage-work, updated. gnupg-2.1.0beta3-173-g273bb38

by Werner Koch cvs at cvs.gnupg.org
Thu Feb 21 20:45:16 CET 2013


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, key-storage-work has been updated
       via  273bb38cd7b517460cb3de67662e96e910104675 (commit)
       via  18a261b65fd77a9e434b13483ceaaaf2176f1197 (commit)
       via  4af0c62b15c51056dc293c8e3b907e7c41fbf08c (commit)
      from  8e5766c38f3ac376fb8e7c7f2b0f65de23d84cbe (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 273bb38cd7b517460cb3de67662e96e910104675
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 21 20:35:10 2013 +0100

    gpg: Fix a memory leak in batch key generation
    
    * g10/keygen.c (append_to_parameter): New.
    (proc_parameter_file): Use new func to extend the parameter list.
    
    * g10/passphrase.c (passphrase_to_dek_ext): Print a diagnostic of
    gcry_kdf_derive failed.
    * g10/keygen.c (proc_parameter_file): Print a diagnostic if
    passphrase_to_dek failed.
    --
    
    Due to an improper way of using the linked list head, all memory for
    items allocated in proc_parameter_file was never released.  If batched
    key generation with a passphrase and more than ~200 keys was used this
    exhausted the secure memory.

diff --git a/g10/keygen.c b/g10/keygen.c
index b5ccf02..fc985ee 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -2591,6 +2591,17 @@ generate_user_id (KBNODE keyblock)
 }
 
 
+/* Append R to the linked list PARA.  */
+static void
+append_to_parameter (struct para_data_s *para, struct para_data_s *r)
+{
+  assert (para);
+  while (para->next)
+    para = para->next;
+  para->next = r;
+}
+
+/* Release the parameter list R.  */
 static void
 release_parameter_list (struct para_data_s *r)
 {
@@ -2817,8 +2828,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
       r->u.usage = (is_default
                     ? (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG)
                     : openpgp_pk_algo_usage(algo));
-      r->next = para;
-      para = r;
+      append_to_parameter (para, r);
     }
   else if (err == -1)
     return -1;
@@ -2854,8 +2864,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
 	  r->u.usage = (is_default
                         ? PUBKEY_USAGE_ENC
                         : openpgp_pk_algo_usage (algo));
-	  r->next = para;
-	  para = r;
+          append_to_parameter (para, r);
 	}
       else if (err == -1)
 	return -1;
@@ -2892,8 +2901,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
 	    p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")");
 	  if( s3 )
 	    p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">");
-	  r->next = para;
-	  para = r;
+          append_to_parameter (para, r);
 	  have_user_id=1;
 	}
     }
@@ -2946,13 +2954,11 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
           r = xmalloc_clear( sizeof *r );
           r->key = pPASSPHRASE_DEK;
           r->u.dek = dek;
-          r->next = para;
-          para = r;
+          append_to_parameter (para, r);
           r = xmalloc_clear( sizeof *r );
           r->key = pPASSPHRASE_S2K;
           r->u.s2k = s2k;
-          r->next = para;
-          para = r;
+          append_to_parameter (para, r);
         }
 
       if (canceled)
@@ -2971,27 +2977,32 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
            * but because we do this always, why not here.  */
           STRING2KEY *s2k;
           DEK *dek;
+          static int count;
 
-          s2k = xmalloc_secure ( sizeof *s2k );
+          s2k = xmalloc ( sizeof *s2k );
           s2k->mode = opt.s2k_mode;
           s2k->hash_algo = S2K_DIGEST_ALGO;
           set_next_passphrase ( r->u.value );
           dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2,
                                    NULL, NULL);
-          set_next_passphrase (NULL );
-          assert (dek);
+          if (!dek)
+            {
+              log_error ("%s:%d: error post processing the passphrase\n",
+                         fname, r->lnr );
+              xfree (s2k);
+              return -1;
+            }
+          set_next_passphrase (NULL);
           memset (r->u.value, 0, strlen(r->u.value));
 
           r = xmalloc_clear (sizeof *r);
           r->key = pPASSPHRASE_S2K;
           r->u.s2k = s2k;
-          r->next = para;
-          para = r;
+          append_to_parameter (para, r);
           r = xmalloc_clear (sizeof *r);
           r->key = pPASSPHRASE_DEK;
           r->u.dek = dek;
-          r->next = para;
-          para = r;
+          append_to_parameter (para, r);
         }
     }
 
@@ -3029,8 +3040,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
       r = xmalloc_clear( sizeof *r + 20 );
       r->key = pSUBKEYEXPIRE;
       r->u.expire = seconds;
-      r->next = para;
-      para = r;
+      append_to_parameter (para, r);
     }
 
   do_generate_keypair( para, outctrl, card );
diff --git a/g10/passphrase.c b/g10/passphrase.c
index d872e36..f83e668 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -569,17 +569,21 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
     dek->keylen = 0;
   else
     {
+      gpg_error_t err;
+
       dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
       if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key)))
         BUG ();
-      if (gcry_kdf_derive (pw, strlen (pw),
-                           s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
-                           s2k->mode == 1? GCRY_KDF_SALTED_S2K :
-                           /* */           GCRY_KDF_SIMPLE_S2K,
-                           s2k->hash_algo, s2k->salt, 8,
-                           S2K_DECODE_COUNT(s2k->count),
-                           dek->keylen, dek->key))
+      err = gcry_kdf_derive (pw, strlen (pw),
+                             s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
+                             s2k->mode == 1? GCRY_KDF_SALTED_S2K :
+                             /* */           GCRY_KDF_SIMPLE_S2K,
+                             s2k->hash_algo, s2k->salt, 8,
+                             S2K_DECODE_COUNT(s2k->count),
+                             dek->keylen, dek->key);
+      if (err)
         {
+          log_error ("gcry_kdf_derive failed: %s", gpg_strerror (err));
           xfree (pw);
           xfree (dek);
 	  write_status( STATUS_MISSING_PASSPHRASE );

commit 18a261b65fd77a9e434b13483ceaaaf2176f1197
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 21 20:27:20 2013 +0100

    gpg: Handle the agent's NEW_PASSPHRASE inquiry.
    
    * g10/call-agent.c (default_inq_cb): Take care of NEW_PASSPHRASE.

diff --git a/g10/call-agent.c b/g10/call-agent.c
index 85a3f28..4828f9a 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -336,7 +336,7 @@ default_inq_cb (void *opaque, const char *line)
   gpg_error_t err = 0;
   struct default_inq_parm_s *parm = opaque;
 
-  if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
+  if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
     {
       err = gpg_proxy_pinentry_notify (parm->ctrl, line);
       if (err)
@@ -344,7 +344,8 @@ default_inq_cb (void *opaque, const char *line)
                    "PINENTRY_LAUNCHED");
       /* We do not pass errors to avoid breaking other code.  */
     }
-  else if (!strncmp (line, "PASSPHRASE", 10) && (line[10]==' '||!line[10])
+  else if ((has_leading_keyword (line, "PASSPHRASE")
+            || has_leading_keyword (line, "NEW_PASSPHRASE"))
            && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
     {
       if (have_static_passphrase ())

commit 4af0c62b15c51056dc293c8e3b907e7c41fbf08c
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 21 20:25:12 2013 +0100

    common: Add func has_leading_keyword.
    
    * common/stringhelp.c (has_leading_keyword): New.

diff --git a/common/stringhelp.c b/common/stringhelp.c
index 842f6a1..d51d3e0 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -74,6 +74,29 @@ change_slashes (char *name)
 
 
 /*
+ * Check whether STRINGS starts with KEYWORD.  The keyword is
+ * delimited by end of string, a space or a tab.  Returns NULL if not
+ * found or a pointer into STRING to the next non-space character
+ * after the KEYWORD (which may be end of string).
+ */
+char *
+has_leading_keyword (const char *string, const char *keyword)
+{
+  size_t n = strlen (keyword);
+
+  if (!strncmp (string, keyword, n)
+      && (!string[n] || string[n] == ' ' || string[n] == '\t'))
+    {
+      string += n;
+      while (*string == ' ' || *string == '\t')
+        string++;
+      return (char*)string;
+    }
+  return NULL;
+}
+
+
+/*
  * Look for the substring SUB in buffer and return a pointer to that
  * substring in BUFFER or NULL if not found.
  * Comparison is case-insensitive.
diff --git a/common/stringhelp.h b/common/stringhelp.h
index 60ba12b..c1f7ea1 100644
--- a/common/stringhelp.h
+++ b/common/stringhelp.h
@@ -34,6 +34,8 @@
 
 #include "types.h"
 
+char *has_leading_keyword (const char *string, const char *keyword);
+
 const char *memistr (const void *buf, size_t buflen, const char *sub);
 char *mem2str( char *, const void *, size_t);
 char *trim_spaces( char *string );

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

Summary of changes:
 common/stringhelp.c |   23 +++++++++++++++++++++++
 common/stringhelp.h |    2 ++
 g10/call-agent.c    |    5 +++--
 g10/keygen.c        |   48 +++++++++++++++++++++++++++++-------------------
 g10/passphrase.c    |   18 +++++++++++-------
 5 files changed, 68 insertions(+), 28 deletions(-)


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




More information about the Gnupg-commits mailing list