1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-04-17 15:44:34 +02:00

Fixed minor card related bugs and enhanced status messages

This commit is contained in:
Werner Koch 2005-10-18 17:41:20 +00:00
parent 9b7f1f6976
commit c8571979ef
6 changed files with 129 additions and 56 deletions

View File

@ -330,7 +330,7 @@ more arguments in future versions.
NEED_PASSPHRASE_SYM <cipher_algo> <s2k_mode> <s2k_hash> NEED_PASSPHRASE_SYM <cipher_algo> <s2k_mode> <s2k_hash>
Issued whenever a passphrase for symmetric encryption is needed. 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. Issued whenever a PIN is requested to unlock a card.
MISSING_PASSPHRASE MISSING_PASSPHRASE
@ -572,10 +572,14 @@ more arguments in future versions.
This indicates that a signature subpacket was seen. The This indicates that a signature subpacket was seen. The
format is the same as the "spk" record above. format is the same as the "spk" record above.
SC_OP_FAILURE SC_OP_FAILURE [<code>]
An operation on a smartcard definitely failed. Currently An operation on a smartcard definitely failed. Currently
there is no indication of the actual error code, but there is no indication of the actual error code, but
application should be prepared to later accept more arguments. 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 SC_OP_SUCCESS
A smart card operaion succeeded. This status is only printed A smart card operaion succeeded. This status is only printed

View File

@ -1,3 +1,19 @@
2005-10-18 Werner Koch <wk@g10code.com>
* 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 <wk@g10code.com> 2005-10-17 Werner Koch <wk@g10code.com>
* export.c (do_export_stream): Factored some code out to ... * export.c (do_export_stream): Factored some code out to ...

View File

