From 7cde92403c2134a20818a9c499b60450a3addfcb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 20 Aug 2009 08:41:15 +0000 Subject: [PATCH] 2009-08-20 Daiki Ueno * mainproc.c (proc_encrypted): Clear passphrase cached with S2K cache ID if decryption failed. * passphrase.c (passphrase_to_dek_ext): Set dek->s2k_cacheid. * gpgv.c (passphrase_clear_cache): New stub. --- README.maint | 3 ++- g10/ChangeLog | 7 +++++++ g10/gpgv.c | 8 ++++++++ g10/mainproc.c | 7 +++++++ g10/passphrase.c | 16 ++++++++-------- include/ChangeLog | 4 ++++ include/cipher.h | 1 + 7 files changed, 37 insertions(+), 9 deletions(-) diff --git a/README.maint b/README.maint index 045c21ccb..3d0e5abd3 100644 --- a/README.maint +++ b/README.maint @@ -21,7 +21,8 @@ Release process: * Make sure that all new PO files are checked in. * Decide whether you want to update the automake standard files (Mainly config.guess and config.sub). - * [1.4 only] Update gpg.texi and gpgv.texi from the trunk. + * [1.4 only] Update gpg.texi and gpgv.texi from the trunk: + make -C doc update-source-from-gnupg-2 * Run "make -C po update-po". * Write NEWS entries and set the release date in NEWS. * In configure.ac set "my_issvn" to "no". diff --git a/g10/ChangeLog b/g10/ChangeLog index f4cfe361f..22fe85941 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,10 @@ +2009-08-20 Daiki Ueno + + * mainproc.c (proc_encrypted): Clear passphrase cached with S2K + cache ID if decryption failed. + * passphrase.c (passphrase_to_dek_ext): Set dek->s2k_cacheid. + * gpgv.c (passphrase_clear_cache): New stub. + 2009-08-11 Werner Koch * call-agent.c (get_serialno_cb): New. From ../agent/call-scd.c. diff --git a/g10/gpgv.c b/g10/gpgv.c index e1f20fb7d..747b05ff2 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -426,6 +426,14 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, return NULL; } +void +passphrase_clear_cache (u32 *keyid, const char *cacheid, int algo) +{ + (void)keyid; + (void)cacheid; + (void)algo; +} + struct keyserver_spec * parse_preferred_keyserver(PKT_signature *sig) { diff --git a/g10/mainproc.c b/g10/mainproc.c index 31d338529..4a8df6f57 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -586,6 +586,13 @@ proc_encrypted( CTX c, PACKET *pkt ) write_status( STATUS_DECRYPTION_FAILED ); } else { + if (gpg_err_code (result) == GPG_ERR_BAD_KEY + && *c->dek->s2k_cacheid != '\0') + { + log_debug(_("cleared passphrase cached with ID: %s\n"), + c->dek->s2k_cacheid); + passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0); + } write_status( STATUS_DECRYPTION_FAILED ); log_error(_("decryption failed: %s\n"), g10_errstr(result)); /* Hmmm: does this work when we have encrypted using multiple diff --git a/g10/passphrase.c b/g10/passphrase.c index 83a6b0cf8..9fddebf0e 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -452,6 +452,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, DEK *dek; STRING2KEY help_s2k; int dummy_canceled; + char s2k_cacheidbuf[1+16+1], *s2k_cacheid = NULL; if (!canceled) canceled = &dummy_canceled; @@ -573,19 +574,16 @@ 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; + memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf); + *s2k_cacheidbuf = 'S'; + bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1); + s2k_cacheid = s2k_cacheidbuf; } /* Divert to the gpg-agent. */ - pw = passphrase_get (keyid, mode == 2, cacheid, + pw = passphrase_get (keyid, mode == 2, s2k_cacheid, (mode == 2 || mode == 4)? opt.passwd_repeat : 0, tryagain_text, custdesc, custprompt, canceled); if (*canceled) @@ -608,6 +606,8 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, dek->keylen = 0; else hash_passphrase (dek, pw, s2k); + if (s2k_cacheid) + memcpy (dek->s2k_cacheid, s2k_cacheid, sizeof dek->s2k_cacheid); xfree(last_pw); last_pw = pw; return dek; diff --git a/include/ChangeLog b/include/ChangeLog index 559d305ba..339800f37 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2009-08-20 Daiki Ueno (wk) + + * cipher.h (struct DEK): Add field S2K_CACHEID. + 2008-04-18 Werner Koch * cipher.h (CIPHER_ALGO_CAMELLIA256): Change ID to 13. diff --git a/include/cipher.h b/include/cipher.h index 0d75fa6cd..8e198283d 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -94,6 +94,7 @@ typedef struct int use_mdc; int symmetric; byte key[32]; /* This is the largest used keylen (256 bit). */ + char s2k_cacheid[1+16+1]; } DEK;