aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-06-25 07:48:18 +0000
committerWerner Koch <[email protected]>2019-06-25 07:48:18 +0000
commit92ba831758cff0262504ac51e5df7a439844327c (patch)
treeffe322a44bef967d303b80e48d502c31d9ed936a
parentscd: Return a stable list with "getinfo card_list". (diff)
downloadgnupg-92ba831758cff0262504ac51e5df7a439844327c.tar.gz
gnupg-92ba831758cff0262504ac51e5df7a439844327c.zip
scd: Do not conflict if a card with another serialno is demanded.
* scd/app.c (check_application_conflict): Add args to pass a serialno. * scd/command.c (open_card_with_request): Pass the serialno to check_application_conflict. -- Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--scd/app-common.h4
-rw-r--r--scd/app.c18
-rw-r--r--scd/command.c14
3 files changed, 26 insertions, 10 deletions
diff --git a/scd/app-common.h b/scd/app-common.h
index 460046f89..5866c9b32 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -229,7 +229,9 @@ 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 (card_t card, const char *name);
+gpg_error_t check_application_conflict (card_t card, const char *name,
+ const unsigned char *serialno_bin,
+ size_t serialno_bin_len);
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 1ad6b9ed6..ed7adc3a3 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -260,10 +260,15 @@ is_app_allowed (const char *name)
* 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.
+ * Other code - Switching is not possible.
+ *
+ * If SERIALNO_BIN is not NULL a coflict is onl asserted if the
+ * serialno of the card matches.
*/
gpg_error_t
-check_application_conflict (card_t card, const char *name)
+check_application_conflict (card_t card, const char *name,
+ const unsigned char *serialno_bin,
+ size_t serialno_bin_len)
{
app_t app;
@@ -272,6 +277,13 @@ check_application_conflict (card_t card, const char *name)
if (!card->app)
return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); /* Should not happen. */
+ if (serialno_bin && card->serialno)
+ {
+ if (serialno_bin_len != card->serialnolen
+ || memcmp (serialno_bin, card->serialno, card->serialnolen))
+ return 0; /* The card does not match the requested S/N. */
+ }
+
/* Check whether the requested NAME matches any already selected
* application. */
for (app = card->app; app; app = app->next)
@@ -638,7 +650,7 @@ select_application (ctrl_t ctrl, const char *name, card_t *r_card,
if (card)
{
- err = check_application_conflict (card, name);
+ err = check_application_conflict (card, name, NULL, 0);
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 f341b6ae2..0096ca96d 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -228,18 +228,22 @@ open_card_with_request (ctrl_t ctrl,
size_t serialno_bin_len = 0;
card_t card = ctrl->card_ctx;
+ if (serialno)
+ serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
+
/* If we are already initialized for one specific application we
need to check that the client didn't requested a specific
application different from the one in use before we continue. */
if (apptypestr && ctrl->card_ctx)
{
- err = check_application_conflict (ctrl->card_ctx, apptypestr);
+ err = check_application_conflict (ctrl->card_ctx, apptypestr,
+ serialno_bin, serialno_bin_len);
if (gpg_err_code (err) == GPG_ERR_FALSE)
{
/* Different application but switching is supported. */
err = select_additional_application (ctrl, apptypestr);
}
- return err;
+ goto leave;
}
/* Re-scan USB devices. Release CARD, before the scan. */
@@ -247,13 +251,11 @@ open_card_with_request (ctrl_t ctrl,
ctrl->card_ctx = NULL;
card_unref (card);
- if (serialno)
- serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
-
err = select_application (ctrl, apptypestr, &ctrl->card_ctx, 1,
serialno_bin, serialno_bin_len);
- xfree (serialno_bin);
+ leave:
+ xfree (serialno_bin);
return err;
}