diff options
author | Werner Koch <[email protected]> | 2019-06-21 12:01:06 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2019-06-21 12:01:06 +0000 |
commit | 0400a4eb1782e7a4aea5b04492c93939c6b9799a (patch) | |
tree | dcfb5fe3009f476df0c9eb792e2843bd91dd1a72 | |
parent | scd: Add code to check whether app switching is possible. (diff) | |
download | gnupg-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.c | 267 |
1 files changed, 154 insertions, 113 deletions
@@ -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; |