aboutsummaryrefslogtreecommitdiffstats
path: root/scd/app.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2021-04-01 08:31:52 +0000
committerWerner Koch <[email protected]>2021-04-01 08:31:52 +0000
commitff87f4e578f412332ae59fdab016f0a5304baaf9 (patch)
tree8bdc825e66936906031dcdc6bd0edf7f981c5d41 /scd/app.c
parentscd:p15: New flag APP_LEARN_FLAG_REREAD. (diff)
downloadgnupg-ff87f4e578f412332ae59fdab016f0a5304baaf9.tar.gz
gnupg-ff87f4e578f412332ae59fdab016f0a5304baaf9.zip
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 <[email protected]>
Diffstat (limited to 'scd/app.c')
-rw-r--r--scd/app.c119
1 files changed, 86 insertions, 33 deletions
diff --git a/scd/app.c b/scd/app.c
index e378f23b8..d0e990e48 100644
--- a/scd/app.c
+++ b/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