1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-30 16:17:02 +01:00

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 <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-06-21 14:01:06 +02:00
parent 1b78e4951e
commit 0400a4eb17
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

267
scd/app.c
View File

@ -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;