gnupg/g10 (8 files)

cvs user wk cvs at cvs.gnupg.org
Wed May 4 00:08:57 CEST 2005


    Date: Wednesday, May 4, 2005 @ 00:27:07
  Author: wk
    Path: /cvs/gnupg/gnupg/g10

Modified: ChangeLog card-util.c cardglue.c cardglue.h keydb.h passphrase.c
          seckey-cert.c sign.c

* passphrase.c (agent_get_passphrase): Add new arg CACHEID.
Changed all callers.
(ask_passphrase): Add new arg CACHEID and use it in agent mode.
Changed all callers.
(passphrase_clear_cache): New arg CACHEID.  Changed all callers.
* cardglue.c (format_cacheid): New.
(pin_cb): Compute a cache ID.
(agent_scd_pksign, agent_scd_pkdecrypt): Use it.
(agent_clear_pin_cache): New.
* card-util.c (change_pin): Clear the PIN cache.
(check_pin_for_key_operation): Ditto.


---------------+
 ChangeLog     |   19 ++++++++++
 card-util.c   |    4 ++
 cardglue.c    |   97 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 cardglue.h    |    4 ++
 keydb.h       |    5 +-
 passphrase.c  |   71 +++++++++++++++++++++++++++-------------
 seckey-cert.c |    4 +-
 sign.c        |    4 ++
 8 files changed, 174 insertions(+), 34 deletions(-)


Index: gnupg/g10/ChangeLog
diff -u gnupg/g10/ChangeLog:1.726 gnupg/g10/ChangeLog:1.727
--- gnupg/g10/ChangeLog:1.726	Sun Apr 24 20:35:30 2005
+++ gnupg/g10/ChangeLog	Wed May  4 00:27:07 2005
@@ -1,3 +1,17 @@
+2005-05-03  Werner Koch  <wk at g10code.com>
+
+	* passphrase.c (agent_get_passphrase): Add new arg CACHEID.
+	Changed all callers.
+	(ask_passphrase): Add new arg CACHEID and use it in agent mode.
+	Changed all callers.
+	(passphrase_clear_cache): New arg CACHEID.  Changed all callers.
+	* cardglue.c (format_cacheid): New.
+	(pin_cb): Compute a cache ID.
+	(agent_scd_pksign, agent_scd_pkdecrypt): Use it.
+	(agent_clear_pin_cache): New.
+	* card-util.c (change_pin): Clear the PIN cache.
+	(check_pin_for_key_operation): Ditto.
+
 2005-04-24  David Shaw  <dshaw at jabberwocky.com>
 
 	* trustdb.h, trustdb.c (mark_usable_uid_certs): Add flags for the
@@ -24,6 +38,11 @@
 	here.  We'll fail quite happily later, and usually with a better
 	error message to boot.
 
+2005-04-20  Werner Koch  <wk at g10code.com>
+
+	* sign.c (sign_file, sign_symencrypt_file): Allow for hash
+	debugging.
+
 2005-04-16  David Shaw  <dshaw at jabberwocky.com>
 
 	* keyserver.c (keyserver_spawn): Free some memory.
Index: gnupg/g10/card-util.c
diff -u gnupg/g10/card-util.c:1.33 gnupg/g10/card-util.c:1.34
--- gnupg/g10/card-util.c:1.33	Thu Apr  7 10:31:23 2005
+++ gnupg/g10/card-util.c	Wed May  4 00:27:07 2005
@@ -67,6 +67,8 @@
   log_info (_("OpenPGP card no. %s detected\n"),
               info.serialno? info.serialno : "[none]");
 
+  agent_clear_pin_cache (info.serialno);
+
   agent_release_card_info (&info);
 
   if (opt.batch)
