* card-util.c (card_edit): New command "passwd". Add logic to
authorWerner Koch <wk@gnupg.org>
Tue, 21 Oct 2003 17:12:21 +0000 (17:12 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 21 Oct 2003 17:12:21 +0000 (17:12 +0000)
check the PIN in advance.
(card_status): Add new args to return the serial number.  Changed
all callers.
* call-agent.c (agent_scd_checkpin): New.

doc/scdaemon.texi
g10/ChangeLog
g10/call-agent.c
g10/call-agent.h
g10/card-util.c
g10/g10.c
g10/main.h

index 36274e6..3bd8caa 100644 (file)
@@ -191,6 +191,12 @@ syncronizing access to a token between sessions.
 * Scdaemon READKEY::      Return a public key.
 * Scdaemon PKSIGN::       Signing data with a Smartcard.
 * Scdaemon PKDECRYPT::    Decrypting data with a Smartcard.
+* Scdaemon GETATTR::      Read an attribute's value.
+* Scdaemon SETATTR::      Update an attribute's value.
+* Scdaemon GENKEY::       Generate a new key on-card.
+* Scdaemon RANDOM::       Return random bytes generate on-card.
+* Scdaemon PASSWD::       Change PINs.
+* Scdaemon CHECKPIN::     Perform a VERIFY operation.
 @end menu
 
 @node Scdaemon SERIALNO 
@@ -309,3 +315,37 @@ hex notation.  The actual decryption is then done using the command
 
 where @var{keyid} is the hexified ID of the key to be used.
 
+
+@node Scdaemon GETATTR
+@subsection Read an attribute's value.
+
+TO BE WRITTEN.
+
+@node Scdaemon SETATTR
+@subsection Update an attribute's value.
+
+TO BE WRITTEN.
+
+@node Scdaemon GENKEY
+@subsection Generate a new key on-card.
+
+TO BE WRITTEN.
+
+@node Scdaemon RANDOM
+@subsection Return random bytes generate on-card.
+
+TO BE WRITTEN.
+
+
+@node Scdaemon PASSWD
+@subsection Change PINs.
+
+TO BE WRITTEN.
+
+
+@node Scdaemon CHECKPIN
+@subsection Perform a VERIFY operation.
+
+TO BE WRITTEN.
+
+
index cb5a8ad..80216ce 100644 (file)
@@ -1,3 +1,11 @@
+2003-10-20  Werner Koch  <wk@gnupg.org>
+
+       * card-util.c (card_edit): New command "passwd".  Add logic to
+       check the PIN in advance.
+       (card_status): Add new args to return the serial number.  Changed
+       all callers.
+       * call-agent.c (agent_scd_checkpin): New.
+
 2003-10-08  Werner Koch  <wk@gnupg.org>
 
        * call-agent.c (agent_scd_getattr): Don't clear the passed info
index c6c8faa..9ca127c 100644 (file)
@@ -869,3 +869,25 @@ agent_scd_change_pin (int chvno)
   return map_assuan_err (rc);
 }
 
