aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-06-21 12:01:06 +0000
committerWerner Koch <[email protected]>2019-06-21 12:01:06 +0000
commit0400a4eb1782e7a4aea5b04492c93939c6b9799a (patch)
treedcfb5fe3009f476df0c9eb792e2843bd91dd1a72
parentscd: Add code to check whether app switching is possible. (diff)
downloadgnupg-0400a4eb1782e7a4aea5b04492c93939c6b9799a.tar.gz
gnupg-0400a4eb1782e7a4aea5b04492c93939c6b9799a.zip
scd: Take the lock earlier in the function dispatchers.
* scd/app.c: Chnage all function dispatcher. -- This change will allow us to easier integrate an app swithcing logic. The change should have no user visible effect. The error checking we do now with the card locked will rarely be asserted. It is the correct thing to do anyway. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--scd/app.c267
1 files changed, 154 insertions, 113 deletions
diff --git a/scd/app.c b/scd/app.c
index b415668f0..34ed99d57 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -841,30 +841,35 @@ app_write_learn_status (card_t card, ctrl_t ctrl, unsigned int flags)
if (!card)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- app = card->app;
- if (!app->fnc.learn_status)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
-
- /* We do not send CARD and APPTYPE if only keypairinfo is requested. */
- if (!(flags &1))
- {
- if (card->cardtype)
- send_status_direct (ctrl, "CARDTYPE", strcardtype (card->cardtype));
- if (card->cardversion)
- send_status_printf (ctrl, "CARDVERSION", "%X", card->cardversion);
- if (app->apptype)
- send_status_direct (ctrl, "APPTYPE", strapptype (app->apptype));
- if (app->appversion)
- send_status_printf (ctrl, "APPVERSION", "%X", app->appversion);
- /* FIXME: Send info for the other active apps of the card? */
- }
err = lock_card (card, ctrl);
if (err)
return err;
- err = app->fnc.learn_status (card->app, ctrl, flags);
+
+ app = card->app;
+ if (!app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!app->fnc.learn_status)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ {
+ /* We do not send CARD and APPTYPE if only keypairinfo is requested. */
+ if (!(flags &1))
+ {
+ if (card->cardtype)
+ send_status_direct (ctrl, "CARDTYPE", strcardtype (card->cardtype));
+ if (card->cardversion)
+ send_status_printf (ctrl, "CARDVERSION", "%X", card->cardversion);
+ if (app->apptype)
+ send_status_direct (ctrl, "APPTYPE", strapptype (app->apptype));
+ if (app->appversion)
+ send_status_printf (ctrl, "APPVERSION", "%X", app->appversion);
+ /* FIXME: Send info for the other active apps of the card? */
+ }
+
+ err = app->fnc.learn_status (app, ctrl, flags);
+ }
+
unlock_card (card);
return err;
}
@@ -882,14 +887,17 @@ app_readcert (card_t card, ctrl_t ctrl, const char *certid,
if (!card)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.readcert)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.readcert (card->app, certid, cert, certlen);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.readcert)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.readcert (card->app, certid, cert, certlen);
+
unlock_card (card);
return err;
}
@@ -916,14 +924,17 @@ app_readkey (card_t card, ctrl_t ctrl, const char *keyid, unsigned int flags,
if (!card || !keyid)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.readkey)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.readkey (card->app, ctrl, keyid, flags, pk, pklen);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.readkey)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.readkey (card->app, ctrl, keyid, flags, pk, pklen);
+
unlock_card (card);
return err;
}
@@ -937,38 +948,38 @@ app_getattr (card_t card, ctrl_t ctrl, const char *name)
if (!card || !name || !*name)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ err = lock_card (card, ctrl);
+ if (err)
+ return err;
- if (name && !strcmp (name, "CARDTYPE"))
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (name && !strcmp (name, "CARDTYPE"))
{
send_status_direct (ctrl, "CARDTYPE", strcardtype (card->cardtype));
- return 0;
}
- if (name && !strcmp (name, "APPTYPE"))
+ else if (name && !strcmp (name, "APPTYPE"))
{
send_status_direct (ctrl, "APPTYPE", strapptype (card->app->apptype));
- return 0;
}
- if (name && !strcmp (name, "SERIALNO"))
+ else if (name && !strcmp (name, "SERIALNO"))
{
char *serial;
serial = card_get_serialno (card);
if (!serial)
- return gpg_error (GPG_ERR_INV_VALUE);
-
- send_status_direct (ctrl, "SERIALNO", serial);
- xfree (serial);
- return 0;
+ err = gpg_error (GPG_ERR_INV_VALUE);
+ else
+ {
+ send_status_direct (ctrl, "SERIALNO", serial);
+ xfree (serial);
+ }
}
+ else if (!card->app->fnc.getattr)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.getattr (card->app, ctrl, name);
- if (!card->app->fnc.getattr)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
- err = lock_card (card, ctrl);
- if (err)
- return err;
- err = card->app->fnc.getattr (card->app, ctrl, name);
unlock_card (card);
return err;
}
@@ -985,15 +996,18 @@ app_setattr (card_t card, ctrl_t ctrl, const char *name,
if (!card || !name || !*name || !value)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.setattr)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.setattr (card->app, name, pincb, pincb_arg,
- value, valuelen);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.setattr)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.setattr (card->app, name, pincb, pincb_arg,
+ value, valuelen);
+
unlock_card (card);
return err;
}
@@ -1013,17 +1027,20 @@ app_sign (card_t card, ctrl_t ctrl, const char *keyidstr, int hashalgo,
if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.sign)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.sign (card->app, keyidstr, hashalgo,
- pincb, pincb_arg,
- indata, indatalen,
- outdata, outdatalen);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.sign)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.sign (card->app, keyidstr, hashalgo,
+ pincb, pincb_arg,
+ indata, indatalen,
+ outdata, outdatalen);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation sign result: %s\n", gpg_strerror (err));
@@ -1046,17 +1063,20 @@ app_auth (card_t card, ctrl_t ctrl, const char *keyidstr,
if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.auth)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.auth (card->app, keyidstr,
- pincb, pincb_arg,
- indata, indatalen,
- outdata, outdatalen);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.auth)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.auth (card->app, keyidstr,
+ pincb, pincb_arg,
+ indata, indatalen,
+ outdata, outdatalen);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation auth result: %s\n", gpg_strerror (err));
@@ -1081,18 +1101,21 @@ app_decipher (card_t card, ctrl_t ctrl, const char *keyidstr,
if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.decipher)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.decipher (card->app, keyidstr,
- pincb, pincb_arg,
- indata, indatalen,
- outdata, outdatalen,
- r_info);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.decipher)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.decipher (card->app, keyidstr,
+ pincb, pincb_arg,
+ indata, indatalen,
+ outdata, outdatalen,
+ r_info);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation decipher result: %s\n", gpg_strerror (err));
@@ -1112,15 +1135,18 @@ app_writecert (card_t card, ctrl_t ctrl,
if (!card || !certidstr || !*certidstr || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.writecert)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.writecert (card->app, ctrl, certidstr,
- pincb, pincb_arg, data, datalen);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.writecert)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.writecert (card->app, ctrl, certidstr,
+ pincb, pincb_arg, data, datalen);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation writecert result: %s\n", gpg_strerror (err));
@@ -1140,15 +1166,18 @@ app_writekey (card_t card, ctrl_t ctrl,
if (!card || !keyidstr || !*keyidstr || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.writekey)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.writekey (card->app, ctrl, keyidstr, flags,
- pincb, pincb_arg, keydata, keydatalen);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.writekey)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.writekey (card->app, ctrl, keyidstr, flags,
+ pincb, pincb_arg, keydata, keydatalen);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation writekey result: %s\n", gpg_strerror (err));
@@ -1156,7 +1185,7 @@ app_writekey (card_t card, ctrl_t ctrl,
}
-/* Perform a SETATTR operation. */
+/* Perform a GENKEY operation. */
gpg_error_t
app_genkey (card_t card, ctrl_t ctrl, const char *keynostr,
const char *keytype, unsigned int flags, time_t createtime,
@@ -1167,15 +1196,18 @@ app_genkey (card_t card, ctrl_t ctrl, const char *keynostr,
if (!card || !keynostr || !*keynostr || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.genkey)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.genkey (card->app, ctrl, keynostr, keytype, flags,
- createtime, pincb, pincb_arg);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.genkey)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.genkey (card->app, ctrl, keynostr, keytype, flags,
+ createtime, pincb, pincb_arg);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation genkey result: %s\n", gpg_strerror (err));
@@ -1194,12 +1226,15 @@ app_get_challenge (card_t card, ctrl_t ctrl,
if (!card || !nbytes || !buffer)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
err = lock_card (card, ctrl);
if (err)
return err;
- err = iso7816_get_challenge (card->slot, nbytes, buffer);
+
+ if (!card->ref_count)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else
+ err = iso7816_get_challenge (card->slot, nbytes, buffer);
+
unlock_card (card);
return err;
}
@@ -1216,15 +1251,18 @@ app_change_pin (card_t card, ctrl_t ctrl, const char *chvnostr,
if (!card || !chvnostr || !*chvnostr || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.change_pin)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.change_pin (card->app, ctrl,
- chvnostr, flags, pincb, pincb_arg);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.change_pin)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.change_pin (card->app, ctrl,
+ chvnostr, flags, pincb, pincb_arg);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation change_pin result: %s\n", gpg_strerror (err));
@@ -1244,14 +1282,17 @@ app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr,
if (!card || !keyidstr || !*keyidstr || !pincb)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!card->ref_count || !card->app)
- return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
- if (!card->app->fnc.check_pin)
- return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
err = lock_card (card, ctrl);
if (err)
return err;
- err = card->app->fnc.check_pin (card->app, keyidstr, pincb, pincb_arg);
+
+ if (!card->ref_count || !card->app)
+ err = gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+ else if (!card->app->fnc.check_pin)
+ err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+ else
+ err = card->app->fnc.check_pin (card->app, keyidstr, pincb, pincb_arg);
+
unlock_card (card);
if (opt.verbose)
log_info ("operation check_pin result: %s\n", gpg_strerror (err));
@@ -1464,7 +1505,7 @@ app_do_with_keygrip (ctrl_t ctrl, int action, const char *keygrip_str)
/* FIXME: Add app switching logic. The above code assumes that the
* actions can be performend without switching. This needs to be
* checked. For a lookup we also need to reorder the apps so that
- * the selected one will be used. */
+ * the selected one will be used. */
npth_mutex_unlock (&card_list_lock);
return c;