static int asepcos_match_card(sc_card_t *card) { int i = _sc_match_atr(card, asepcos_atrs, &card->type); if (i < 0) return 0; return 1; }
static int mcrd_match_card(sc_card_t * card) { int i = 0, r = 0; sc_apdu_t apdu; i = _sc_match_atr(card, mcrd_atrs, &card->type); if (i >= 0) { card->name = mcrd_atrs[i].name; return 1; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00); apdu.lc = sizeof(EstEID_v35_AID); apdu.data = EstEID_v35_AID; apdu.datalen = sizeof(EstEID_v35_AID); apdu.resplen = 0; apdu.le = 0; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2); if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { sc_log(card->ctx, "AID found"); card->type = SC_CARD_TYPE_MCRD_ESTEID_V30; return 1; } return 0; }
static int cardos_match_card(sc_card_t *card) { unsigned char atr[SC_MAX_ATR_SIZE]; int i; i = _sc_match_atr(card, cardos_atrs, &card->type); if (i < 0) return 0; memcpy(atr, card->atr.value, sizeof(atr)); /* Do not change card type for CIE! */ if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1) return 1; if (card->type == SC_CARD_TYPE_CARDOS_M4_4) return 1; if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { int rv; sc_apdu_t apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; /* first check some additional ATR bytes */ if ((atr[4] != 0xff && atr[4] != 0x02) || (atr[6] != 0x10 && atr[6] != 0x0a) || (atr[9] != 0x55 && atr[9] != 0x58)) return 0; /* get the os version using GET DATA and compare it with * version in the ATR */ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "checking cardos version ..."); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x82); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = 256; apdu.lc = 0; rv = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return 0; if (apdu.resp[0] != atr[10] || apdu.resp[1] != atr[11]) /* version mismatch */ return 0; if (atr[11] <= 0x04) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos m4.01"); card->type = SC_CARD_TYPE_CARDOS_M4_01; } else if (atr[11] == 0x08) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.3b"); card->type = SC_CARD_TYPE_CARDOS_M4_3; } else if (atr[11] == 0x09) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.2b"); card->type = SC_CARD_TYPE_CARDOS_M4_2B; } else if (atr[11] >= 0x0B) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos v4.2c or higher"); card->type = SC_CARD_TYPE_CARDOS_M4_2C; } else { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "found cardos m4.2"); } } return 1; }
static int esteid_match_card(sc_card_t *card) { int i = _sc_match_atr(card, esteid_atrs, &card->type); if (i >= 0 && gp_select_aid(card, &IASECC_AID) == SC_SUCCESS) { card->name = esteid_atrs[i].name; return 1; } return 0; }
static int belpic_match_card(sc_card_t *card) { int i; i = _sc_match_atr(card, belpic_atrs, &card->type); if (i < 0) return 0; return 1; }
static int incrypto34_match_card(struct sc_card *card) { int i; i = _sc_match_atr(card, incrypto34_atrs, &card->type); if (i < 0) return 0; return 1; }
static int gemsafe_match_card(sc_card_t *card) { int i; i = _sc_match_atr(card, gemsafe_atrs, &card->type); if (i < 0) return 0; return 1; }
static int mcrd_match_card(sc_card_t * card) { int i = 0; i = _sc_match_atr(card, mcrd_atrs, &card->type); if (i >= 0) { card->name = mcrd_atrs[i].name; return 1; } return 0; }
/* the entersafe part */ static int entersafe_match_card(sc_card_t *card) { int i; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); i = _sc_match_atr(card, entersafe_atrs, &card->type); if (i < 0) return 0; return 1; }
static int mcrd_match_card(sc_card_t * card) { int i; if (is_esteid_atr(card->atr, card->atr_len)) { sc_debug(card->ctx, "Found EstEID ver 1.0 card!"); card->type = SC_CARD_TYPE_MCRD_ESTEID; return 1; } i = _sc_match_atr(card, mcrd_atrs, &card->type); if (i < 0) return 0; return 1; }
static int cyberflex_match_card(sc_card_t *card) { int i; i = _sc_match_atr(card, flex_atrs, NULL); if (i < 0) return 0; switch (flex_atrs[i].type) { case SC_CARD_TYPE_FLEX_CYBER: card->name = flex_atrs[i].name; card->type = flex_atrs[i].type; card->flags = flex_atrs[i].flags; return 1; } return 0; }
static int jpki_match_card(struct sc_card *card) { int i, rc; i = _sc_match_atr(card, jpki_atrs, &card->type); if (i >= 0) { return 1; } rc = jpki_select_ap(card); if (rc == SC_SUCCESS) { card->type = SC_CARD_TYPE_JPKI_BASE; return 1; } return 0; }
int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out) { sc_card_t *card; sc_context_t *ctx; struct sc_card_driver *driver; int i, r = 0, idx, connected = 0; if (card_out == NULL || reader == NULL) return SC_ERROR_INVALID_ARGUMENTS; ctx = reader->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (reader->ops->connect == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); card = sc_card_new(ctx); if (card == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); r = reader->ops->connect(reader); if (r) goto err; connected = 1; card->reader = reader; card->ctx = ctx; if (reader->flags & SC_READER_ENABLE_ESCAPE) sc_detect_escape_cmds(reader); memcpy(&card->atr, &reader->atr, sizeof(card->atr)); memcpy(&card->uid, &reader->uid, sizeof(card->uid)); _sc_parse_atr(reader); /* See if the ATR matches any ATR specified in the config file */ if ((driver = ctx->forced_driver) == NULL) { sc_log(ctx, "matching configured ATRs"); for (i = 0; ctx->card_drivers[i] != NULL; i++) { driver = ctx->card_drivers[i]; if (driver->atr_map == NULL || !strcmp(driver->short_name, "default")) { driver = NULL; continue; } sc_log(ctx, "trying driver '%s'", driver->short_name); idx = _sc_match_atr(card, driver->atr_map, NULL); if (idx >= 0) { struct sc_atr_table *src = &driver->atr_map[idx]; sc_log(ctx, "matched driver '%s'", driver->name); /* It's up to card driver to notice these correctly */ card->name = src->name; card->type = src->type; card->flags = src->flags; 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->match_card != NULL) if (card->ops->match_card(card) != 1) sc_log(ctx, "driver '%s' match_card() failed: %s (will continue anyway)", card->driver->name, sc_strerror(r)); if (card->ops->init != NULL) { r = card->ops->init(card); if (r) { sc_log(ctx, "driver '%s' init() failed: %s", card->driver->name, sc_strerror(r)); goto err; } } } else { sc_card_t uninitialized = *card; sc_log(ctx, "matching built-in ATRs"); for (i = 0; ctx->card_drivers[i] != NULL; i++) { /* FIXME If we had a clean API description, we'd propably get a * cleaner implementation of the driver's match_card and init, * which should normally *not* modify the card object if * unsuccessful. However, after years of relentless hacking, reality * is different: The card object is changed in virtually every card * driver so in order to prevent unwanted interaction, we reset the * card object here and hope that the card driver at least doesn't * allocate any internal ressources that need to be freed. If we * had more time, we should refactor the existing code to not * modify sc_card_t until complete success (possibly by combining * `match_card()` and `init()`) */ *card = uninitialized; struct sc_card_driver *drv = ctx->card_drivers[i]; const struct sc_card_operations *ops = drv->ops; sc_log(ctx, "trying driver '%s'", drv->short_name); if (ops == NULL || ops->match_card == NULL) { continue; } else if (!(ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER) && !strcmp("default", drv->short_name)) { sc_log(ctx , "ignore 'default' card driver"); continue; } /* Needed if match_card() needs to talk with the card (e.g. card-muscle) */ *card->ops = *ops; if (ops->match_card(card) != 1) continue; sc_log(ctx, "matched: %s", drv->name); memcpy(card->ops, ops, sizeof(struct sc_card_operations)); card->driver = drv; r = ops->init(card); if (r) { sc_log(ctx, "driver '%s' init() failed: %s", drv->name, sc_strerror(r)); if (r == SC_ERROR_INVALID_CARD) { card->driver = NULL; continue; } goto err; } break; } } if (card->driver == NULL) { sc_log(ctx, "unable to find driver for inserted card"); r = SC_ERROR_INVALID_CARD; goto err; } if (card->name == NULL) card->name = card->driver->name; /* initialize max_send_size/max_recv_size to a meaningful value */ card->max_recv_size = sc_get_max_recv_size(card); card->max_send_size = sc_get_max_send_size(card); sc_log(ctx, "card info name:'%s', type:%i, flags:0x%lX, max_send/recv_size:%"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u", card->name, card->type, card->flags, card->max_send_size, card->max_recv_size); #ifdef ENABLE_SM /* Check, if secure messaging module present. */ r = sc_card_sm_check(card); if (r) { sc_log(ctx, "cannot load secure messaging module"); goto err; } #endif *card_out = card; LOG_FUNC_RETURN(ctx, SC_SUCCESS); err: if (connected) reader->ops->disconnect(reader); if (card != NULL) sc_card_free(card); LOG_FUNC_RETURN(ctx, r); }
int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out) { sc_card_t *card; sc_context_t *ctx; struct sc_card_driver *driver; int i, r = 0, idx, connected = 0; if (card_out == NULL || reader == NULL) return SC_ERROR_INVALID_ARGUMENTS; ctx = reader->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (reader->ops->connect == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); card = sc_card_new(ctx); if (card == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); r = reader->ops->connect(reader); if (r) goto err; connected = 1; card->reader = reader; card->ctx = ctx; memcpy(&card->atr, &reader->atr, sizeof(card->atr)); _sc_parse_atr(reader); /* See if the ATR matches any ATR specified in the config file */ if ((driver = ctx->forced_driver) == NULL) { sc_log(ctx, "matching configured ATRs"); for (i = 0; ctx->card_drivers[i] != NULL; i++) { driver = ctx->card_drivers[i]; if (driver->atr_map == NULL || !strcmp(driver->short_name, "default")) { driver = NULL; continue; } sc_log(ctx, "trying driver '%s'", driver->short_name); idx = _sc_match_atr(card, driver->atr_map, NULL); if (idx >= 0) { struct sc_atr_table *src = &driver->atr_map[idx]; sc_log(ctx, "matched driver '%s'", driver->name); /* It's up to card driver to notice these correctly */ card->name = src->name; card->type = src->type; card->flags = src->flags; 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->match_card != NULL) if (card->ops->match_card(card) != 1) sc_log(ctx, "driver '%s' match_card() failed: %s (will continue anyway)", card->driver->name, sc_strerror(r)); if (card->ops->init != NULL) { r = card->ops->init(card); if (r) { sc_log(ctx, "driver '%s' init() failed: %s", card->driver->name, sc_strerror(r)); goto err; } } } else { sc_log(ctx, "matching built-in ATRs"); for (i = 0; ctx->card_drivers[i] != NULL; i++) { struct sc_card_driver *drv = ctx->card_drivers[i]; const struct sc_card_operations *ops = drv->ops; sc_log(ctx, "trying driver '%s'", drv->short_name); if (ops == NULL || ops->match_card == NULL) { continue; } else if (!(ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER) && !strcmp("default", drv->short_name)) { sc_log(ctx , "ignore 'default' card driver"); continue; } /* Needed if match_card() needs to talk with the card (e.g. card-muscle) */ *card->ops = *ops; if (ops->match_card(card) != 1) continue; sc_log(ctx, "matched: %s", drv->name); memcpy(card->ops, ops, sizeof(struct sc_card_operations)); card->driver = drv; r = ops->init(card); if (r) { sc_log(ctx, "driver '%s' init() failed: %s", drv->name, sc_strerror(r)); if (r == SC_ERROR_INVALID_CARD) { card->driver = NULL; continue; } goto err; } break; } } if (card->driver == NULL) { sc_log(ctx, "unable to find driver for inserted card"); r = SC_ERROR_INVALID_CARD; goto err; } if (card->name == NULL) card->name = card->driver->name; /* initialize max_send_size/max_recv_size to a meaningfull value */ card->max_recv_size = sc_get_max_recv_size(card); card->max_send_size = sc_get_max_send_size(card); sc_log(ctx, "card info name:'%s', type:%i, flags:0x%X, max_send/recv_size:%i/%i", card->name, card->type, card->flags, card->max_send_size, card->max_recv_size); #ifdef ENABLE_SM /* Check, if secure messaging module present. */ r = sc_card_sm_check(card); if (r) { sc_log(ctx, "cannot load secure messaging module"); goto err; } #endif *card_out = card; LOG_FUNC_RETURN(ctx, SC_SUCCESS); err: if (connected) reader->ops->disconnect(reader); if (card != NULL) sc_card_free(card); LOG_FUNC_RETURN(ctx, r); }
static int javacard_match_card(sc_card_t * card) { if (_sc_match_atr(card, javacard_atrs, &card->type) < 0) return 0; return 1; }
int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out) { sc_card_t *card; sc_context_t *ctx; struct sc_card_driver *driver; int i, r = 0, idx, connected = 0; if (card_out == NULL || reader == NULL) return SC_ERROR_INVALID_ARGUMENTS; ctx = reader->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (reader->ops->connect == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); card = sc_card_new(ctx); if (card == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); r = reader->ops->connect(reader); if (r) goto err; connected = 1; card->reader = reader; card->ctx = ctx; memcpy(&card->atr, &reader->atr, sizeof(card->atr)); _sc_parse_atr(reader); /* See if the ATR matches any ATR specified in the config file */ if ((driver = ctx->forced_driver) == NULL) { sc_debug(ctx, SC_LOG_DEBUG_MATCH, "matching configured ATRs"); for (i = 0; ctx->card_drivers[i] != NULL; i++) { driver = ctx->card_drivers[i]; if (driver->atr_map == NULL || !strcmp(driver->short_name, "default")) { driver = NULL; continue; } sc_debug(ctx, SC_LOG_DEBUG_MATCH, "trying driver: %s", driver->short_name); idx = _sc_match_atr(card, driver->atr_map, NULL); if (idx >= 0) { struct sc_atr_table *src = &driver->atr_map[idx]; sc_debug(ctx, SC_LOG_DEBUG_MATCH, "matched: %s", driver->name); /* It's up to card driver to notice these correctly */ card->name = src->name; card->type = src->type; card->flags = src->flags; 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); if (r) { sc_debug(ctx, SC_LOG_DEBUG_MATCH, "driver '%s' init() failed: %s", card->driver->name, sc_strerror(r)); goto err; } } } else { sc_debug(ctx, SC_LOG_DEBUG_MATCH, "matching built-in ATRs"); for (i = 0; ctx->card_drivers[i] != NULL; i++) { struct sc_card_driver *drv = ctx->card_drivers[i]; const struct sc_card_operations *ops = drv->ops; sc_debug(ctx, SC_LOG_DEBUG_MATCH, "trying driver: %s", drv->short_name); if (ops == NULL || ops->match_card == NULL) continue; /* Needed if match_card() needs to talk with the card (e.g. card-muscle) */ *card->ops = *ops; if (ops->match_card(card) != 1) continue; sc_debug(ctx, SC_LOG_DEBUG_MATCH, "matched: %s", drv->name); memcpy(card->ops, ops, sizeof(struct sc_card_operations)); card->driver = drv; r = ops->init(card); if (r) { sc_debug(ctx, SC_LOG_DEBUG_MATCH, "driver '%s' init() failed: %s", drv->name, sc_strerror(r)); if (r == SC_ERROR_INVALID_CARD) { card->driver = NULL; continue; } goto err; } break; } } if (card->driver == NULL) { sc_debug(ctx, SC_LOG_DEBUG_MATCH, "unable to find driver for inserted card"); r = SC_ERROR_INVALID_CARD; goto err; } if (card->name == NULL) card->name = card->driver->name; *card_out = card; /* Override card limitations with reader limitations. * Note that zero means no limitations at all. */ if ((card->max_recv_size == 0) || ((reader->driver->max_recv_size != 0) && (reader->driver->max_recv_size < card->max_recv_size))) { card->max_recv_size = reader->driver->max_recv_size; } if ((card->max_send_size == 0) || ((reader->driver->max_send_size != 0) && (reader->driver->max_send_size < card->max_send_size))) { card->max_send_size = reader->driver->max_send_size; } sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "card info name:'%s', type:%i, flags:0x%X, max_send/recv_size:%i/%i", card->name, card->type, card->flags, card->max_send_size, card->max_recv_size); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, 0); err: if (connected) reader->ops->disconnect(reader); if (card != NULL) sc_card_free(card); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
static int npa_match_card(sc_card_t * card) { if (_sc_match_atr(card, npa_atrs, &card->type) < 0) return 0; return 1; }