mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02: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 force_chv1:1; /* True if the card does not cache CHV1. */
|
||||||
unsigned int did_chv2:1;
|
unsigned int did_chv2:1;
|
||||||
unsigned int did_chv3: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 app_local_s *app_local; /* Local to the application. */
|
||||||
struct {
|
struct {
|
||||||
void (*deinit) (app_t app);
|
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. */
|
* required to always work. */
|
||||||
if (a_prev && a_prev->fnc.prep_reselect)
|
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)
|
if (err)
|
||||||
log_error ("slot %d, app %s: preparing re-select from %s failed: %s\n",
|
log_error ("slot %d, app %s: preparing re-select from %s failed: %s\n",
|
||||||
c->slot, xstrapptype (a),
|
c->slot, xstrapptype (a),
|
||||||
xstrapptype (a_prev), gpg_strerror (err));
|
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)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error ("slot %d, app %s: error re-selecting: %s\n",
|
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. */
|
* the corresponding app. */
|
||||||
for (app = card->app; app; app_prev = app, app = app->next)
|
for (app = card->app; app; app_prev = app, app = app->next)
|
||||||
if (app->fnc.with_keygrip
|
if (app->fnc.with_keygrip
|
||||||
|
&& !app->need_reset
|
||||||
&& !app->fnc.with_keygrip (app, ctrl,
|
&& !app->fnc.with_keygrip (app, ctrl,
|
||||||
KEYGRIP_ACTION_LOOKUP, keyref, 0))
|
KEYGRIP_ACTION_LOOKUP, keyref, 0))
|
||||||
break;
|
break;
|
||||||
@ -1542,6 +1549,8 @@ static gpg_error_t
|
|||||||
write_learn_status_core (card_t card, app_t app, ctrl_t ctrl,
|
write_learn_status_core (card_t card, app_t app, ctrl_t ctrl,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
/* We do not send CARD and APPTYPE if only keypairinfo is requested. */
|
/* We do not send CARD and APPTYPE if only keypairinfo is requested. */
|
||||||
if (!(flags & APP_LEARN_FLAG_KEYPAIRINFO))
|
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);
|
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)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling readcert(%s)\n",
|
log_debug ("slot %d app %s: calling readcert(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), certid);
|
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);
|
unlock_card (card);
|
||||||
@ -1708,7 +1728,10 @@ app_readkey (card_t card, ctrl_t ctrl, const char *keyid, unsigned int flags,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling readkey(%s)\n",
|
log_debug ("slot %d app %s: calling readkey(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), keyid);
|
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);
|
unlock_card (card);
|
||||||
@ -1758,7 +1781,10 @@ app_getattr (card_t card, ctrl_t ctrl, const char *name)
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling getattr(%s)\n",
|
log_debug ("slot %d app %s: calling getattr(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), name);
|
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);
|
unlock_card (card);
|
||||||
@ -1790,8 +1816,11 @@ app_setattr (card_t card, ctrl_t ctrl, const char *name,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling setattr(%s)\n",
|
log_debug ("slot %d app %s: calling setattr(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), name);
|
card->slot, xstrapptype (card->app), name);
|
||||||
err = card->app->fnc.setattr (card->app, ctrl, name, pincb, pincb_arg,
|
if (card->app->need_reset)
|
||||||
value, valuelen);
|
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);
|
unlock_card (card);
|
||||||
@ -1826,10 +1855,13 @@ app_sign (card_t card, ctrl_t ctrl, const char *keyidstr, int hashalgo,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling sign(%s)\n",
|
log_debug ("slot %d app %s: calling sign(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), keyidstr);
|
card->slot, xstrapptype (card->app), keyidstr);
|
||||||
err = card->app->fnc.sign (card->app, ctrl, keyidstr, hashalgo,
|
if (card->app->need_reset)
|
||||||
pincb, pincb_arg,
|
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||||
indata, indatalen,
|
else
|
||||||
outdata, outdatalen);
|
err = card->app->fnc.sign (card->app, ctrl, keyidstr, hashalgo,
|
||||||
|
pincb, pincb_arg,
|
||||||
|
indata, indatalen,
|
||||||
|
outdata, outdatalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_card (card);
|
unlock_card (card);
|
||||||
@ -1867,10 +1899,13 @@ app_auth (card_t card, ctrl_t ctrl, const char *keyidstr,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling auth(%s)\n",
|
log_debug ("slot %d app %s: calling auth(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), keyidstr);
|
card->slot, xstrapptype (card->app), keyidstr);
|
||||||
err = card->app->fnc.auth (card->app, ctrl, keyidstr,
|
if (card->app->need_reset)
|
||||||
pincb, pincb_arg,
|
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||||
indata, indatalen,
|
else
|
||||||
outdata, outdatalen);
|
err = card->app->fnc.auth (card->app, ctrl, keyidstr,
|
||||||
|
pincb, pincb_arg,
|
||||||
|
indata, indatalen,
|
||||||
|
outdata, outdatalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_card (card);
|
unlock_card (card);
|
||||||
@ -1910,11 +1945,14 @@ app_decipher (card_t card, ctrl_t ctrl, const char *keyidstr,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling decipher(%s)\n",
|
log_debug ("slot %d app %s: calling decipher(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), keyidstr);
|
card->slot, xstrapptype (card->app), keyidstr);
|
||||||
err = card->app->fnc.decipher (card->app, ctrl, keyidstr,
|
if (card->app->need_reset)
|
||||||
pincb, pincb_arg,
|
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||||
indata, indatalen,
|
else
|
||||||
outdata, outdatalen,
|
err = card->app->fnc.decipher (card->app, ctrl, keyidstr,
|
||||||
r_info);
|
pincb, pincb_arg,
|
||||||
|
indata, indatalen,
|
||||||
|
outdata, outdatalen,
|
||||||
|
r_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_card (card);
|
unlock_card (card);
|
||||||
@ -1949,8 +1987,11 @@ app_writecert (card_t card, ctrl_t ctrl,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling writecert(%s)\n",
|
log_debug ("slot %d app %s: calling writecert(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), certidstr);
|
card->slot, xstrapptype (card->app), certidstr);
|
||||||
err = card->app->fnc.writecert (card->app, ctrl, certidstr,
|
if (card->app->need_reset)
|
||||||
pincb, pincb_arg, data, datalen);
|
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);
|
unlock_card (card);
|
||||||
@ -1985,8 +2026,11 @@ app_writekey (card_t card, ctrl_t ctrl,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling writekey(%s)\n",
|
log_debug ("slot %d app %s: calling writekey(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), keyidstr);
|
card->slot, xstrapptype (card->app), keyidstr);
|
||||||
err = card->app->fnc.writekey (card->app, ctrl, keyidstr, flags,
|
if (card->app->need_reset)
|
||||||
pincb, pincb_arg, keydata, keydatalen);
|
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);
|
unlock_card (card);
|
||||||
@ -2020,8 +2064,11 @@ app_genkey (card_t card, ctrl_t ctrl, const char *keynostr,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling genkey(%s)\n",
|
log_debug ("slot %d app %s: calling genkey(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), keynostr);
|
card->slot, xstrapptype (card->app), keynostr);
|
||||||
err = card->app->fnc.genkey (card->app, ctrl, keynostr, keytype, flags,
|
if (card->app->need_reset)
|
||||||
createtime, pincb, pincb_arg);
|
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);
|
unlock_card (card);
|
||||||
@ -2080,8 +2127,11 @@ app_change_pin (card_t card, ctrl_t ctrl, const char *chvnostr,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling change_pin(%s)\n",
|
log_debug ("slot %d app %s: calling change_pin(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), chvnostr);
|
card->slot, xstrapptype (card->app), chvnostr);
|
||||||
err = card->app->fnc.change_pin (card->app, ctrl,
|
if (card->app->need_reset)
|
||||||
chvnostr, flags, pincb, pincb_arg);
|
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);
|
unlock_card (card);
|
||||||
@ -2116,8 +2166,11 @@ app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr,
|
|||||||
if (DBG_APP)
|
if (DBG_APP)
|
||||||
log_debug ("slot %d app %s: calling check_pin(%s)\n",
|
log_debug ("slot %d app %s: calling check_pin(%s)\n",
|
||||||
card->slot, xstrapptype (card->app), keyidstr);
|
card->slot, xstrapptype (card->app), keyidstr);
|
||||||
err = card->app->fnc.check_pin (card->app, ctrl, keyidstr,
|
if (card->app->need_reset)
|
||||||
pincb, pincb_arg);
|
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||||
|
else
|
||||||
|
err = card->app->fnc.check_pin (card->app, ctrl, keyidstr,
|
||||||
|
pincb, pincb_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_card (card);
|
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);
|
put_membuf_str (&mb, serial);
|
||||||
for (a = card->app; a; a = a->next)
|
for (a = card->app; a; a = a->next)
|
||||||
{
|
{
|
||||||
if (!a->fnc.with_keygrip)
|
if (!a->fnc.with_keygrip || a->need_reset)
|
||||||
continue;
|
continue;
|
||||||
any = 1;
|
any = 1;
|
||||||
put_membuf (&mb, " ", 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;
|
a_prev = NULL;
|
||||||
for (a = c->app; a; a = a->next)
|
for (a = c->app; a; a = a->next)
|
||||||
{
|
{
|
||||||
if (!a->fnc.with_keygrip)
|
if (!a->fnc.with_keygrip || a->need_reset)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Note that we need to do a re-select even for the current
|
/* 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[] =
|
static const char hlp_learn[] =
|
||||||
"LEARN [--force] [--keypairinfo] [--multi]\n"
|
"LEARN [--force] [--keypairinfo] [--reread] [--multi]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Learn all useful information of the currently inserted card. When\n"
|
"Learn all useful information of the currently inserted card. When\n"
|
||||||
"used without the force options, the command might do an INQUIRE\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"
|
"error message.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"With the option --keypairinfo only KEYPAIRINFO status lines are\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"
|
"\n"
|
||||||
"The response of this command is a list of status lines formatted as\n"
|
"The response of this command is a list of status lines formatted as\n"
|
||||||
"this:\n"
|
"this:\n"
|
||||||
@ -498,6 +499,8 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
int only_keypairinfo = has_option (line, "--keypairinfo");
|
int only_keypairinfo = has_option (line, "--keypairinfo");
|
||||||
int opt_multi = has_option (line, "--multi");
|
int opt_multi = has_option (line, "--multi");
|
||||||
|
int opt_reread = has_option (line, "--reread");
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
if ((rc = open_card (ctrl)))
|
if ((rc = open_card (ctrl)))
|
||||||
return rc;
|
return rc;
|
||||||
@ -559,11 +562,16 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
/* Let the application print out its collection of useful status
|
/* Let the application print out its collection of useful status
|
||||||
information. */
|
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)
|
if (!rc)
|
||||||
rc = app_write_learn_status
|
rc = app_write_learn_status (ctrl->card_ctx, ctrl, flags);
|
||||||
(ctrl->card_ctx, ctrl,
|
|
||||||
( (only_keypairinfo? APP_LEARN_FLAG_KEYPAIRINFO : 0)
|
|
||||||
| (opt_multi? APP_LEARN_FLAG_MULTI : 0)) );
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user