int sc_release_context(sc_context_t *ctx) { unsigned int i; if (ctx == NULL) { return SC_ERROR_INVALID_ARGUMENTS; } SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); while (list_size(&ctx->readers)) { sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0); _sc_delete_reader(ctx, rdr); } if (ctx->reader_driver->ops->finish != NULL) ctx->reader_driver->ops->finish(ctx); for (i = 0; ctx->card_drivers[i]; i++) { struct sc_card_driver *drv = ctx->card_drivers[i]; if (drv->atr_map) _sc_free_atr(ctx, drv); if (drv->dll) sc_dlclose(drv->dll); } if (ctx->preferred_language != NULL) free(ctx->preferred_language); if (ctx->mutex != NULL) { int r = sc_mutex_destroy(ctx, ctx->mutex); if (r != SC_SUCCESS) { sc_log(ctx, "unable to destroy mutex"); return r; } } if (ctx->conf != NULL) scconf_free(ctx->conf); if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr)) fclose(ctx->debug_file); if (ctx->debug_filename != NULL) free(ctx->debug_filename); if (ctx->app_name != NULL) free(ctx->app_name); list_destroy(&ctx->readers); sc_mem_clear(ctx, sizeof(*ctx)); free(ctx); return SC_SUCCESS; }
static void sc_card_free(sc_card_t *card) { sc_free_apps(card); sc_free_ef_atr(card); if (card->ef_dir != NULL) sc_file_free(card->ef_dir); free(card->ops); if (card->algorithms != NULL) free(card->algorithms); if (card->mutex != NULL) { int r = sc_mutex_destroy(card->ctx, card->mutex); if (r != SC_SUCCESS) sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "unable to destroy mutex"); } sc_mem_clear(card, sizeof(*card)); free(card); }
static void sc_card_free(sc_card_t *card) { sc_free_apps(card); sc_free_ef_atr(card); if (card->ef_dir != NULL) sc_file_free(card->ef_dir); free(card->ops); if (card->algorithms != NULL) { int i; for (i=0; i<card->algorithm_count; i++) { struct sc_algorithm_info *info = (card->algorithms + i); if (info->algorithm == SC_ALGORITHM_EC) { struct sc_ec_parameters ep = info->u._ec.params; free(ep.named_curve); free(ep.der.value); } } free(card->algorithms); card->algorithms = NULL; card->algorithm_count = 0; } if (card->cache.current_ef) sc_file_free(card->cache.current_ef); if (card->cache.current_df) sc_file_free(card->cache.current_df); if (card->mutex != NULL) { int r = sc_mutex_destroy(card->ctx, card->mutex); if (r != SC_SUCCESS) sc_log(card->ctx, "unable to destroy mutex"); } sc_mem_clear(card, sizeof(*card)); free(card); }
int ctbcs_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data) { sc_card_t dummy_card, *card; sc_apdu_t apdu; struct sc_card_operations ops; int r, s; switch (data->cmd) { case SC_PIN_CMD_VERIFY: r = ctbcs_build_perform_verification_apdu(&apdu, data); if (r != SC_SUCCESS) return r; break; case SC_PIN_CMD_CHANGE: case SC_PIN_CMD_UNBLOCK: r = ctbcs_build_modify_verification_apdu(&apdu, data); if (r != SC_SUCCESS) return r; break; default: sc_log(reader->ctx, "Unknown PIN command %d", data->cmd); return SC_ERROR_NOT_SUPPORTED; } memset(&ops, 0, sizeof(ops)); memset(&dummy_card, 0, sizeof(dummy_card)); dummy_card.reader = reader; dummy_card.ctx = reader->ctx; r = sc_mutex_create(reader->ctx, &dummy_card.mutex); if (r != SC_SUCCESS) return r; dummy_card.ops = &ops; card = &dummy_card; r = sc_transmit_apdu(card, &apdu); s = sc_mutex_destroy(reader->ctx, card->mutex); if (s != SC_SUCCESS) { sc_log(reader->ctx, "unable to destroy mutex\n"); return s; } LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); /* Check CTBCS status word */ switch (((unsigned int) apdu.sw1 << 8) | apdu.sw2) { case 0x9000: r = 0; break; case 0x6400: /* Input timed out */ r = SC_ERROR_KEYPAD_TIMEOUT; break; case 0x6401: /* Input cancelled */ r = SC_ERROR_KEYPAD_CANCELLED; break; case 0x6402: /* PINs did not match */ r = SC_ERROR_KEYPAD_PIN_MISMATCH; break; case 0x6700: /* message too long */ r = SC_ERROR_KEYPAD_MSG_TOO_LONG; break; default: r = SC_ERROR_CARD_CMD_FAILED; break; } LOG_TEST_RET(card->ctx, r, "PIN command failed"); /* Calling Function may expect SW1/SW2 in data-apdu set... */ if (data->apdu) { data->apdu->sw1 = apdu.sw1; data->apdu->sw2 = apdu.sw2; } return 0; }