diff options
-rw-r--r-- | scd/app-common.h | 2 | ||||
-rw-r--r-- | scd/app.c | 43 | ||||
-rw-r--r-- | scd/command.c | 9 |
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, @@ -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); |