@@ -950,6 +952,8 @@
 {     
   int rc = 0;
 
+  agent_clear_pin_cache (info->serialno);
+
   *forced_chv1 = !info->chv1_cached;
   if (*forced_chv1)
     { /* Switch of the forced mode so that during key generation we
Index: gnupg/g10/cardglue.c
diff -u gnupg/g10/cardglue.c:1.25 gnupg/g10/cardglue.c:1.26
--- gnupg/g10/cardglue.c:1.25	Wed Mar 30 12:39:13 2005
+++ gnupg/g10/cardglue.c	Wed May  4 00:27:07 2005
@@ -43,12 +43,19 @@
 #include "apdu.h"
 #include "app-common.h"
 
-struct ctrl_ctx_s {
+struct ctrl_ctx_s 
+{
   int (*status_cb)(void *opaque, const char *line);
   void *status_cb_arg;
 };
 
 
+struct pincb_parm_s
+{
+  const char *sn;
+};
+
+
 static char *default_reader_port;
 static APP current_app;
 
@@ -334,6 +341,39 @@
 }
 
 
+/* Format a cache ID from the serialnumber in SN and return it as an
+   allocated string.  In case of an error NULL is returned. */
+static char *
+format_cacheid (const char *sn)
+{
+  const char *s;
+  size_t snlen;
+  char *cacheid = NULL;
+
+  /* The serialnumber we use for a card is "CARDSN:serialno".  Where
+     serialno is the BCD string (i.e. hex string) with the full
+     number.  The serial number expect here constsis of hexdigits
+     followed by other characters, we cut off these other
+     characters. */
+  if (sn)
+    {
+      for (s=sn,snlen=0; hexdigitp (s); s++, snlen++)
+        ;
+      if (snlen == 32)
+        {
+          /* Yes, this looks indeed like an OpenPGP card S/N. */
+          cacheid = xtrymalloc (7+snlen+1);
+          if (cacheid)
+            {
+              memcpy (cacheid, "CARDSN:", 7);
+              memcpy (cacheid+7, sn, snlen);
+              cacheid[7+snlen] = 0;
+            }
+        }
+    }
+  return cacheid;
+}
+
 /* Check that the serial number of the current card (as described by
    APP) matches SERIALNO.  If there is no match and we are not in
    batch mode, present a prompt to insert the desired card.  The
@@ -651,12 +691,14 @@
 static int 
 pin_cb (void *opaque, const char *info, char **retstr)
 {
+  struct pincb_parm_s *parm = opaque;
   char *value;
   int canceled;
   int isadmin = 0;
   int newpin = 0;
   const char *again_text = NULL;
   const char *ends, *s;
+  char *cacheid = NULL;
 
   *retstr = NULL;
   /*   log_debug ("asking for PIN '%s'\n", info); */
@@ -674,9 +716,23 @@
         }
       info = ends+1;
     }
-  else
+  else if (info && *info == '|')
     log_debug ("pin_cb called without proper PIN info hack\n");
 
+  /* If we are not requesting a new PIN and we are not requesting an
+     AdminPIN, compute a string to be used as the cacheID for
+     gpg-agent. */
+  if (!newpin && !isadmin && parm)
+    {
+      cacheid = format_cacheid (parm->sn);
+    }
+  else if (newpin && parm)
+    {
+      /* Make really sure that it is not cached anymore. */
+      agent_clear_pin_cache (parm->sn);
+    }
+
+
  again:
   if (is_status_enabled())
     write_status_text (STATUS_NEED_PASSPHRASE_PIN,
@@ -691,7 +747,10 @@
                           newpin?  _("Enter New PIN: ") :
                           isadmin? _("Enter Admin PIN: ")
                                  : _("Enter PIN: "),
+                          cacheid,
                           &canceled);
+  xfree (cacheid);
+  cacheid = NULL;
   again_text = NULL;
   if (!value && canceled)
     return -1;
@@ -702,7 +761,7 @@
     {
       char *value2;
 
-      value2 = ask_passphrase (info, NULL,
+      value2 = ask_passphrase (info, NULL, NULL,
                                "passphrase.pin.repeat", 
                                _("Repeat this PIN: "),
                               &canceled);
@@ -837,11 +896,14 @@
                   const unsigned char *indata, size_t indatalen,
                   unsigned char **r_buf, size_t *r_buflen)
 {
+  struct pincb_parm_s parm;
   APP app;
   int rc;
 
   *r_buf = NULL;
   *r_buflen = 0;
+  memset (&parm, 0, sizeof parm);
+  parm.sn = serialno;
  retry:
   app = current_app? current_app : open_card ();
   if (!app)
@@ -854,11 +916,14 @@
 
   if (!rc)
     rc = app->fnc.sign (app, serialno, hashalgo,
-                        pin_cb, NULL,
+                        pin_cb, &parm,
                         indata, indatalen,
                         r_buf, r_buflen);
   if (rc)
-    write_status (STATUS_SC_OP_FAILURE);
+    {
+      write_status (STATUS_SC_OP_FAILURE);
+      agent_clear_pin_cache (serialno);
+    }
   return rc;
 }
 
@@ -869,11 +934,14 @@
                      const unsigned char *indata, size_t indatalen,
                      unsigned char **r_buf, size_t *r_buflen)
 {
+  struct pincb_parm_s parm;
   APP app;
   int rc;
 
   *r_buf = NULL;
   *r_buflen = 0;
+  memset (&parm, 0, sizeof parm);
+  parm.sn = serialno;
  retry:
   app = current_app? current_app : open_card ();
   if (!app)
@@ -886,11 +954,14 @@
 
   if (!rc)
     rc = app->fnc.decipher (app, serialno, 
-                            pin_cb, NULL,
+                            pin_cb, &parm,
                             indata, indatalen,
                             r_buf, r_buflen);
   if (rc)
-    write_status (STATUS_SC_OP_FAILURE);
+    {
+      write_status (STATUS_SC_OP_FAILURE);
+      agent_clear_pin_cache (serialno);
+    }
   return rc;
 }
 