+
+/* Perform a CHECKPIN operation.  SERIALNO should be the seriial
+   number of the card - optioanlly followed by the fingerprint;
+   however the fingerprint is ignored here. */
+int
+agent_scd_checkpin  (const char *serialno)
+{
+  int rc;
+  char line[ASSUAN_LINELENGTH];
+
+  rc = start_agent ();
+  if (rc)
+    return rc;
+
+  snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
+  line[DIM(line)-1] = 0;
+  return assuan_transact (agent_ctx, line,
+                          NULL, NULL,
+                          NULL, NULL, NULL, NULL);
+}
+
+
index 101db95..8751101 100644 (file)
@@ -85,6 +85,10 @@ int agent_scd_pkdecrypt (const char *serialno,
 /* Change the PIN of an OpenPGP card or reset the retry counter. */
 int agent_scd_change_pin (int chvno);
 
+/* Send the CHECKPIN command to the SCdaemon. */
+int agent_scd_checkpin  (const char *serialno);
+
+
 
 #endif /*GNUPG_G10_CALL_AGENT_H*/
 
index 6699277..de445b7 100644 (file)
@@ -255,13 +255,16 @@ fpr_is_zero (const char *fpr)
 
 /* Print all available information about the current card. */
 void
-card_status (FILE *fp)
+card_status (FILE *fp, char *serialno, size_t serialnobuflen)
 {
   struct agent_card_info_s info;
   PKT_public_key *pk = xcalloc (1, sizeof *pk);
   int rc;
   unsigned int uval;
 
+  if (serialno && serialnobuflen)
+    *serialno = 0;
+
   rc = agent_learn (&info);
   if (rc)
     {
@@ -289,6 +292,13 @@ card_status (FILE *fp)
       return;
     }
 
+  if (!serialno)
+    ;
+  else if (strlen (serialno)+1 > serialnobuflen)
+    log_error ("serial number longer than expected\n");
+  else 
+    strcpy (serialno, info.serialno);
+
   if (opt.with_colons)
     fputs ("openpgp-card:\n", fp);
 
@@ -660,29 +670,33 @@ card_edit (STRLIST commands)
     cmdNOP = 0,
     cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
     cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
-    cmdFORCESIG, cmdGENERATE,
+    cmdFORCESIG, cmdGENERATE, cmdPASSWD,
     cmdINVCMD
   };
 
   static struct {
     const char *name;
     enum cmdids id;
+    int requires_pin;
     const char *desc;
   } cmds[] = {
-    { N_("quit")  , cmdQUIT  , N_("quit this menu") },
-    { N_("q")     , cmdQUIT  , NULL   },
-    { N_("help")  , cmdHELP  , N_("show this help") },
-    {    "?"      , cmdHELP  , NULL   },
-    { N_("list")  , cmdLIST  , N_("list all available data") },
-    { N_("l")     , cmdLIST  , NULL   },
-    { N_("debug") , cmdDEBUG , NULL },
-    { N_("name")  , cmdNAME  , N_("change card holder's name") },
-    { N_("url")   , cmdURL   , N_("change URL to retrieve key") },
-    { N_("login") , cmdLOGIN , N_("change the login name") },
-    { N_("lang")  , cmdLANG  , N_("change the language preferences") },
-    { N_("sex")   , cmdSEX   , N_("change card holder's sex") },
-    { N_("forcesig"), cmdFORCESIG, N_("toggle the signature force PIN flag") },
-    { N_("generate"), cmdGENERATE, N_("generate new keys") },
+    { N_("quit")  , cmdQUIT  , 0, N_("quit this menu") },
+    { N_("q")     , cmdQUIT  , 0, NULL   },
+    { N_("help")  , cmdHELP  , 0, N_("show this help") },
+    {    "?"      , cmdHELP  , 0, NULL   },
+    { N_("list")  , cmdLIST  , 0, N_("list all available data") },
+    { N_("l")     , cmdLIST  , 0, NULL   },
+    { N_("debug") , cmdDEBUG , 0, NULL },
+    { N_("name")  , cmdNAME  , 1, N_("change card holder's name") },
+    { N_("url")   , cmdURL   , 1, N_("change URL to retrieve key") },
+    { N_("login") , cmdLOGIN , 1, N_("change the login name") },
+    { N_("lang")  , cmdLANG  , 1, N_("change the language preferences") },
+    { N_("sex")   , cmdSEX   , 1, N_("change card holder's sex") },
+    { N_("forcesig"),
+                  cmdFORCESIG, 1, N_("toggle the signature force PIN flag") },
+    { N_("generate"),
+                  cmdGENERATE, 1, N_("generate new keys") },
+    { N_("passwd"), cmdPASSWD, 0, N_("menu to change or unblock the PIN") },
     { NULL, cmdINVCMD } 
   };
  
@@ -690,6 +704,9 @@ card_edit (STRLIST commands)
   int have_commands = !!commands;
   int redisplay = 1;
   char *answer = NULL;
+  int did_checkpin = 0;
+  char serialnobuf[50];
+
 
   if (opt.command_fd != -1)
     ;
@@ -705,18 +722,19 @@ card_edit (STRLIST commands)
       const char *arg_string = "";
       char *p;
       int i;
-
+      int requires_pin;
+      
       tty_printf("\n");
       if (redisplay )
         {
           if (opt.with_colons)
             {
-              card_status (stdout);
+              card_status (stdout, serialnobuf, DIM (serialnobuf));
               fflush (stdout);
             }
           else
             {
-              card_status (NULL);
+              card_status (NULL, serialnobuf, DIM (serialnobuf));
               tty_printf("\n");
             }
           redisplay = 0;
@@ -750,6 +768,7 @@ card_edit (STRLIST commands)
       while( *answer == '#' );
 
       arg_number = 0; /* Yes, here is the init which egcc complains about */
+      requires_pin = 0;
       if (!*answer)
         cmd = cmdLIST; /* Default to the list command */
       else if (*answer == CONTROL_D)
@@ -769,7 +788,19 @@ card_edit (STRLIST commands)
             break;
 
         cmd = cmds[i].id;
+        requires_pin = cmds[i].requires_pin;
       }
+      
+      if (requires_pin && !did_checkpin)
+        {
+          int rc = agent_scd_checkpin (serialnobuf);
+          if (rc)
+            {
+              log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
+              continue;
+            }
+          did_checkpin = 1;
+        }
 
       switch (cmd)
         {
@@ -811,6 +842,11 @@ card_edit (STRLIST commands)
           generate_card_keys ();
           break;
 
+        case cmdPASSWD:
+          change_pin (0);
+          did_checkpin = 0; /* Need to reset it of course. */
+          break;
+
         case cmdQUIT:
           goto leave;
 
index 984e50d..77e6f6c 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -2844,7 +2844,7 @@ main( int argc, char **argv )
     case aCardStatus:
       if (argc)
         wrong_args ("--card-status");
-      card_status (stdout);
+      card_status (stdout, NULL, 0);
       break;
 
     case aCardEdit:
index d00044c..52bfa76 100644 (file)
@@ -260,7 +260,7 @@ void run_in_pipemode (void);
 
 /*-- card-util.c --*/
 void change_pin (int no);
-void card_status (FILE *fp);
+void card_status (FILE *fp, char *serialnobuf, size_t serialnobuflen);
 void card_edit (STRLIST commands);
 
 /*-- signal.c --*/