>>>>> In 
>>>>> <4a8c5344.4060701__17863.5451746688$1250713354$gmane$...@dougbarton.us> 
>>>>>   Doug Barton <do...@dougbarton.us> wrote:
> >> Today I mis-typed a passphrase for a symmetrically encrypted file and
> >> was surprised to discover that gpg-agent had stored the bad passphrase
> >> and would not let me access the file. I have occasionally in the past
> > 
> > This is a new and probably not too well tested feature.  I'll check whey
> > this is going wrong.

> Fair enough, thanks.

That's my fault, sorry.  The attached patch should fix the problem.
Could you try it?

2009-08-20  Daiki Ueno  <u...@unixuser.org>

        * 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.

Index: g10/gpgv.c
===================================================================
--- g10/gpgv.c	(revision 5124)
+++ g10/gpgv.c	(working copy)
@@ -426,6 +426,14 @@
   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) 
 {
Index: g10/mainproc.c
===================================================================
--- g10/mainproc.c	(revision 5124)
+++ g10/mainproc.c	(working copy)
@@ -586,6 +586,13 @@
 	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
Index: g10/passphrase.c
===================================================================
--- g10/passphrase.c	(revision 5124)
+++ g10/passphrase.c	(working copy)
@@ -452,6 +452,7 @@
   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 @@
     }
   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 @@
     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;
Index: include/cipher.h
===================================================================
--- include/cipher.h	(revision 5124)
+++ include/cipher.h	(working copy)
@@ -94,6 +94,7 @@
   int use_mdc;
   int symmetric;
   byte key[32]; /* This is the largest used keylen (256 bit). */
+  char s2k_cacheid[1+16+1];
 } DEK;
 
 
Regards,
-- 
Daiki Ueno
_______________________________________________
Gnupg-users mailing list
Gnupg-users@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-users

Reply via email to