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:
parent
1b78e4951e
commit
0400a4eb17
267
scd/app.c
267
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user