mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-31 11:41:32 +01:00
scd: New flag --reread for LEARN
* scd/command.c (cmd_learn): Add flag --reread. * scd/app-common.h (struct app_ctx_s): New field need_reset. * scd/app.c (write_learn_status_core): Set need_reset if we notice an error after returning from a reread. Change all callers of card functions to return GPG_ERR_CARD_RESET so that that app is not anymore used. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
e17d3f8660
commit
ff87f4e578
@ -136,6 +136,7 @@ struct app_ctx_s {
|
||||
unsigned int force_chv1:1; /* True if the card does not cache CHV1. */
|
||||
unsigned int did_chv2:1;
|
||||
unsigned int did_chv3:1;
|
||||
unsigned int need_reset:1; /* Do't allow any functions but deinit. */
|
||||
struct app_local_s *app_local; /* Local to the application. */
|
||||
struct {
|
||||
void (*deinit) (app_t app);
|
||||
|
119
scd/app.c
119
scd/app.c
@ -1407,14 +1407,20 @@ run_reselect (ctrl_t ctrl, card_t c, app_t a, app_t a_prev)
|
||||
* required to always work. */
|
||||
if (a_prev && a_prev->fnc.prep_reselect)
|
||||
{
|
||||
err = a_prev->fnc.prep_reselect (a_prev, ctrl);
|
||||
if (a_prev->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = a_prev->fnc.prep_reselect (a_prev, ctrl);
|
||||
if (err)
|
||||
log_error ("slot %d, app %s: preparing re-select from %s failed: %s\n",
|
||||
c->slot, xstrapptype (a),
|
||||
xstrapptype (a_prev), gpg_strerror (err));
|
||||
}
|
||||
|
||||
err = a->fnc.reselect (a, ctrl);
|
||||
if (a->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = a->fnc.reselect (a, ctrl);
|
||||
if (err)
|
||||
{
|
||||
log_error ("slot %d, app %s: error re-selecting: %s\n",
|
||||
@ -1491,6 +1497,7 @@ maybe_switch_app (ctrl_t ctrl, card_t card, const char *keyref)
|
||||
* the corresponding app. */
|
||||
for (app = card->app; app; app_prev = app, app = app->next)
|
||||
if (app->fnc.with_keygrip
|
||||
&& !app->need_reset
|
||||
&& !app->fnc.with_keygrip (app, ctrl,
|
||||
KEYGRIP_ACTION_LOOKUP, keyref, 0))
|
||||
break;
|
||||
@ -1542,6 +1549,8 @@ static gpg_error_t
|
||||
write_learn_status_core (card_t card, app_t app, ctrl_t ctrl,
|
||||
unsigned int flags)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
/* We do not send CARD and APPTYPE if only keypairinfo is requested. */
|
||||
if (!(flags & APP_LEARN_FLAG_KEYPAIRINFO))
|
||||
{
|
||||
@ -1555,7 +1564,15 @@ write_learn_status_core (card_t card, app_t app, ctrl_t ctrl,
|
||||
send_status_printf (ctrl, "APPVERSION", "%X", app->appversion);
|
||||
}
|
||||
|
||||
return app->fnc.learn_status (app, ctrl, flags);
|
||||
if (app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
{
|
||||
err = app->fnc.learn_status (app, ctrl, flags);
|
||||
if (err && (flags & APP_LEARN_FLAG_REREAD))
|
||||
app->need_reset = 1;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -1666,7 +1683,10 @@ app_readcert (card_t card, ctrl_t ctrl, const char *certid,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling readcert(%s)\n",
|
||||
card->slot, xstrapptype (card->app), certid);
|
||||
err = card->app->fnc.readcert (card->app, certid, cert, certlen);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.readcert (card->app, certid, cert, certlen);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1708,7 +1728,10 @@ app_readkey (card_t card, ctrl_t ctrl, const char *keyid, unsigned int flags,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling readkey(%s)\n",
|
||||
card->slot, xstrapptype (card->app), keyid);
|
||||
err = card->app->fnc.readkey (card->app, ctrl, keyid, flags, pk, pklen);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.readkey (card->app, ctrl, keyid, flags, pk, pklen);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1758,7 +1781,10 @@ app_getattr (card_t card, ctrl_t ctrl, const char *name)
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling getattr(%s)\n",
|
||||
card->slot, xstrapptype (card->app), name);
|
||||
err = card->app->fnc.getattr (card->app, ctrl, name);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.getattr (card->app, ctrl, name);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1790,8 +1816,11 @@ app_setattr (card_t card, ctrl_t ctrl, const char *name,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling setattr(%s)\n",
|
||||
card->slot, xstrapptype (card->app), name);
|
||||
err = card->app->fnc.setattr (card->app, ctrl, name, pincb, pincb_arg,
|
||||
value, valuelen);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.setattr (card->app, ctrl, name, pincb, pincb_arg,
|
||||
value, valuelen);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1826,10 +1855,13 @@ app_sign (card_t card, ctrl_t ctrl, const char *keyidstr, int hashalgo,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling sign(%s)\n",
|
||||
card->slot, xstrapptype (card->app), keyidstr);
|
||||
err = card->app->fnc.sign (card->app, ctrl, keyidstr, hashalgo,
|
||||
pincb, pincb_arg,
|
||||
indata, indatalen,
|
||||
outdata, outdatalen);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.sign (card->app, ctrl, keyidstr, hashalgo,
|
||||
pincb, pincb_arg,
|
||||
indata, indatalen,
|
||||
outdata, outdatalen);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1867,10 +1899,13 @@ app_auth (card_t card, ctrl_t ctrl, const char *keyidstr,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling auth(%s)\n",
|
||||
card->slot, xstrapptype (card->app), keyidstr);
|
||||
err = card->app->fnc.auth (card->app, ctrl, keyidstr,
|
||||
pincb, pincb_arg,
|
||||
indata, indatalen,
|
||||
outdata, outdatalen);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.auth (card->app, ctrl, keyidstr,
|
||||
pincb, pincb_arg,
|
||||
indata, indatalen,
|
||||
outdata, outdatalen);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1910,11 +1945,14 @@ app_decipher (card_t card, ctrl_t ctrl, const char *keyidstr,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling decipher(%s)\n",
|
||||
card->slot, xstrapptype (card->app), keyidstr);
|
||||
err = card->app->fnc.decipher (card->app, ctrl, keyidstr,
|
||||
pincb, pincb_arg,
|
||||
indata, indatalen,
|
||||
outdata, outdatalen,
|
||||
r_info);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.decipher (card->app, ctrl, keyidstr,
|
||||
pincb, pincb_arg,
|
||||
indata, indatalen,
|
||||
outdata, outdatalen,
|
||||
r_info);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1949,8 +1987,11 @@ app_writecert (card_t card, ctrl_t ctrl,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling writecert(%s)\n",
|
||||
card->slot, xstrapptype (card->app), certidstr);
|
||||
err = card->app->fnc.writecert (card->app, ctrl, certidstr,
|
||||
pincb, pincb_arg, data, datalen);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.writecert (card->app, ctrl, certidstr,
|
||||
pincb, pincb_arg, data, datalen);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -1985,8 +2026,11 @@ app_writekey (card_t card, ctrl_t ctrl,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling writekey(%s)\n",
|
||||
card->slot, xstrapptype (card->app), keyidstr);
|
||||
err = card->app->fnc.writekey (card->app, ctrl, keyidstr, flags,
|
||||
pincb, pincb_arg, keydata, keydatalen);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.writekey (card->app, ctrl, keyidstr, flags,
|
||||
pincb, pincb_arg, keydata, keydatalen);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -2020,8 +2064,11 @@ app_genkey (card_t card, ctrl_t ctrl, const char *keynostr,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling genkey(%s)\n",
|
||||
card->slot, xstrapptype (card->app), keynostr);
|
||||
err = card->app->fnc.genkey (card->app, ctrl, keynostr, keytype, flags,
|
||||
createtime, pincb, pincb_arg);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.genkey (card->app, ctrl, keynostr, keytype, flags,
|
||||
createtime, pincb, pincb_arg);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -2080,8 +2127,11 @@ app_change_pin (card_t card, ctrl_t ctrl, const char *chvnostr,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling change_pin(%s)\n",
|
||||
card->slot, xstrapptype (card->app), chvnostr);
|
||||
err = card->app->fnc.change_pin (card->app, ctrl,
|
||||
chvnostr, flags, pincb, pincb_arg);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.change_pin (card->app, ctrl,
|
||||
chvnostr, flags, pincb, pincb_arg);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -2116,8 +2166,11 @@ app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr,
|
||||
if (DBG_APP)
|
||||
log_debug ("slot %d app %s: calling check_pin(%s)\n",
|
||||
card->slot, xstrapptype (card->app), keyidstr);
|
||||
err = card->app->fnc.check_pin (card->app, ctrl, keyidstr,
|
||||
pincb, pincb_arg);
|
||||
if (card->app->need_reset)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
else
|
||||
err = card->app->fnc.check_pin (card->app, ctrl, keyidstr,
|
||||
pincb, pincb_arg);
|
||||
}
|
||||
|
||||
unlock_card (card);
|
||||
@ -2331,7 +2384,7 @@ send_serialno_and_app_status (card_t card, int with_apps, ctrl_t ctrl)
|
||||
put_membuf_str (&mb, serial);
|
||||
for (a = card->app; a; a = a->next)
|
||||
{
|
||||
if (!a->fnc.with_keygrip)
|
||||
if (!a->fnc.with_keygrip || a->need_reset)
|
||||
continue;
|
||||
any = 1;
|
||||
put_membuf (&mb, " ", 1);
|
||||
@ -2517,7 +2570,7 @@ app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str,
|
||||
a_prev = NULL;
|
||||
for (a = c->app; a; a = a->next)
|
||||
{
|
||||
if (!a->fnc.with_keygrip)
|
||||
if (!a->fnc.with_keygrip || a->need_reset)
|
||||
continue;
|
||||
|
||||
/* Note that we need to do a re-select even for the current
|
||||
|
@ -420,7 +420,7 @@ cmd_switchapp (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
static const char hlp_learn[] =
|
||||
"LEARN [--force] [--keypairinfo] [--multi]\n"
|
||||
"LEARN [--force] [--keypairinfo] [--reread] [--multi]\n"
|
||||
"\n"
|
||||
"Learn all useful information of the currently inserted card. When\n"
|
||||
"used without the force options, the command might do an INQUIRE\n"
|
||||
@ -433,7 +433,8 @@ static const char hlp_learn[] =
|
||||
"error message.\n"
|
||||
"\n"
|
||||
"With the option --keypairinfo only KEYPAIRINFO status lines are\n"
|
||||
"returned.\n"
|
||||
"returned. With the option --reread information from the card are\n"
|
||||
"read again without the need for a reset (sone some cards).\n"
|
||||
"\n"
|
||||
"The response of this command is a list of status lines formatted as\n"
|
||||
"this:\n"
|
||||
@ -498,6 +499,8 @@ cmd_learn (assuan_context_t ctx, char *line)
|
||||
int rc = 0;
|
||||
int only_keypairinfo = has_option (line, "--keypairinfo");
|
||||
int opt_multi = has_option (line, "--multi");
|
||||
int opt_reread = has_option (line, "--reread");
|
||||
unsigned int flags;
|
||||
|
||||
if ((rc = open_card (ctrl)))
|
||||
return rc;
|
||||
@ -559,11 +562,16 @@ cmd_learn (assuan_context_t ctx, char *line)
|
||||
|
||||
/* Let the application print out its collection of useful status
|
||||
information. */
|
||||
flags = 0;
|
||||
if (only_keypairinfo)
|
||||
flags |= APP_LEARN_FLAG_KEYPAIRINFO;
|
||||
if (opt_multi)
|
||||
flags |= APP_LEARN_FLAG_MULTI;
|
||||
if (opt_reread)
|
||||
flags |= APP_LEARN_FLAG_REREAD;
|
||||
|
||||
if (!rc)
|
||||
rc = app_write_learn_status
|
||||
(ctrl->card_ctx, ctrl,
|
||||
( (only_keypairinfo? APP_LEARN_FLAG_KEYPAIRINFO : 0)
|
||||
| (opt_multi? APP_LEARN_FLAG_MULTI : 0)) );
|
||||
rc = app_write_learn_status (ctrl->card_ctx, ctrl, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user