aboutsummaryrefslogtreecommitdiffstats
path: root/agent/protect.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2011-04-26 18:33:46 +0000
committerWerner Koch <[email protected]>2011-04-26 18:39:09 +0000
commit817f07173cda59565c179bde6c3edcf2508bbc98 (patch)
treec6aa504d8e1154f23ebbdc2f544703de21ec962b /agent/protect.c
parentFix regression in gpg's mail address parsing. (diff)
downloadgnupg-817f07173cda59565c179bde6c3edcf2508bbc98.tar.gz
gnupg-817f07173cda59565c179bde6c3edcf2508bbc98.zip
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.
Diffstat (limited to 'agent/protect.c')
-rw-r--r--agent/protect.c32
1 files changed, 31 insertions, 1 deletions
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);
}