@@ -960,3 +1031,15 @@
     write_status (STATUS_SC_OP_FAILURE);
   return rc;
 }
+
+
+void
+agent_clear_pin_cache (const char *sn)
+{
+  char *cacheid = format_cacheid (sn);
+  if (cacheid)
+    {
+      passphrase_clear_cache (NULL, cacheid, 0);
+      xfree (cacheid);
+    }
+}
Index: gnupg/g10/cardglue.h
diff -u gnupg/g10/cardglue.h:1.13 gnupg/g10/cardglue.h:1.14
--- gnupg/g10/cardglue.h:1.13	Fri Dec 10 11:49:14 2004
+++ gnupg/g10/cardglue.h	Wed May  4 00:27:07 2005
@@ -194,6 +194,10 @@
                             const unsigned char *m, size_t mlen,
                             const unsigned char *e, size_t elen);
 
+/* Clear a cached PIN. */
+void agent_clear_pin_cache (const char *sn);
+
+
 #endif /*ENABLE_CARD_SUPPORT*/
 #endif /*GNUPG_G10_CARDGLUE_H*/
 
Index: gnupg/g10/keydb.h
diff -u gnupg/g10/keydb.h:1.88 gnupg/g10/keydb.h:1.89
--- gnupg/g10/keydb.h:1.88	Thu Jan 20 18:21:40 2005
+++ gnupg/g10/keydb.h	Wed May  4 00:27:07 2005
@@ -186,11 +186,12 @@
 /*-- passphrase.h --*/
 int  have_static_passphrase(void);
 void read_passphrase_from_fd( int fd );
-void passphrase_clear_cache ( u32 *keyid, int algo );
+void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo );
 char *ask_passphrase (const char *description,
                       const char *tryagain_text,
                       const char *promptid,
-                      const char *prompt, int *canceled);
+                      const char *prompt, 
+                      const char *cacheid, int *canceled);
 DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
 			int cipher_algo, STRING2KEY *s2k, int mode,
                         const char *tryagain_text, int *canceled);
Index: gnupg/g10/passphrase.c
diff -u gnupg/g10/passphrase.c:1.77 gnupg/g10/passphrase.c:1.78
--- gnupg/g10/passphrase.c:1.77	Tue Apr  5 19:09:12 2005
+++ gnupg/g10/passphrase.c	Wed May  4 00:27:07 2005
@@ -425,10 +425,13 @@
  *
  * Note that TRYAGAIN_TEXT must not be translated.  If canceled is not
  * NULL, the function does set it to 1 if the user canceled the
- * operation.
+ * operation.  If CACHEID is not NULL, it will be used as the cacheID
+ * for the gpg-agent; if is NULL and a key fingerprint can be
+ * computed, this will be used as the cacheid.
  */
 static char *
-agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text,
+agent_get_passphrase ( u32 *keyid, int mode, const char *cacheid,
+                       const char *tryagain_text,
                        const char *custom_description,
                        const char *custom_prompt, int *canceled)
 {
@@ -545,11 +548,16 @@
       line = xmalloc (15 + 46 
                       + 3*strlen (atext)
                       + 3*strlen (custom_prompt? custom_prompt:"")
+                      + (cacheid? (3*strlen (cacheid)): 0)
                       + 3*strlen (tryagain_text)
                       + 1);
       strcpy (line, "GET_PASSPHRASE ");
       p = line+15;
-      if (!mode && have_fpr)
+      if (!mode && cacheid)
+        {
+          p = percent_plus_escape (p, cacheid);
+        }
+      else if (!mode && have_fpr)
         {
           for (i=0; i < 20; i++, p +=2 )
             sprintf (p, "%02X", fpr[i]);
@@ -629,10 +637,11 @@
 
 
 /*
- * Clear the cached passphrase
+ * Clear the cached passphrase.  If CACHEID is not NULL, it will be
+ * used instead of a cache ID derived from KEYID.
  */
 void
-passphrase_clear_cache ( u32 *keyid, int algo )
+passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
 {
 #ifdef ENABLE_AGENT_SUPPORT
   assuan_context_t ctx = NULL;
@@ -646,17 +655,22 @@
   if (!opt.use_agent)
     return;
   
-  pk = xcalloc (1, sizeof *pk);
-  memset (fpr, 0, MAX_FINGERPRINT_LEN );
-  if( !keyid || get_pubkey( pk, keyid ) )
+  if (!cacheid)
     {
-      goto failure; /* oops: no key for some reason */
-    }
+      pk = xcalloc (1, sizeof *pk);
+      memset (fpr, 0, MAX_FINGERPRINT_LEN );
+      if( !keyid || get_pubkey( pk, keyid ) )
+        {
+          goto failure; /* oops: no key for some reason */
+        }
   
-  {
-    size_t dummy;
-    fingerprint_from_pk( pk, fpr, &dummy );
-  }
+      {
+        size_t dummy;
+        fingerprint_from_pk( pk, fpr, &dummy );
+      }
+    }
+  else
+    pk = NULL;
     
   if ( !(ctx = agent_open ()) ) 
     goto failure;
@@ -665,11 +679,21 @@
       char *line, *p;
       int i, rc; 
 
-      line = xmalloc (17 + 40 + 2);
-      strcpy (line, "CLEAR_PASSPHRASE ");
-      p = line+17;
-      for (i=0; i < 20; i++, p +=2 )
-        sprintf (p, "%02X", fpr[i]);
+      if (cacheid)
+        {
+          line = xmalloc (17 + 3*strlen (cacheid) + 2);
+          strcpy (line, "CLEAR_PASSPHRASE ");
+          p = line+17;
+          p = percent_plus_escape (p, cacheid);
+        }
+      else
+        {
+          line = xmalloc (17 + 40 + 2);
+          strcpy (line, "CLEAR_PASSPHRASE ");
+          p = line+17;
+          for (i=0; i < 20; i++, p +=2 )
+            sprintf (p, "%02X", fpr[i]);
+        }
       *p = 0;
 
       rc = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -696,7 +720,8 @@
 ask_passphrase (const char *description,
                 const char *tryagain_text,
                 const char *promptid,
-                const char *prompt, int *canceled)
+                const char *prompt,
+                const char *cacheid, int *canceled)
 {
   char *pw = NULL;
   
@@ -709,7 +734,7 @@
  agent_died:
   if ( opt.use_agent ) 
     {
-      pw = agent_get_passphrase (NULL, 0,
+      pw = agent_get_passphrase (NULL, 0, cacheid,
                                  tryagain_text, description, prompt,
                                  canceled );
       if (!pw)
@@ -853,7 +878,7 @@
     }
     else if ( opt.use_agent ) {
       /* Divert to the gpg-agent. */
-	pw = agent_get_passphrase ( keyid, mode == 2? 1: 0,
+        pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, NULL,
                                     tryagain_text, NULL, NULL, canceled );
         if (!pw)
           {
@@ -862,7 +887,7 @@
             pw = m_strdup ("");
           }
         if( *pw && mode == 2 ) {
-          char *pw2 = agent_get_passphrase ( keyid, 2, NULL, NULL,
+            char *pw2 = agent_get_passphrase ( keyid, 2, NULL, NULL, NULL,
                                                NULL, canceled );
             if (!pw2)
               {
Index: gnupg/g10/seckey-cert.c
diff -u gnupg/g10/seckey-cert.c:1.75 gnupg/g10/seckey-cert.c:1.76
--- gnupg/g10/seckey-cert.c:1.75	Mon Dec 20 11:05:20 2004
+++ gnupg/g10/seckey-cert.c	Wed May  4 00:27:07 2005
@@ -203,7 +203,7 @@
 	/* now let's see whether we have used the right passphrase */
 	if( csum != sk->csum ) {
 	    copy_secret_key( sk, save_sk );
-            passphrase_clear_cache ( keyid, sk->pubkey_algo );
+            passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
 	    free_secret_key( save_sk );
 	    return G10ERR_BAD_PASS;
 	}
@@ -211,7 +211,7 @@
 	res = pubkey_check_secret_key( sk->pubkey_algo, sk->skey );
 	if( res ) {
 	    copy_secret_key( sk, save_sk );
-            passphrase_clear_cache ( keyid, sk->pubkey_algo );
+            passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
 	    free_secret_key( save_sk );
 	    return G10ERR_BAD_PASS;
 	}
Index: gnupg/g10/sign.c
diff -u gnupg/g10/sign.c:1.136 gnupg/g10/sign.c:1.137
--- gnupg/g10/sign.c:1.136	Sun Apr 17 06:10:03 2005
+++ gnupg/g10/sign.c	Wed May  4 00:27:07 2005
@@ -808,6 +808,8 @@
       }
 
     mfx.md = md_open(0, 0);
+    if (DBG_HASHING)
+	md_start_debug (mfx.md, "sign");
 
    /* If we're encrypting and signing, it is reasonable to pick the
        hash algorithm to use out of the recepient key prefs. */
@@ -1217,6 +1219,8 @@
     if (opt.textmode)
 	iobuf_push_filter (inp, text_filter, &tfx);
     mfx.md = md_open(0, 0);
+    if ( DBG_HASHING )
+	md_start_debug (mfx.md, "symc-sign");
 
     for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
 	PKT_secret_key *sk = sk_rover->sk;




More information about the Gnupg-commits mailing list