summaryrefslogtreecommitdiffstats
path: root/g10/passphrase.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/passphrase.c')
-rw-r--r--g10/passphrase.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/g10/passphrase.c b/g10/passphrase.c
index f5d301398..84eedc211 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -50,11 +50,10 @@ static char *next_pw = NULL;
static char *last_pw = NULL;
-/* Hash a passphrase using the supplied s2k. If create is true, create
- a new salt or what else must be filled into the s2k for a new key.
- always needs: dek->algo, s2k->mode, s2k->hash_algo. */
+/* Hash a passphrase using the supplied s2k.
+ Always needs: dek->algo, s2k->mode, s2k->hash_algo. */
static void
-hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k, int create )
+hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k)
{
gcry_md_hd_t md;
int pass, i;
@@ -82,13 +81,6 @@ hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k, int create )
int len2 = pwlen + 8;
ulong count = len2;
- if ( create && !pass )
- {
- gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
- if ( s2k->mode == 3 )
- s2k->count = opt.s2k_count;
- }
-
if ( s2k->mode == 3 )
{
count = S2K_DECODE_COUNT(s2k->count);
@@ -441,7 +433,9 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
MODE 0: Allow cached passphrase
1: Ignore cached passphrase
- 2: Ditto, but change the text to "repeat entry"
+ 2: Ditto, but create a new key
+ 3: Allow cached passphrase; use the S2K salt as the cache ID
+ 4: Ditto, but create a new key
*/
DEK *
passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
@@ -461,6 +455,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
if ( !s2k )
{
+ assert (mode != 3 && mode != 4);
/* This is used for the old rfc1991 mode
* Note: This must match the code in encode.c with opt.rfc1991 set */
s2k = &help_s2k;
@@ -468,6 +463,15 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
s2k->hash_algo = S2K_DIGEST_ALGO;
}
+ /* Create a new salt or what else to be filled into the s2k for a
+ new key. */
+ if ((mode == 2 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
+ {
+ gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
+ if ( s2k->mode == 3 )
+ s2k->count = opt.s2k_count;
+ }
+
/* If we do not have a passphrase available in NEXT_PW and status
information are request, we print them now. */
if ( !next_pw && is_status_enabled() )
@@ -565,10 +569,21 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
}
else
{
+ char *cacheid = NULL;
+ char buf[1+16+1];
+
+ if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
+ {
+ memset (buf, 0, sizeof buf);
+ *buf = 'S';
+ bin2hex (s2k->salt, 8, buf + 1);
+ cacheid = buf;
+ }
+
/* Divert to the gpg-agent. */
- pw = passphrase_get ( keyid, mode == 2, NULL,
- mode == 2? opt.passwd_repeat: 0,
- tryagain_text, custdesc, custprompt, canceled);
+ pw = passphrase_get (keyid, mode == 2, cacheid,
+ (mode == 2 || mode == 4)? opt.passwd_repeat : 0,
+ tryagain_text, custdesc, custprompt, canceled);
if (*canceled)
{
xfree (pw);
@@ -585,10 +600,10 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
get_last_passphrase(). */
dek = xmalloc_secure_clear ( sizeof *dek );
dek->algo = cipher_algo;
- if ( !*pw && mode == 2 )
+ if ( !*pw && (mode == 2 || mode == 4))
dek->keylen = 0;
else
- hash_passphrase( dek, pw, s2k, mode==2 );
+ hash_passphrase (dek, pw, s2k);
xfree(last_pw);
last_pw = pw;
return dek;