- support ATR maps in /etc/opensc.conf, e.g.
card_driver flex { atr = 11:22:33:44; atr = 55:66:77:88; } git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@738 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
5e8a76d6da
commit
d635d53771
|
@ -326,6 +326,7 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
|
|||
struct sc_card *card;
|
||||
struct sc_context *ctx = reader->ctx;
|
||||
struct sc_slot_info *slot = _sc_get_slot_info(reader, slot_id);
|
||||
const struct sc_card_driver *driver;
|
||||
int i, r = 0, connected = 0;
|
||||
|
||||
assert(card_out != NULL);
|
||||
|
@ -352,8 +353,20 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
|
|||
|
||||
_sc_parse_atr(reader->ctx, slot);
|
||||
|
||||
if (ctx->forced_driver != NULL) {
|
||||
card->driver = ctx->forced_driver;
|
||||
/* See if the ATR matches any ATR specified in the config file */
|
||||
if ((driver = ctx->forced_driver) == NULL) {
|
||||
for (i = 0; ctx->card_drivers[i] != NULL; i++) {
|
||||
driver = ctx->card_drivers[i];
|
||||
if (_sc_match_atr(card, driver->atr_map, NULL) == 0)
|
||||
break;
|
||||
driver = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (driver != NULL) {
|
||||
/* Forced driver, or matched via ATR mapping from
|
||||
* config file */
|
||||
card->driver = driver;
|
||||
memcpy(card->ops, card->driver->ops, sizeof(struct sc_card_operations));
|
||||
if (card->ops->init != NULL) {
|
||||
r = card->ops->init(card);
|
||||
|
@ -804,6 +817,9 @@ int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *id_out)
|
|||
size_t atr_len = card->atr_len;
|
||||
int i = 0;
|
||||
|
||||
if (table == NULL)
|
||||
return -1;
|
||||
|
||||
for (i = 0; table[i].atr != NULL; i++) {
|
||||
if (table[i].atr_len != atr_len)
|
||||
continue;
|
||||
|
@ -815,3 +831,25 @@ int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *id_out)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _sc_add_atr(struct sc_card_driver *driver,
|
||||
const u8 *atr, size_t atrlen, int id)
|
||||
{
|
||||
struct sc_atr_table *map, *entry;
|
||||
u8 *dst_atr;
|
||||
|
||||
map = (struct sc_atr_table *) realloc(driver->atr_map,
|
||||
(driver->natrs + 2) * sizeof(struct sc_atr_table));
|
||||
if (!map)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
driver->atr_map = map;
|
||||
if (!(dst_atr = (u8 *) malloc(atrlen)))
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
entry = &driver->atr_map[driver->natrs++];
|
||||
memset(entry+1, 0, sizeof(*entry));
|
||||
entry->atr = dst_atr;
|
||||
entry->atr_len = atrlen;
|
||||
entry->id = id;
|
||||
memcpy(dst_atr, atr, atrlen);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ struct _sc_driver_entry {
|
|||
char *name;
|
||||
void *func;
|
||||
char *libpath;
|
||||
struct sc_atr_table *atrs;
|
||||
unsigned int natrs;
|
||||
};
|
||||
|
||||
static const struct _sc_driver_entry internal_card_drivers[] = {
|
||||
|
@ -243,6 +245,45 @@ static int load_reader_drivers(struct sc_context *ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int load_card_driver_options(struct sc_context *ctx,
|
||||
struct sc_card_driver *driver)
|
||||
{
|
||||
scconf_block **blocks, *blk;
|
||||
const scconf_list *list;
|
||||
int i, r;
|
||||
|
||||
for (i = 0; ctx->conf_blocks[i]; i++) {
|
||||
u8 atr_buf[SC_MAX_ATR_SIZE];
|
||||
size_t atr_len;
|
||||
|
||||
blocks = scconf_find_blocks(ctx->conf,
|
||||
ctx->conf_blocks[i],
|
||||
"card_driver", driver->short_name);
|
||||
blk = blocks[0];
|
||||
free(blocks);
|
||||
|
||||
if (blk == NULL)
|
||||
continue;
|
||||
|
||||
list = scconf_find_list(blk, "atr");
|
||||
while (list != NULL) {
|
||||
atr_len = sizeof(atr_buf);
|
||||
r = sc_hex_to_bin(list->data,
|
||||
atr_buf, &atr_len);
|
||||
if (r < 0) {
|
||||
error(ctx,
|
||||
"Unable to parse ATR '%s'.\n",
|
||||
list->data);
|
||||
continue;
|
||||
}
|
||||
_sc_add_atr(driver, atr_buf, atr_len, 0);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_card_drivers(struct sc_context *ctx,
|
||||
struct _sc_ctx_options *opts)
|
||||
{
|
||||
|
@ -270,10 +311,12 @@ static int load_card_drivers(struct sc_context *ctx,
|
|||
continue;
|
||||
}
|
||||
ctx->card_drivers[drv_count] = func();
|
||||
|
||||
load_card_driver_options(ctx, ctx->card_drivers[drv_count]);
|
||||
drv_count++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void process_config_file(struct sc_context *ctx, struct _sc_ctx_options *opts)
|
||||
{
|
||||
|
|
|
@ -50,6 +50,9 @@ int _sc_add_reader(struct sc_context *ctx, struct sc_reader *reader);
|
|||
int _sc_parse_atr(struct sc_context *ctx, struct sc_slot_info *slot);
|
||||
struct sc_slot_info * _sc_get_slot_info(struct sc_reader *reader, int slot_id);
|
||||
|
||||
/* Add an ATR to the card driver's struct sc_atr_table */
|
||||
int _sc_add_atr(struct sc_card_driver *, const u8 *, size_t, int);
|
||||
|
||||
/* Returns an index number if a match was found, -1 otherwise. table has to
|
||||
* be null terminated. */
|
||||
int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *id_out);
|
||||
|
|
|
@ -470,6 +470,8 @@ struct sc_card_driver {
|
|||
const char *name;
|
||||
const char *short_name;
|
||||
struct sc_card_operations *ops;
|
||||
struct sc_atr_table *atr_map;
|
||||
unsigned int natrs;
|
||||
};
|
||||
|
||||
struct sc_context {
|
||||
|
|
Loading…
Reference in New Issue