@ -70,17 +70,16 @@ change_pin (int chvno, int allow_admin)
agent_clear_pin_cache (info.serialno); agent_clear_pin_cache (info.serialno);
agent_release_card_info (&info);
if (opt.batch) if (opt.batch)
{ {
agent_release_card_info (&info);
log_error (_("can't do this in batch mode\n")); log_error (_("can't do this in batch mode\n"));
return; return;
} }
if(!allow_admin) if(!allow_admin)
{ {
rc = agent_scd_change_pin (1); rc = agent_scd_change_pin (1, info.serialno);
if (rc) if (rc)
tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
else else
@ -109,7 +108,7 @@ change_pin (int chvno, int allow_admin)
rc = 0; rc = 0;
if (*answer == '1') if (*answer == '1')
{ {
rc = agent_scd_change_pin (1); rc = agent_scd_change_pin (1, info.serialno);
if (rc) if (rc)
tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
else else
@ -120,7 +119,7 @@ change_pin (int chvno, int allow_admin)
} }
else if (*answer == '2') else if (*answer == '2')
{ {
rc = agent_scd_change_pin (101); rc = agent_scd_change_pin (101, info.serialno);
if (rc) if (rc)
tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc)); tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
else else
@ -131,7 +130,7 @@ change_pin (int chvno, int allow_admin)
} }
else if (*answer == '3') else if (*answer == '3')
{ {
rc = agent_scd_change_pin (3); rc = agent_scd_change_pin (3, info.serialno);
if (rc) if (rc)
tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
else else
@ -145,6 +144,8 @@ change_pin (int chvno, int allow_admin)
break; break;
} }
} }
agent_release_card_info (&info);
} }
static const char * static const char *
@ -561,7 +562,7 @@ change_name (void)
return -1; return -1;
} }
rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) ); rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
if (rc) if (rc)
log_error ("error setting Name: %s\n", gpg_strerror (rc)); log_error ("error setting Name: %s\n", gpg_strerror (rc));
@ -590,7 +591,7 @@ change_url (void)
return -1; return -1;
} }
rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) ); rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
if (rc) if (rc)
log_error ("error setting URL: %s\n", gpg_strerror (rc)); log_error ("error setting URL: %s\n", gpg_strerror (rc));
xfree (url); xfree (url);
@ -706,7 +707,7 @@ change_login (const char *args)
return -1; return -1;
} }
rc = agent_scd_setattr ("LOGIN-DATA", data, n ); rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
if (rc) if (rc)
log_error ("error setting login data: %s\n", gpg_strerror (rc)); log_error ("error setting login data: %s\n", gpg_strerror (rc));
xfree (data); xfree (data);
@ -775,7 +776,7 @@ change_private_do (const char *args, int nr)
return -1; return -1;
} }
rc = agent_scd_setattr (do_name, data, n ); rc = agent_scd_setattr (do_name, data, n, NULL );
if (rc) if (rc)
log_error ("error setting private DO: %s\n", gpg_strerror (rc)); log_error ("error setting private DO: %s\n", gpg_strerror (rc));
xfree (data); xfree (data);
@ -811,7 +812,7 @@ change_lang (void)
return -1; return -1;
} }
rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) ); rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
if (rc) if (rc)
log_error ("error setting lang: %s\n", gpg_strerror (rc)); log_error ("error setting lang: %s\n", gpg_strerror (rc));
xfree (data); xfree (data);
@ -846,7 +847,7 @@ change_sex (void)
return -1; return -1;
} }
rc = agent_scd_setattr ("DISP-SEX", str, 1 ); rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
if (rc) if (rc)
log_error ("error setting sex: %s\n", gpg_strerror (rc)); log_error ("error setting sex: %s\n", gpg_strerror (rc));
xfree (data); xfree (data);
@ -891,7 +892,7 @@ change_cafpr (int fprno)
rc = agent_scd_setattr (fprno==1?"CA-FPR-1": rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
fprno==2?"CA-FPR-2": fprno==2?"CA-FPR-2":
fprno==3?"CA-FPR-3":"x", fpr, 20 ); fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
if (rc) if (rc)
log_error ("error setting cafpr: %s\n", gpg_strerror (rc)); log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
return rc; return rc;
@ -916,7 +917,7 @@ toggle_forcesig (void)
newstate = !info.chv1_cached; newstate = !info.chv1_cached;
agent_release_card_info (&info); 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) if (rc)
log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (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 { /* Switch of the forced mode so that during key generation we
don't get bothered with PIN queries for each don't get bothered with PIN queries for each
self-signature. */ self-signature. */
rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1); rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
if (rc) if (rc)
{ {
log_error ("error clearing forced signature PIN flag: %s\n", log_error ("error clearing forced signature PIN flag: %s\n",
@ -989,7 +990,7 @@ restore_forced_chv1 (int *forced_chv1)
if (*forced_chv1) if (*forced_chv1)
{ /* Switch back to forced state. */ { /* Switch back to forced state. */
rc = agent_scd_setattr ("CHV-STATUS-1", "", 1); rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
if (rc) if (rc)
{ {
log_error ("error setting forced signature PIN flag: %s\n", log_error ("error setting forced signature PIN flag: %s\n",

View File

@ -520,6 +520,20 @@ format_cacheid (const char *sn)
return cacheid; 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 /* 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 APP) matches SERIALNO. If there is no match and we are not in
batch mode, present a prompt to insert the desired card. The 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: again:
if (is_status_enabled()) if (is_status_enabled())
{
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, write_status_text (STATUS_NEED_PASSPHRASE_PIN,
isadmin? "OPENPGP 3" : "OPENPGP 1"); isadmin? "OPENPGP 3" : "OPENPGP 1");
}
value = ask_passphrase (info, again_text, value = ask_passphrase (info, again_text,
newpin && isadmin? "passphrase.adminpin.new.ask" : newpin && isadmin? "passphrase.adminpin.new.ask" :
@ -898,7 +922,7 @@ pin_cb (void *opaque, const char *info, char **retstr)
cacheid = NULL; cacheid = NULL;
again_text = NULL; again_text = NULL;
if (!value && canceled) if (!value && canceled)
return -1; return G10ERR_CANCELED;
else if (!value) else if (!value)
return G10ERR_GENERAL; return G10ERR_GENERAL;
@ -906,16 +930,17 @@ pin_cb (void *opaque, const char *info, char **retstr)
{ {
char *value2; char *value2;
value2 = ask_passphrase (info, NULL, NULL, value2 = ask_passphrase (info, NULL,
"passphrase.pin.repeat", "passphrase.pin.repeat",
_("Repeat this PIN: "), _("Repeat this PIN: "),
NULL,
&canceled); &canceled);
if (!value && canceled) if (!value2 && canceled)
{ {
xfree (value); xfree (value);
return -1; return G10ERR_CANCELED;
} }
else if (!value) else if (!value2)
{ {
xfree (value); xfree (value);
return G10ERR_GENERAL; return G10ERR_GENERAL;
@ -940,10 +965,15 @@ pin_cb (void *opaque, const char *info, char **retstr)
/* Send a SETATTR command to the SCdaemon. */ /* Send a SETATTR command to the SCdaemon. */
int int
agent_scd_setattr (const char *name, 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; app_t app;
int rc; int rc;
struct pincb_parm_s parm;
memset (&parm, 0, sizeof parm);
parm.sn = serialno;
app = current_app? current_app : open_card (); app = current_app? current_app : open_card ();
if (!app) if (!app)
@ -981,11 +1011,10 @@ agent_scd_setattr (const char *name,
} }
else 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) status_sc_op_failure (rc);
write_status (STATUS_SC_OP_FAILURE);
return rc; return rc;
} }
@ -1003,11 +1032,17 @@ inq_writekey_parms (void *opaque, const char *keyword)
/* Send a WRITEKEY command to the SCdaemon. */ /* Send a WRITEKEY command to the SCdaemon. */
int 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; app_t app;
int rc; int rc;
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
struct pincb_parm_s parm;
memset (&parm, 0, sizeof parm);
parm.sn = serialno;
app = current_app? current_app : open_card (); app = current_app? current_app : open_card ();
if (!app) if (!app)
return gpg_error (GPG_ERR_CARD); 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); snprintf (line, DIM(line)-1, "OPENPGP.%d", keyno);
line[DIM(line)-1] = 0; line[DIM(line)-1] = 0;
rc = app->fnc.writekey (app, NULL, line, 0x0001, rc = app->fnc.writekey (app, NULL, line, 0x0001,
pin_cb, NULL, pin_cb, &parm,
keydata, keydatalen); keydata, keydatalen);
} }
if (rc) status_sc_op_failure (rc);
write_status (STATUS_SC_OP_FAILURE);
return rc; return rc;
} }
@ -1097,12 +1131,17 @@ genkey_status_cb (void *opaque, const char *line)
/* Send a GENKEY command to the SCdaemon. */ /* Send a GENKEY command to the SCdaemon. */
int 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; app_t app;
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
struct ctrl_ctx_s ctrl; struct ctrl_ctx_s ctrl;
int rc; int rc;
struct pincb_parm_s parm;
memset (&parm, 0, sizeof parm);
parm.sn = serialno;
app = current_app? current_app : open_card (); app = current_app? current_app : open_card ();
if (!app) if (!app)
@ -1127,11 +1166,10 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
ctrl.status_cb_arg = info; ctrl.status_cb_arg = info;
rc = app->fnc.genkey (app, &ctrl, line, rc = app->fnc.genkey (app, &ctrl, line,
force? 1:0, force? 1:0,
pin_cb, NULL); pin_cb, &parm);
} }
if (rc) status_sc_op_failure (rc);
write_status (STATUS_SC_OP_FAILURE);
return rc; return rc;
} }
@ -1213,7 +1251,7 @@ agent_scd_pksign (const char *serialno, int hashalgo,
if (rc) if (rc)
{ {
write_status (STATUS_SC_OP_FAILURE); status_sc_op_failure (rc);
if (!app->assuan_ctx) if (!app->assuan_ctx)
agent_clear_pin_cache (serialno); agent_clear_pin_cache (serialno);
} }
@ -1287,20 +1325,26 @@ agent_scd_pkdecrypt (const char *serialno,
if (rc) if (rc)
{ {
write_status (STATUS_SC_OP_FAILURE); status_sc_op_failure (rc);
if (!app->assuan_ctx) if (!app->assuan_ctx)
agent_clear_pin_cache (serialno); agent_clear_pin_cache (serialno);
} }
return rc; 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 int
agent_scd_change_pin (int chvno) agent_scd_change_pin (int chvno, const char *serialno)
{ {
app_t app; app_t app;
int reset = 0; int reset = 0;
int rc; int rc;
struct pincb_parm_s parm;
memset (&parm, 0, sizeof parm);
parm.sn = serialno;
reset = (chvno >= 100); reset = (chvno >= 100);
chvno %= 100; chvno %= 100;
@ -1326,11 +1370,10 @@ agent_scd_change_pin (int chvno)
sprintf (chvnostr, "%d", chvno); sprintf (chvnostr, "%d", chvno);
rc = app->fnc.change_pin (app, NULL, chvnostr, reset, rc = app->fnc.change_pin (app, NULL, chvnostr, reset,
pin_cb, NULL); pin_cb, &parm);
} }
if (rc) status_sc_op_failure (rc);
write_status (STATUS_SC_OP_FAILURE);
return rc; return rc;
} }
@ -1342,6 +1385,10 @@ agent_scd_checkpin (const char *serialnobuf)
{ {
app_t app; app_t app;
int rc; int rc;
struct pincb_parm_s parm;
memset (&parm, 0, sizeof parm);
parm.sn = serialnobuf;
app = current_app? current_app : open_card (); app = current_app? current_app : open_card ();
if (!app) if (!app)
@ -1360,11 +1407,10 @@ agent_scd_checkpin (const char *serialnobuf)
} }
else else
{ {
rc = app->fnc.check_pin (app, serialnobuf, pin_cb, NULL); rc = app->fnc.check_pin (app, serialnobuf, pin_cb, &parm);
} }
if (rc) status_sc_op_failure (rc);
write_status (STATUS_SC_OP_FAILURE);
return rc; return rc;
} }

