aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;