diff options
author | Werner Koch <[email protected]> | 2005-10-18 17:41:20 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2005-10-18 17:41:20 +0000 |
commit | c8571979efc165cfe2616add2d44aa876ff1f551 (patch) | |
tree | b683a50a299ea5d3b76deb81f855737f185fc45b | |
parent | exported subkeys are now merged into one output keyblock (diff) | |
download | gnupg-c8571979efc165cfe2616add2d44aa876ff1f551.tar.gz gnupg-c8571979efc165cfe2616add2d44aa876ff1f551.zip |
Fixed minor card related bugs and enhanced status messages
Diffstat (limited to '')
-rw-r--r-- | doc/DETAILS | 8 | ||||
-rw-r--r-- | g10/ChangeLog | 16 | ||||
-rw-r--r-- | g10/card-util.c | 33 | ||||
-rw-r--r-- | g10/cardglue.c | 106 | ||||
-rw-r--r-- | g10/cardglue.h | 12 | ||||
-rw-r--r-- | g10/keygen.c | 10 |
6 files changed, 129 insertions, 56 deletions
diff --git a/doc/DETAILS b/doc/DETAILS index 8ffd9145d..df1803919 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -330,7 +330,7 @@ more arguments in future versions. NEED_PASSPHRASE_SYM <cipher_algo> <s2k_mode> <s2k_hash> Issued whenever a passphrase for symmetric encryption is needed. - NEED_PASSPHRASE_PIN <card_type> <chvno> + NEED_PASSPHRASE_PIN <card_type> <chvno> [<serialno>] Issued whenever a PIN is requested to unlock a card. MISSING_PASSPHRASE @@ -572,10 +572,14 @@ more arguments in future versions. This indicates that a signature subpacket was seen. The format is the same as the "spk" record above. - SC_OP_FAILURE + SC_OP_FAILURE [<code>] An operation on a smartcard definitely failed. Currently there is no indication of the actual error code, but application should be prepared to later accept more arguments. + Defined values for CODE are: + 0 - unspecified error (identically to a missing CODE) + 1 - canceled + 2 - bad PIN SC_OP_SUCCESS A smart card operaion succeeded. This status is only printed diff --git a/g10/ChangeLog b/g10/ChangeLog index 272df32ca..46f0a4179 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,19 @@ +2005-10-18 Werner Koch <[email protected]> + + * cardglue.c (pin_cb): Fixed prompt for repeated PIN. Return + G10ERR_CANCELED and not just -1. + (status_sc_op_failure): New. Use it where we issue that status. + (pin_cb): Append serial number to the need-pin status message. + (agent_scd_change_pin): Add arg SERIALNO. Changed all callers. + (agent_scd_writekey): Ditto. + (agent_scd_setattr): Ditto. + (agent_scd_genkey): Ditto. + (agent_scd_checkpin): Pass serialno to the pin_cb. + + * keygen.c (parse_expire_string): Allow setting the expire + interval using a "seconds=<n>" syntax. This is useful for + debugging. + 2005-10-17 Werner Koch <[email protected]> * export.c (do_export_stream): Factored some code out to ... diff --git a/g10/card-util.c b/g10/card-util.c index 6159512c1..d9e9d8906 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -70,17 +70,16 @@ change_pin (int chvno, int allow_admin) agent_clear_pin_cache (info.serialno); - agent_release_card_info (&info); - if (opt.batch) { + agent_release_card_info (&info); log_error (_("can't do this in batch mode\n")); return; } if(!allow_admin) { - rc = agent_scd_change_pin (1); + rc = agent_scd_change_pin (1, info.serialno); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); else @@ -109,7 +108,7 @@ change_pin (int chvno, int allow_admin) rc = 0; if (*answer == '1') { - rc = agent_scd_change_pin (1); + rc = agent_scd_change_pin (1, info.serialno); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); else @@ -120,7 +119,7 @@ change_pin (int chvno, int allow_admin) } else if (*answer == '2') { - rc = agent_scd_change_pin (101); + rc = agent_scd_change_pin (101, info.serialno); if (rc) tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc)); else @@ -131,7 +130,7 @@ change_pin (int chvno, int allow_admin) } else if (*answer == '3') { - rc = agent_scd_change_pin (3); + rc = agent_scd_change_pin (3, info.serialno); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); else @@ -145,6 +144,8 @@ change_pin (int chvno, int allow_admin) break; } } + + agent_release_card_info (&info); } static const char * @@ -561,7 +562,7 @@ change_name (void) return -1; } - rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) ); + rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL ); if (rc) log_error ("error setting Name: %s\n", gpg_strerror (rc)); @@ -590,7 +591,7 @@ change_url (void) return -1; } - rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) ); + rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL ); if (rc) log_error ("error setting URL: %s\n", gpg_strerror (rc)); xfree (url); @@ -706,7 +707,7 @@ change_login (const char *args) return -1; } - rc = agent_scd_setattr ("LOGIN-DATA", data, n ); + rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL ); if (rc) log_error ("error setting login data: %s\n", gpg_strerror (rc)); xfree (data); @@ -775,7 +776,7 @@ change_private_do (const char *args, int nr) return -1; } - rc = agent_scd_setattr (do_name, data, n ); + rc = agent_scd_setattr (do_name, data, n, NULL ); if (rc) log_error ("error setting private DO: %s\n", gpg_strerror (rc)); xfree (data); @@ -811,7 +812,7 @@ change_lang (void) return -1; } - rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) ); + rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL ); if (rc) log_error ("error setting lang: %s\n", gpg_strerror (rc)); xfree (data); @@ -846,7 +847,7 @@ change_sex (void) return -1; } - rc = agent_scd_setattr ("DISP-SEX", str, 1 ); + rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL ); if (rc) log_error ("error setting sex: %s\n", gpg_strerror (rc)); xfree (data); @@ -891,7 +892,7 @@ change_cafpr (int fprno) rc = agent_scd_setattr (fprno==1?"CA-FPR-1": fprno==2?"CA-FPR-2": - fprno==3?"CA-FPR-3":"x", fpr, 20 ); + fprno==3?"CA-FPR-3":"x", fpr, 20, NULL ); if (rc) log_error ("error setting cafpr: %s\n", gpg_strerror (rc)); return rc; @@ -916,7 +917,7 @@ toggle_forcesig (void) newstate = !info.chv1_cached; agent_release_card_info (&info); - rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1); + rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL); if (rc) log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc)); } @@ -961,7 +962,7 @@ check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1) { /* Switch of the forced mode so that during key generation we don't get bothered with PIN queries for each self-signature. */ - rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1); + rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno); if (rc) { log_error ("error clearing forced signature PIN flag: %s\n", @@ -989,7 +990,7 @@ restore_forced_chv1 (int *forced_chv1) if (*forced_chv1) { /* Switch back to forced state. */ - rc = agent_scd_setattr ("CHV-STATUS-1", "", 1); + rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL); if (rc) { log_error ("error setting forced signature PIN flag: %s\n", diff --git a/g10/cardglue.c b/g10/cardglue.c index 6330b73d3..c165adcca 100644 --- a/g10/cardglue.c +++ b/g10/cardglue.c @@ -520,6 +520,20 @@ format_cacheid (const char *sn) return cacheid; } + +/* If RC is not 0, write an appropriate status message. */ +static void +status_sc_op_failure (int rc) +{ + if (rc == G10ERR_CANCELED) + write_status_text (STATUS_SC_OP_FAILURE, "1"); + else if (rc == G10ERR_BAD_PASS) + write_status_text (STATUS_SC_OP_FAILURE, "2"); + else if (rc) + write_status (STATUS_SC_OP_FAILURE); +} + + /* 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 @@ -880,8 +894,18 @@ pin_cb (void *opaque, const char *info, char **retstr) again: if (is_status_enabled()) - write_status_text (STATUS_NEED_PASSPHRASE_PIN, - isadmin? "OPENPGP 3" : "OPENPGP 1"); + { + if (parm && parm->sn && *parm->sn) + { + char *buf = xmalloc ( 10 + strlen (parm->sn) + 1); + strcpy (stpcpy (buf, isadmin? "OPENPGP 3 ":"OPENPGP 1 "), parm->sn); + write_status_text (STATUS_NEED_PASSPHRASE_PIN, buf); + xfree (buf); + } + else + write_status_text (STATUS_NEED_PASSPHRASE_PIN, + isadmin? "OPENPGP 3" : "OPENPGP 1"); + } value = ask_passphrase (info, again_text, newpin && isadmin? "passphrase.adminpin.new.ask" : @@ -898,7 +922,7 @@ pin_cb (void *opaque, const char *info, char **retstr) cacheid = NULL; again_text = NULL; if (!value && canceled) - return -1; + return G10ERR_CANCELED; else if (!value) return G10ERR_GENERAL; @@ -906,16 +930,17 @@ pin_cb (void *opaque, const char *info, char **retstr) { char *value2; - value2 = ask_passphrase (info, NULL, NULL, + value2 = ask_passphrase (info, NULL, "passphrase.pin.repeat", _("Repeat this PIN: "), - &canceled); - if (!value && canceled) + NULL, + &canceled); + if (!value2 && canceled) { xfree (value); - return -1; + return G10ERR_CANCELED; } - else if (!value) + else if (!value2) { xfree (value); return G10ERR_GENERAL; @@ -940,10 +965,15 @@ pin_cb (void *opaque, const char *info, char **retstr) /* Send a SETATTR command to the SCdaemon. */ int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen) + const unsigned char *value, size_t valuelen, + const char *serialno) { app_t app; int rc; + struct pincb_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.sn = serialno; app = current_app? current_app : open_card (); if (!app) @@ -981,11 +1011,10 @@ agent_scd_setattr (const char *name, } else { - rc = app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen); + rc = app->fnc.setattr (app, name, pin_cb, &parm, value, valuelen); } - if (rc) - write_status (STATUS_SC_OP_FAILURE); + status_sc_op_failure (rc); return rc; } @@ -1003,11 +1032,17 @@ inq_writekey_parms (void *opaque, const char *keyword) /* Send a WRITEKEY command to the SCdaemon. */ int -agent_scd_writekey (int keyno, const unsigned char *keydata, size_t keydatalen) +agent_scd_writekey (int keyno, const char *serialno, + const unsigned char *keydata, size_t keydatalen) { app_t app; int rc; char line[ASSUAN_LINELENGTH]; + struct pincb_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.sn = serialno; + app = current_app? current_app : open_card (); if (!app) return gpg_error (GPG_ERR_CARD); @@ -1032,12 +1067,11 @@ agent_scd_writekey (int keyno, const unsigned char *keydata, size_t keydatalen) snprintf (line, DIM(line)-1, "OPENPGP.%d", keyno); line[DIM(line)-1] = 0; rc = app->fnc.writekey (app, NULL, line, 0x0001, - pin_cb, NULL, + pin_cb, &parm, keydata, keydatalen); } - if (rc) - write_status (STATUS_SC_OP_FAILURE); + status_sc_op_failure (rc); return rc; } @@ -1097,12 +1131,17 @@ genkey_status_cb (void *opaque, const char *line) /* Send a GENKEY command to the SCdaemon. */ int -agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force) +agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force, + const char *serialno) { app_t app; char line[ASSUAN_LINELENGTH]; struct ctrl_ctx_s ctrl; int rc; + struct pincb_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.sn = serialno; app = current_app? current_app : open_card (); if (!app) @@ -1127,11 +1166,10 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force) ctrl.status_cb_arg = info; rc = app->fnc.genkey (app, &ctrl, line, force? 1:0, - pin_cb, NULL); + pin_cb, &parm); } - if (rc) - write_status (STATUS_SC_OP_FAILURE); + status_sc_op_failure (rc); return rc; } @@ -1213,7 +1251,7 @@ agent_scd_pksign (const char *serialno, int hashalgo, if (rc) { - write_status (STATUS_SC_OP_FAILURE); + status_sc_op_failure (rc); if (!app->assuan_ctx) agent_clear_pin_cache (serialno); } @@ -1287,20 +1325,26 @@ agent_scd_pkdecrypt (const char *serialno, if (rc) { - write_status (STATUS_SC_OP_FAILURE); + status_sc_op_failure (rc); if (!app->assuan_ctx) agent_clear_pin_cache (serialno); } return rc; } -/* Change the PIN of an OpenPGP card or reset the retry counter. */ +/* Change the PIN of an OpenPGP card or reset the retry + counter. SERIALNO may be NULL or a hex string finally passed to the + passphrase callback. */ int -agent_scd_change_pin (int chvno) +agent_scd_change_pin (int chvno, const char *serialno) { app_t app; int reset = 0; int rc; + struct pincb_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.sn = serialno; reset = (chvno >= 100); chvno %= 100; @@ -1326,11 +1370,10 @@ agent_scd_change_pin (int chvno) sprintf (chvnostr, "%d", chvno); rc = app->fnc.change_pin (app, NULL, chvnostr, reset, - pin_cb, NULL); + pin_cb, &parm); } - if (rc) - write_status (STATUS_SC_OP_FAILURE); + status_sc_op_failure (rc); return rc; } @@ -1342,6 +1385,10 @@ agent_scd_checkpin (const char *serialnobuf) { app_t app; int rc; + struct pincb_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.sn = serialnobuf; app = current_app? current_app : open_card (); if (!app) @@ -1360,11 +1407,10 @@ agent_scd_checkpin (const char *serialnobuf) } else { - rc = app->fnc.check_pin (app, serialnobuf, pin_cb, NULL); + rc = app->fnc.check_pin (app, serialnobuf, pin_cb, &parm); } - if (rc) - write_status (STATUS_SC_OP_FAILURE); + status_sc_op_failure (rc); return rc; } diff --git a/g10/cardglue.h b/g10/cardglue.h index 5699fe959..b1f2811df 100644 --- a/g10/cardglue.h +++ b/g10/cardglue.h @@ -82,7 +82,7 @@ typedef struct ctrl_ctx_s *ctrl_t; #define GPG_ERR_GENERAL G10ERR_GENERAL #define GPG_ERR_BAD_PIN G10ERR_BAD_PASS -#define GPG_ERR_BAD_KEy G10ERR_BAD_KEY +#define GPG_ERR_BAD_KEY G10ERR_BAD_KEY #define GPG_ERR_CARD G10ERR_GENERAL #define GPG_ERR_EEXIST G10ERR_FILE_EXISTS #define GPG_ERR_ENOMEM G10ERR_RESOURCE_LIMIT @@ -175,14 +175,16 @@ int agent_scd_getattr (const char *name, struct agent_card_info_s *info); /* Send a SETATTR command to the SCdaemon. */ int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen); + const unsigned char *value, size_t valuelen, + const char *serialno); /* Send a WRITEKEY command to the SCdaemon. */ -int agent_scd_writekey (int keyno, +int agent_scd_writekey (int keyno, const char *serialno, const unsigned char *keydata, size_t keydatalen); /* Send a GENKEY command to the SCdaemon. */ -int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force); +int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force, + const char *serialno); /* Send a PKSIGN command to the SCdaemon. */ int agent_scd_pksign (const char *keyid, int hashalgo, @@ -195,7 +197,7 @@ int agent_scd_pkdecrypt (const char *serialno, unsigned char **r_buf, size_t *r_buflen); /* Change the PIN of an OpenPGP card or reset the retry counter. */ -int agent_scd_change_pin (int chvno); +int agent_scd_change_pin (int chvno, const char *serialno); /* Send a CHECKPIN command. */ int agent_scd_checkpin (const char *serialnobuf); diff --git a/g10/keygen.c b/g10/keygen.c index ae1ac6334..d2348c07c 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1492,6 +1492,8 @@ parse_expire_string( const char *string ) if( !*string ) seconds = 0; + else if ( !strncmp (string, "seconds=", 8) ) + seconds = atoi (string+8); else if( (abs_date = scan_isodatestr(string)) && abs_date > curtime ) seconds = abs_date - curtime; else if( (mult=check_valid_days(string)) ) @@ -3274,8 +3276,8 @@ gen_card_key (int algo, int keyno, int is_primary, assert (algo == PUBKEY_ALGO_RSA); - - rc = agent_scd_genkey (&info, keyno, 1); + /* Fixme: We don't have the serialnumber available, thus passing NULL. */ + rc = agent_scd_genkey (&info, keyno, 1, NULL); /* if (gpg_err_code (rc) == GPG_ERR_EEXIST) */ /* { */ /* tty_printf ("\n"); */ @@ -3550,7 +3552,9 @@ save_unprotected_key_to_card (PKT_secret_key *sk, int keyno) sprintf (numbuf, "%lu:", (unsigned long)strlen (numbuf2)); p = stpcpy (stpcpy (stpcpy (p, numbuf), numbuf2), "))"); - rc = agent_scd_writekey (keyno, sexp, p - sexp); + /* Fixme: Unfortunately we don't have the serialnumber available - + thus we can't pass it down to the agent. */ + rc = agent_scd_writekey (keyno, NULL, sexp, p - sexp); leave: xfree (sexp); |