From f070c99b65850ba2f2d40192b59a70712a7902a9 Mon Sep 17 00:00:00 2001 From: Peter Popovec Date: Wed, 6 Mar 2019 13:34:22 +0100 Subject: [PATCH] opensc-tool: do not use card driver to read ATR If card driver fails to connect to card, 'opensc-tool -a' may fail to print ATR even if ATR is available from card reader. Before use of card driver, do only card reader connect, then print ATR. Only if it is neccesary, use card driver for the rest of opensc-tool functions. --- src/tools/opensc-tool.c | 43 ++++++++++++++++++++++++++++------------- src/tools/util.c | 40 ++++++++++++++++++++++++-------------- src/tools/util.h | 2 ++ 3 files changed, 57 insertions(+), 28 deletions(-) diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 81b9af0f..4b309e14 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -712,6 +712,7 @@ int main(int argc, char *argv[]) const char *opt_conf_entry = NULL; const char *opt_reset_type = NULL; char **p; + struct sc_reader *reader = NULL; sc_context_param_t ctx_param; while (1) { @@ -846,6 +847,24 @@ int main(int argc, char *argv[]) goto end; action_count--; } + + err = util_connect_reader(ctx, &reader, opt_reader, opt_wait, verbose); + if (err) { + fprintf(stderr, "Failed to connect to reader: %s\n", sc_strerror(err)); + err = 1; + goto end; + } + if (do_print_atr) { + if (verbose) { + printf("Card ATR:\n"); + util_hex_dump_asc(stdout, reader->atr.value, reader->atr.len, -1); + } else { + char tmp[SC_MAX_ATR_SIZE*3]; + sc_bin_to_hex(reader->atr.value, reader->atr.len, tmp, sizeof(tmp) - 1, ':'); + fprintf(stdout,"%s\n",tmp); + } + action_count--; + } if (action_count <= 0) goto end; @@ -858,21 +877,19 @@ int main(int argc, char *argv[]) } } - err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, verbose); - if (err) - goto end; + if (verbose) + printf("Connecting to card in reader %s...\n", reader->name); - if (do_print_atr) { - if (verbose) { - printf("Card ATR:\n"); - util_hex_dump_asc(stdout, card->atr.value, card->atr.len, -1); - } else { - char tmp[SC_MAX_ATR_SIZE*3]; - sc_bin_to_hex(card->atr.value, card->atr.len, tmp, sizeof(tmp) - 1, ':'); - fprintf(stdout,"%s\n",tmp); - } - action_count--; + err = sc_connect_card(reader, &card); + if (err < 0) { + fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(err)); + err = 1; + goto end; } + + if (verbose) + printf("Using card driver %s.\n", card->driver->name); + if (do_print_serial) { if (verbose) printf("Card serial number:"); diff --git a/src/tools/util.c b/src/tools/util.c index 5b8492e6..f0893177 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -48,12 +48,10 @@ is_string_valid_atr(const char *atr_str) return 1; } -int -util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, - const char *reader_id, int do_wait, int do_lock, int verbose) +int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, + const char *reader_id, int do_wait, int verbose) { - struct sc_reader *reader = NULL, *found = NULL; - struct sc_card *card = NULL; + struct sc_reader *found = NULL; int r; setbuf(stderr, NULL); @@ -88,7 +86,7 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, fprintf(stderr, "Error while waiting for a card: %s\n", sc_strerror(r)); return 3; } - reader = found; + *reader = found; } else if (sc_ctx_get_reader_count(ctx) == 0) { fprintf(stderr, "No smart card readers found.\n"); @@ -99,14 +97,14 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, unsigned int i; /* Automatically try to skip to a reader with a card if reader not specified */ for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) { - reader = sc_ctx_get_reader(ctx, i); - if (sc_detect_card_presence(reader) & SC_READER_CARD_PRESENT) { - fprintf(stderr, "Using reader with a card: %s\n", reader->name); + *reader = sc_ctx_get_reader(ctx, i); + if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { + fprintf(stderr, "Using reader with a card: %s\n", (*reader)->name); goto autofound; } } /* If no reader had a card, default to the first reader */ - reader = sc_ctx_get_reader(ctx, 0); + *reader = sc_ctx_get_reader(ctx, 0); } else { /* If the reader identifier looks like an ATR, try to find the reader with that card */ @@ -128,7 +126,7 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, continue; fprintf(stderr, "Matched ATR in reader: %s\n", rdr->name); - reader = rdr; + *reader = rdr; goto autofound; } } @@ -139,24 +137,36 @@ util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, errno = 0; num = strtol(reader_id, &endptr, 0); if (!errno && endptr && *endptr == '\0') - reader = sc_ctx_get_reader(ctx, num); + *reader = sc_ctx_get_reader(ctx, num); else - reader = sc_ctx_get_reader_by_name(ctx, reader_id); + *reader = sc_ctx_get_reader_by_name(ctx, reader_id); } } autofound: - if (!reader) { + if (!(*reader)) { fprintf(stderr, "Reader \"%s\" not found (%d reader(s) detected)\n", reader_id, sc_ctx_get_reader_count(ctx)); return 1; } - if (sc_detect_card_presence(reader) <= 0) { + if (sc_detect_card_presence(*reader) <= 0) { fprintf(stderr, "Card not present.\n"); return 3; } } + return 0; +} +int +util_connect_card_ex(sc_context_t *ctx, sc_card_t **cardp, + const char *reader_id, int do_wait, int do_lock, int verbose) +{ + struct sc_reader *reader = NULL; + struct sc_card *card = NULL; + int r; + r = util_connect_reader(ctx, &reader, reader_id, do_wait, verbose); + if(r) + return r; if (verbose) printf("Connecting to card in reader %s...\n", reader->name); r = sc_connect_card(reader, &card); diff --git a/src/tools/util.h b/src/tools/util.h index 26b60c29..21c8293e 100644 --- a/src/tools/util.h +++ b/src/tools/util.h @@ -45,6 +45,8 @@ const char * util_acl_to_str(const struct sc_acl_entry *e); void util_warn(const char *fmt, ...); void util_error(const char *fmt, ...); NORETURN void util_fatal(const char *fmt, ...); + +int util_connect_reader (sc_context_t *ctx, sc_reader_t **reader, const char *reader_id, int do_wait, int verbose); /* All singing all dancing card connect routine */ int util_connect_card_ex(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int do_lock, int verbose); int util_connect_card(struct sc_context *, struct sc_card **, const char *reader_id, int do_wait, int verbose);