From 99277d21c190965d1b7c95b895324f467413f0f1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 21 Oct 2003 17:12:21 +0000 Subject: [PATCH] * 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. --- doc/scdaemon.texi | 40 +++++++++++++++++++++++++ g10/ChangeLog | 8 +++++ g10/call-agent.c | 22 ++++++++++++++ g10/call-agent.h | 4 +++ g10/card-util.c | 74 +++++++++++++++++++++++++++++++++++------------ g10/g10.c | 2 +- g10/main.h | 2 +- 7 files changed, 131 insertions(+), 21 deletions(-) diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 36274e601..3bd8caaa8 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -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. + + diff --git a/g10/ChangeLog b/g10/ChangeLog index cb5a8ad64..80216ced3 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,11 @@ +2003-10-20 Werner Koch + + * 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 * call-agent.c (agent_scd_getattr): Don't clear the passed info diff --git a/g10/call-agent.c b/g10/call-agent.c index c6c8faaec..9ca127c3c 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -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); +} + + diff --git a/g10/call-agent.h b/g10/call-agent.h index 101db9574..875110118 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -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*/ diff --git a/g10/card-util.c b/g10/card-util.c index 669927707..de445b796 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -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; diff --git a/g10/g10.c b/g10/g10.c index 984e50d9c..77e6f6cf9 100644 --- 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: diff --git a/g10/main.h b/g10/main.h index d00044c9f..52bfa7659 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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 --*/