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.
This commit is contained in:
Peter Popovec 2019-03-06 13:34:22 +01:00 committed by Frank Morgner
parent b389b19ca5
commit f070c99b65
3 changed files with 57 additions and 28 deletions

View File

@ -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:");

View File

@ -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);

View File

@ -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);