aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--NEWS2
-rw-r--r--agent/ChangeLog7
-rw-r--r--agent/agent.h1
-rw-r--r--agent/cvt-openpgp.c5
-rw-r--r--agent/protect.c32
-rw-r--r--g10/ChangeLog5
-rw-r--r--g10/export.c7
7 files changed, 53 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index beadfc3ac..f37deb29e 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 9a6134d7f..78ddf8d22 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,10 @@
+2011-04-26 Werner Koch <[email protected]>
+
+ * 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 <[email protected]>
* agent.h (server_control_s): Add field cache_ttl_opt_preset.
diff --git a/agent/agent.h b/agent/agent.h
index 16c9aba56..9aaf26441 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 1595a324b..0f3172894 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 0b8c9b408..7df82de03 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 8b22df854..86c9b9817 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,8 @@
+2011-04-26 Werner Koch <[email protected]>
+
+ * export.c (transfer_format_to_openpgp): Do not apply
+ encode_s2k_iterations to S2K_COUNT.
+
2011-04-25 Werner Koch <[email protected]>
* delkey.c (do_delete_key): Mark classify_user_id for use with
diff --git a/g10/export.c b/g10/export.c
index 9f4959e61..2e35eea9f 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;