aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scd/app-common.h2
-rw-r--r--scd/app.c43
-rw-r--r--scd/command.c9
3 files changed, 34 insertions, 20 deletions
diff --git a/scd/app-common.h b/scd/app-common.h
index 3925eacf7..a13623fde 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -228,7 +228,7 @@ char *app_get_serialno (app_t app);
void app_dump_state (void);
void application_notify_card_reset (int slot);
-gpg_error_t check_application_conflict (const char *name, card_t card);
+gpg_error_t check_application_conflict (card_t card, const char *name);
gpg_error_t card_reset (card_t card, ctrl_t ctrl, int send_reset);
gpg_error_t select_application (ctrl_t ctrl, const char *name, card_t *r_app,
int scan, const unsigned char *serialno_bin,
diff --git a/scd/app.c b/scd/app.c
index 61ae5c27a..b415668f0 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -235,15 +235,23 @@ is_app_allowed (const char *name)
}
-static gpg_error_t
-check_conflict (card_t card, const char *name)
+/* This function is mainly used by the serialno command to check for
+ * an application conflict which may appear if the serialno command is
+ * used to request a specific application and the connection has
+ * already done a select_application. Return values are:
+ * 0 - No conflict
+ * GPG_ERR_FALSE - Another application is in use but it is possible
+ * to switch to the requested application.
+ * other code - Switching is not possible.
+ */
+gpg_error_t
+check_application_conflict (card_t card, const char *name)
{
if (!card || !name)
return 0;
if (!card->app)
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); /* Should not happen. */
- /* FIXME: Needs changes for app switching. */
if (!card->app->apptype
|| !ascii_strcasecmp (strapptype (card->app->apptype), name))
return 0;
@@ -251,6 +259,22 @@ check_conflict (card_t card, const char *name)
if (card->app->apptype == APPTYPE_UNDEFINED)
return 0;
+ if (card->cardtype == CARDTYPE_YUBIKEY)
+ {
+ if (card->app->apptype == APPTYPE_OPENPGP)
+ {
+ /* Current app is OpenPGP. */
+ if (!ascii_strcasecmp (name, "piv"))
+ return gpg_error (GPG_ERR_FALSE); /* Switching allowed. */
+ }
+ else if (card->app->apptype == APPTYPE_PIV)
+ {
+ /* Current app is PIV. */
+ if (!ascii_strcasecmp (name, "openpgp"))
+ return gpg_error (GPG_ERR_FALSE); /* Switching allowed. */
+ }
+ }
+
log_info ("application '%s' in use - can't switch\n",
strapptype (card->app->apptype));
@@ -258,17 +282,6 @@ check_conflict (card_t card, const char *name)
}
-/* This function is used by the serialno command to check for an
- application conflict which may appear if the serialno command is
- used to request a specific application and the connection has
- already done a select_application. */
-gpg_error_t
-check_application_conflict (const char *name, card_t card)
-{
- return check_conflict (card, name);
-}
-
-
gpg_error_t
card_reset (card_t card, ctrl_t ctrl, int send_reset)
{
@@ -607,7 +620,7 @@ select_application (ctrl_t ctrl, const char *name, card_t *r_card,
if (card)
{
- err = check_conflict (card, name);
+ err = check_application_conflict (card, name);
if (!err)
{
/* Note: We do not use card_ref as we are already locked. */
diff --git a/scd/command.c b/scd/command.c
index c45737376..3156aa9ef 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -220,7 +220,8 @@ open_card (ctrl_t ctrl)
/* Explicitly open a card for a specific use of APPTYPE or SERIALNO. */
static gpg_error_t
-open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
+open_card_with_request (ctrl_t ctrl,
+ const char *apptypestr, const char *serialno)
{
gpg_error_t err;
unsigned char *serialno_bin = NULL;
@@ -231,8 +232,8 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
need to check that the client didn't requested a specific
application different from the one in use before we continue. */
/* FIXME: Extend to allow switching between apps. */
- if (apptype && ctrl->card_ctx)
- return check_application_conflict (apptype, ctrl->card_ctx);
+ if (apptypestr && ctrl->card_ctx)
+ return check_application_conflict (ctrl->card_ctx, apptypestr);
/* Re-scan USB devices. Release CARD, before the scan. */
/* FIXME: Is a card_unref sufficient or do we need to deallocate? */
@@ -242,7 +243,7 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
if (serialno)
serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
- err = select_application (ctrl, apptype, &ctrl->card_ctx, 1,
+ err = select_application (ctrl, apptypestr, &ctrl->card_ctx, 1,
serialno_bin, serialno_bin_len);
xfree (serialno_bin);