View File

@ -82,7 +82,7 @@ typedef struct ctrl_ctx_s *ctrl_t;
#define GPG_ERR_GENERAL G10ERR_GENERAL #define GPG_ERR_GENERAL G10ERR_GENERAL
#define GPG_ERR_BAD_PIN G10ERR_BAD_PASS #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_CARD G10ERR_GENERAL
#define GPG_ERR_EEXIST G10ERR_FILE_EXISTS #define GPG_ERR_EEXIST G10ERR_FILE_EXISTS
#define GPG_ERR_ENOMEM G10ERR_RESOURCE_LIMIT #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. */ /* Send a SETATTR command to the SCdaemon. */
int agent_scd_setattr (const char *name, 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. */ /* 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); const unsigned char *keydata, size_t keydatalen);
/* Send a GENKEY command to the SCdaemon. */ /* 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. */ /* Send a PKSIGN command to the SCdaemon. */
int agent_scd_pksign (const char *keyid, int hashalgo, 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); unsigned char **r_buf, size_t *r_buflen);
/* Change the PIN of an OpenPGP card or reset the retry counter. */ /* 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. */ /* Send a CHECKPIN command. */
int agent_scd_checkpin (const char *serialnobuf); int agent_scd_checkpin (const char *serialnobuf);

View File

@ -1492,6 +1492,8 @@ parse_expire_string( const char *string )
if( !*string ) if( !*string )
seconds = 0; seconds = 0;
else if ( !strncmp (string, "seconds=", 8) )
seconds = atoi (string+8);
else if( (abs_date = scan_isodatestr(string)) && abs_date > curtime ) else if( (abs_date = scan_isodatestr(string)) && abs_date > curtime )
seconds = abs_date - curtime; seconds = abs_date - curtime;
else if( (mult=check_valid_days(string)) ) 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); assert (algo == PUBKEY_ALGO_RSA);
/* Fixme: We don't have the serialnumber available, thus passing NULL. */
rc = agent_scd_genkey (&info, keyno, 1); rc = agent_scd_genkey (&info, keyno, 1, NULL);
/* if (gpg_err_code (rc) == GPG_ERR_EEXIST) */ /* if (gpg_err_code (rc) == GPG_ERR_EEXIST) */
/* { */ /* { */
/* tty_printf ("\n"); */ /* 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)); sprintf (numbuf, "%lu:", (unsigned long)strlen (numbuf2));
p = stpcpy (stpcpy (stpcpy (p, numbuf), 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: leave:
xfree (sexp); xfree (sexp);