tools: t404: redesign treatment of 'reader' option

in previous version
first of all the 'reader' option's value was converted to hexadecimal form,
used as ATR value
and all present readers where scanned to find the inserted card with such ATR.
Only after this the 'reader' option was used as reader's number or reader's name.

Currently in use the 'hex-to-bin' procedure accepts for conversion one digit,
and so even if the 'reader' option value is one digit,
the useless search over all present readers take place.

In the current version the order of checks if kept (ATR, reader's number, reader's name),
but enforced the validity check of ATR, presented by 'reader' option.
Also the option is accepted as reader's number only if the 'entire' option's string can be converted to integer.

Thanks to 'jbwisemo' for cooperation.
https://www.opensc-project.org/opensc/ticket/404
This commit is contained in:
Viktor Tarasov 2012-08-25 20:08:56 +02:00
parent 41861e42b0
commit 8c342ec772
1 changed files with 64 additions and 37 deletions

View File

@ -31,12 +31,28 @@
#include <ctype.h>
#include "util.h"
int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
int
is_string_valid_atr(const char *atr_str)
{
unsigned char atr[SC_MAX_ATR_SIZE];
size_t atr_len = sizeof(atr);
if (sc_hex_to_bin(atr_str, atr, &atr_len))
return 0;
if (atr_len < 2)
return 0;
if (atr[0] != 0x3B && atr[0] != 0x3F)
return 0;
return 1;
}
int
util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
const char *reader_id, int do_wait, int verbose)
{
sc_reader_t *reader, *found;
sc_card_t *card;
int r, tmp_reader_num;
struct sc_reader *reader = NULL, *found = NULL;
struct sc_card *card = NULL;
int r;
if (do_wait) {
unsigned int event;
@ -61,11 +77,12 @@ int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
return 3;
}
reader = found;
} else {
if (sc_ctx_get_reader_count(ctx) == 0) {
fprintf(stderr, "No smart card readers found.\n");
return 1;
}
}
else if (sc_ctx_get_reader_count(ctx) == 0) {
fprintf(stderr, "No smart card readers found.\n");
return 1;
}
else {
if (!reader_id) {
unsigned int i;
/* Automatically try to skip to a reader with a card if reader not specified */
@ -78,35 +95,47 @@ int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
}
/* If no reader had a card, default to the first reader */
reader = sc_ctx_get_reader(ctx, 0);
} else {
/* If the reader identifiers looks like an ATR, try to find the reader with that card */
unsigned char atr_buf[SC_MAX_ATR_SIZE * 3];
size_t atr_buf_len = sizeof(atr_buf);
unsigned int i;
}
else {
/* If the reader identifier looks like an ATR, try to find the reader with that card */
if (is_string_valid_atr(reader_id)) {
unsigned char atr_buf[SC_MAX_ATR_SIZE * 3];
size_t atr_buf_len = sizeof(atr_buf);
unsigned int i;
if (sc_hex_to_bin(reader_id, atr_buf, &atr_buf_len) == SC_SUCCESS) {
sc_hex_to_bin(reader_id, atr_buf, &atr_buf_len);
/* Loop readers, looking for a card with ATR */
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) && (reader->atr.len > 0)) {
if (!memcmp(reader->atr.value, atr_buf, reader->atr.len)) {
fprintf(stderr, "Matched ATR in reader: %s\n", reader->name);
goto autofound;
}
}
struct sc_reader *rdr = sc_ctx_get_reader(ctx, i);
if (!(sc_detect_card_presence(rdr) & SC_READER_CARD_PRESENT))
continue;
else if (rdr->atr.len != atr_buf_len)
continue;
else if (memcmp(rdr->atr.value, atr_buf, rdr->atr.len))
continue;
fprintf(stderr, "Matched ATR in reader: %s\n", rdr->name);
reader = rdr;
goto autofound;
}
}
if (!sscanf(reader_id, "%d", &tmp_reader_num)) {
/* Try to get the reader by name if it does not parse as a number */
reader = sc_ctx_get_reader_by_name(ctx, reader_id);
} else {
reader = sc_ctx_get_reader(ctx, tmp_reader_num);
else {
char *endptr = NULL;
unsigned int num;
errno = 0;
num = strtol(reader_id, &endptr, 0);
if (!errno && endptr && *endptr == '\0')
reader = sc_ctx_get_reader(ctx, num);
else
reader = sc_ctx_get_reader_by_name(ctx, reader_id);
}
}
autofound:
if (!reader) {
fprintf(stderr,
"Reader \"%s\" not found (%d reader(s) detected)\n", reader_id, sc_ctx_get_reader_count(ctx));
fprintf(stderr, "Reader \"%s\" not found (%d reader(s) detected)\n",
reader_id, sc_ctx_get_reader_count(ctx));
return 1;
}
@ -118,20 +147,18 @@ autofound:
if (verbose)
printf("Connecting to card in reader %s...\n", reader->name);
if ((r = sc_connect_card(reader, &card)) < 0) {
fprintf(stderr,
"Failed to connect to card: %s\n",
sc_strerror(r));
r = sc_connect_card(reader, &card);
if (r < 0) {
fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r));
return 1;
}
if (verbose)
printf("Using card driver %s.\n", card->driver->name);
if ((r = sc_lock(card)) < 0) {
fprintf(stderr,
"Failed to lock card: %s\n",
sc_strerror(r));
r = sc_lock(card);
if (r < 0) {
fprintf(stderr, "Failed to lock card: %s\n", sc_strerror(r));
sc_disconnect_card(card);
return 1;
}