- 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:
okir 2002-12-03 15:40:40 +00:00
parent 5e8a76d6da
commit d635d53771
4 changed files with 89 additions and 3 deletions

View File

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

View File

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

View File

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

View File

@ -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 {