[git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-49-g817f071

by Werner Koch cvs at cvs.gnupg.org
Tue Apr 26 21:09:12 CEST 2011


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  817f07173cda59565c179bde6c3edcf2508bbc98 (commit)
      from  5da12674eaae11969b22e6f80e4957217ad406d6 (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 817f07173cda59565c179bde6c3edcf2508bbc98
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Apr 26 20:33:46 2011 +0200

    Fixed regression in OpenPGP secret key export.
    
    The protection used in the exported key used a different iteration
    count than given in the S2K field.  Thus all OpenPGP keys exported
    from GnuPG 2.1-beta can't be imported again.  Given that the actual
    secret key material is kept in private-keys-v1.d/ the can be
    re-exported with this fixed version.

diff --git a/NEWS b/NEWS
index beadfc3..f37deb2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 Noteworthy changes in version 2.1.0beta3
 -----------------------------------------------------
 
+ * Fixed regression in GPG'S secret key export function.
+
 
 Noteworthy changes in version 2.1.0beta2 (2011-03-08)
 -----------------------------------------------------
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 9a6134d..78ddf8d 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,10 @@
+2011-04-26  Werner Koch  <wk at g10code.com>
+
+	* cvt-openpgp.c (convert_to_openpgp): Use rfc4880 encoded S2K count.
+	* protect.c (get_standard_s2k_count_rfc4880): New.
+	(S2K_DECODE_COUNT): New.
+	(s2k_hash_passphrase): Use the new macro.
+
 2011-04-21  Werner Koch  <wk at g10code.com>
 
 	* agent.h (server_control_s): Add field cache_ttl_opt_preset.
diff --git a/agent/agent.h b/agent/agent.h
index 16c9aba..9aaf264 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -330,6 +330,7 @@ gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
 
 /*-- protect.c --*/
 unsigned long get_standard_s2k_count (void);
+unsigned char get_standard_s2k_count_rfc4880 (void);
 int agent_protect (const unsigned char *plainkey, const char *passphrase,
                    unsigned char **result, size_t *resultlen);
 int agent_unprotect (const unsigned char *protectedkey, const char *passphrase,
diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
index 1595a32..0f31728 100644
--- a/agent/cvt-openpgp.c
+++ b/agent/cvt-openpgp.c
@@ -1046,7 +1046,10 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
 
   gcry_create_nonce (protect_iv, sizeof protect_iv);
   gcry_create_nonce (salt, sizeof salt);
-  s2k_count = get_standard_s2k_count ();
+  /* We need to use the encoded S2k count.  It is not possible to
+     encode it after it has been used because the encoding procedure
+     may round the value up.  */
+  s2k_count = get_standard_s2k_count_rfc4880 ();
   err = apply_protection (array, npkey, nskey, passphrase,
                           GCRY_CIPHER_AES, protect_iv, sizeof protect_iv,
                           3, GCRY_MD_SHA1, salt, s2k_count);
diff --git a/agent/protect.c b/agent/protect.c
index 0b8c9b4..7df82de 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -41,6 +41,9 @@
 #define PROT_CIPHER_STRING "aes"
 #define PROT_CIPHER_KEYLEN (128/8)
 
+/* Decode an rfc4880 encoded S2K count.  */
+#define S2K_DECODE_COUNT(_val) ((16ul + ((_val) & 15)) << (((_val) >> 4) + 6))
+
 
 /* A table containing the information needed to create a protected
    private key.  */
@@ -192,6 +195,33 @@ get_standard_s2k_count (void)
 }
 
 
+/* Same as get_standard_s2k_count but return the count in the encoding
+   as described by rfc4880.  */
+unsigned char
+get_standard_s2k_count_rfc4880 (void)
+{
+  unsigned long iterations;
+  unsigned int count;
+  unsigned char result;
+  unsigned char c=0;
+
+  iterations = get_standard_s2k_count ();
+  if (iterations >= 65011712)
+    return 255;
+
+  /* Need count to be in the range 16-31 */
+  for (count=iterations>>6; count>=32; count>>=1)
+    c++;
+
+  result = (c<<4)|(count-16);
+
+  if (S2K_DECODE_COUNT(result) < iterations)
+    result++;
+
+  return result;
+
+}
+
 
 
 /* Calculate the MIC for a private key or shared secret S-expression.
@@ -1041,7 +1071,7 @@ s2k_hash_passphrase (const char *passphrase, int hashalgo,
                      unsigned char *key, size_t keylen)
 {
   return hash_passphrase (passphrase, hashalgo, s2kmode, s2ksalt,
-                          (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6),
+                          S2K_DECODE_COUNT (s2kcount),
                           key, keylen);
 }
 
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 8b22df8..86c9b98 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,8 @@
+2011-04-26  Werner Koch  <wk at g10code.com>
+
+	* export.c (transfer_format_to_openpgp): Do not apply
+	encode_s2k_iterations to S2K_COUNT.
+
 2011-04-25  Werner Koch  <wk at g10code.com>
 
 	* delkey.c (do_delete_key): Mark classify_user_id for use with
diff --git a/g10/export.c b/g10/export.c
index 9f4959e..2e35eea 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -626,10 +626,9 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
     }
 
   /* Do some sanity checks.  */
-  if (s2k_count <= 1024)
+  if (s2k_count > 255)
     {
-      /* The count must be larger so that encode_s2k_iterations does
-         not fall into a backward compatibility mode.  */
+      /* We expect an already encoded S2K count.  */
       err = gpg_error (GPG_ERR_INV_DATA);
       goto leave;
     }
@@ -682,7 +681,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
   ski->s2k.hash_algo = s2k_algo;
   assert (sizeof ski->s2k.salt == sizeof s2k_salt);
   memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt);
-  ski->s2k.count = encode_s2k_iterations (s2k_count);
+  ski->s2k.count = s2k_count;
   assert (ivlen <= sizeof ski->iv);
   memcpy (ski->iv, iv, ivlen);
   ski->ivlen = ivlen;

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

Summary of changes:
 NEWS                |    2 ++
 agent/ChangeLog     |    7 +++++++
 agent/agent.h       |    1 +
 agent/cvt-openpgp.c |    5 ++++-
 agent/protect.c     |   32 +++++++++++++++++++++++++++++++-
 g10/ChangeLog       |    5 +++++
 g10/export.c        |    7 +++----
 7 files changed, 53 insertions(+), 6 deletions(-)


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




More information about the Gnupg-commits mailing list