diff --git a/ccid/src/ccid.c b/ccid/src/ccid.c index aabea26..62db4e4 100644 --- a/ccid/src/ccid.c +++ b/ccid/src/ccid.c @@ -156,11 +156,11 @@ detect_card_presence(void) } -int ccid_initialize(int reader_id, const char *cdriver, int verbose) +int ccid_initialize(int reader_id, int verbose) { int i; - i = initialize(reader_id, cdriver, verbose, &ctx, &reader); + i = initialize(reader_id, verbose, &ctx, &reader); if (i < 0) return i; diff --git a/ccid/src/ccid.h b/ccid/src/ccid.h index 98795c2..3c72766 100644 --- a/ccid/src/ccid.h +++ b/ccid/src/ccid.h @@ -271,12 +271,11 @@ struct hid_class_descriptor { * @brief Initializes reader for relaying * * @param[in] reader_id (optional) Index to the reader to be used. Set to -1 to use the first reader with a card or the first reader if no card is available. - * @param[in] cdriver (optional) Card driver to be used * @param[in] verbose Verbosity level passed to \c sc_context_t * * @return \c SC_SUCCESS or error code if an error occurred */ -int ccid_initialize(int reader_id, const char *cdriver, int verbose); +int ccid_initialize(int reader_id, int verbose); /** * @brief Disconnects from card, reader and releases allocated memory diff --git a/ccid/src/usb.c b/ccid/src/usb.c index 552151d..c1687b2 100644 --- a/ccid/src/usb.c +++ b/ccid/src/usb.c @@ -1531,7 +1531,7 @@ main (int argc, char **argv) if (cmdline.info_flag) return print_avail(verbose); - if (ccid_initialize(cmdline.reader_arg, NULL, verbose) < 0) { + if (ccid_initialize(cmdline.reader_arg, verbose) < 0) { fprintf (stderr, "Can't initialize ccid\n"); return 1; } diff --git a/npa/src/example.c b/npa/src/example.c index 44ccca0..9d23506 100644 --- a/npa/src/example.c +++ b/npa/src/example.c @@ -59,7 +59,7 @@ main (int argc, char **argv) /* Connect to a reader and the nPA */ - r = initialize(reader_num, NULL, 0, &ctx, &reader); + r = initialize(reader_num, 0, &ctx, &reader); if (r < 0) { fprintf(stderr, "Can't initialize reader\n"); exit(1); diff --git a/npa/src/npa-tool.c b/npa/src/npa-tool.c index 3bec66e..15ffb5e 100644 --- a/npa/src/npa-tool.c +++ b/npa/src/npa-tool.c @@ -365,7 +365,7 @@ main (int argc, char **argv) return print_avail(cmdline.verbose_given); - r = initialize(cmdline.reader_arg, NULL, cmdline.verbose_given, &ctx, &reader); + r = initialize(cmdline.reader_arg, cmdline.verbose_given, &ctx, &reader); if (r < 0) { fprintf(stderr, "Can't initialize reader\n"); exit(1); diff --git a/npa/src/npa.c b/npa/src/npa.c index 54e4764..e6ac61b 100644 --- a/npa/src/npa.c +++ b/npa/src/npa.c @@ -379,140 +379,6 @@ int get_pace_capabilities(u8 *bitmap) return SC_SUCCESS; } - -#define ISO_READ_BINARY 0xB0 -#define ISO_P1_FLAG_SFID 0x80 -int read_binary_rec(sc_card_t *card, unsigned char sfid, - u8 **ef, size_t *ef_len) -{ - int r; - /* we read less bytes than possible. this is a workaround for acr 122, - * which only supports apdus of max 250 bytes */ - size_t read = maxresp - 8; - sc_apdu_t apdu; - u8 *p; - - if (!card || !ef || !ef_len) { - r = SC_ERROR_INVALID_ARGUMENTS; - goto err; - } - *ef_len = 0; - - if (read > 0xff+1) - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, - ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0); - else - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, - ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0); - - p = realloc(*ef, read); - if (!p) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - *ef = p; - apdu.resp = *ef; - apdu.resplen = read; - apdu.le = read; - - r = sc_transmit_apdu(card, &apdu); - /* emulate the behaviour of sc_read_binary */ - if (r >= 0) - r = apdu.resplen; - - while(1) { - if (r >= 0 && r != read) { - *ef_len += r; - break; - } - if (r < 0) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read EF."); - goto err; - } - *ef_len += r; - - p = realloc(*ef, *ef_len + read); - if (!p) { - r = SC_ERROR_OUT_OF_MEMORY; - goto err; - } - *ef = p; - - r = sc_read_binary(card, *ef_len, - *ef + *ef_len, read, 0); - } - - r = SC_SUCCESS; - -err: - return r; -} - -#define ISO_WRITE_BINARY 0xD0 -int write_binary_rec(sc_card_t *card, unsigned char sfid, - u8 *ef, size_t ef_len) -{ - int r; - /* we write less bytes than possible. this is a workaround for acr 122, - * which only supports apdus of max 250 bytes */ - size_t write = maxresp - 8, wrote = 0; - sc_apdu_t apdu; - struct iso_sm_ctx *iso_sm_ctx = card->sm_ctx.info.cmd_data; - - if (!card) { - r = SC_ERROR_INVALID_ARGUMENTS; - goto err; - } - - if (write > SC_MAX_APDU_BUFFER_SIZE-2 - || (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT - && write > (((SC_MAX_APDU_BUFFER_SIZE-2 - /* for encrypted APDUs we usually get authenticated status - * bytes (4B), a MAC (11B) and a cryptogram with padding - * indicator (3B without data). The cryptogram is always - * padded to the block size. */ - -18) / iso_sm_ctx->block_length) - * iso_sm_ctx->block_length - 1))) - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, - ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); - else - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, - ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); - - if (write > ef_len) { - apdu.datalen = ef_len; - apdu.lc = ef_len; - } else { - apdu.datalen = write; - apdu.lc = write; - } - apdu.data = ef; - - - r = sc_transmit_apdu(card, &apdu); - /* emulate the behaviour of sc_write_binary */ - if (r >= 0) - r = apdu.datalen; - - while (1) { - if (r < 0 || r > ef_len) { - sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not write EF."); - goto err; - } - wrote += r; - apdu.data += r; - if (wrote >= ef_len) - break; - - r = sc_write_binary(card, wrote, ef, write, 0); - } - - r = SC_SUCCESS; - -err: - return r; -} - static int get_ef_card_access(sc_card_t *card, u8 **ef_cardaccess, size_t *length_ef_cardaccess) { diff --git a/npa/src/npa/scutil.h b/npa/src/npa/scutil.h index 40539e3..79131a7 100644 --- a/npa/src/npa/scutil.h +++ b/npa/src/npa/scutil.h @@ -29,15 +29,14 @@ /** * @brief Initializes smart card context and reader * - * @param[in] reader_id Index to the reader to be used (optional). Set to -1 to use a reader with a inserted card. - * @param[in] cdriver Card driver to be used (optional) + * @param[in] reader_id Index to the reader to be used. Set to -1 to use a reader with an inserted card. * @param[in] verbose verbosity level passed to \c sc_context_t * @param[in,out] ctx Where to write the sc context * @param[in,out] reader Where to write the reader context * * @return */ -int initialize(int reader_id, const char *cdriver, int verbose, +int initialize(int reader_id, int verbose, sc_context_t **ctx, sc_reader_t **reader); /** diff --git a/npa/src/scutil.c b/npa/src/scutil.c index 04a4014..9cd6b60 100644 --- a/npa/src/scutil.c +++ b/npa/src/scutil.c @@ -21,11 +21,13 @@ #endif #include +#include #include #include +#include #include -int initialize(int reader_id, const char *cdriver, int verbose, +int initialize(int reader_id, int verbose, sc_context_t **ctx, sc_reader_t **reader) { unsigned int i, reader_count; @@ -34,19 +36,11 @@ int initialize(int reader_id, const char *cdriver, int verbose, return SC_ERROR_INVALID_ARGUMENTS; int r = sc_establish_context(ctx, ""); - if (r < 0) { + if (r < 0 || !*ctx) { fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r)); return r; } - if (cdriver != NULL) { - r = sc_set_card_driver(*ctx, cdriver); - if (r < 0) { - sc_debug(*ctx, SC_LOG_DEBUG_VERBOSE, "Card driver '%s' not found.\n", cdriver); - return r; - } - } - (*ctx)->debug = verbose; reader_count = sc_ctx_get_reader_count(*ctx); @@ -103,23 +97,6 @@ void _bin_log(sc_context_t *ctx, int type, const char *file, int line, } } -static int list_drivers(sc_context_t *ctx) -{ - int i; - - if (ctx->card_drivers[0] == NULL) { - printf("No card drivers installed!\n"); - return 0; - } - printf("Configured card drivers:\n"); - for (i = 0; ctx->card_drivers[i] != NULL; i++) { - printf(" %-16s %s\n", ctx->card_drivers[i]->short_name, - ctx->card_drivers[i]->name); - } - - return 0; -} - static int list_readers(sc_context_t *ctx) { unsigned int i, rcount = sc_ctx_get_reader_count(ctx); @@ -151,10 +128,144 @@ int print_avail(int verbose) } ctx->debug = verbose; - r = list_readers(ctx)|list_drivers(ctx); + r = list_readers(ctx); if (ctx) sc_release_context(ctx); return r; } + +#define maxresp SC_MAX_APDU_BUFFER_SIZE - 2 +#define ISO_READ_BINARY 0xB0 +#define ISO_P1_FLAG_SFID 0x80 +int read_binary_rec(sc_card_t *card, unsigned char sfid, + u8 **ef, size_t *ef_len) +{ + int r; + /* we read less bytes than possible. this is a workaround for acr 122, + * which only supports apdus of max 250 bytes */ + size_t read = maxresp - 8; + sc_apdu_t apdu; + u8 *p; + + if (!card || !ef || !ef_len) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; + } + *ef_len = 0; + + if (read > 0xff+1) + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, + ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0); + else + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, + ISO_READ_BINARY, ISO_P1_FLAG_SFID|sfid, 0); + + p = realloc(*ef, read); + if (!p) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + *ef = p; + apdu.resp = *ef; + apdu.resplen = read; + apdu.le = read; + + r = sc_transmit_apdu(card, &apdu); + /* emulate the behaviour of sc_read_binary */ + if (r >= 0) + r = apdu.resplen; + + while(1) { + if (r >= 0 && r != read) { + *ef_len += r; + break; + } + if (r < 0) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read EF."); + goto err; + } + *ef_len += r; + + p = realloc(*ef, *ef_len + read); + if (!p) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + *ef = p; + + r = sc_read_binary(card, *ef_len, + *ef + *ef_len, read, 0); + } + + r = SC_SUCCESS; + +err: + return r; +} + +#define ISO_WRITE_BINARY 0xD0 +int write_binary_rec(sc_card_t *card, unsigned char sfid, + u8 *ef, size_t ef_len) +{ + int r; + /* we write less bytes than possible. this is a workaround for acr 122, + * which only supports apdus of max 250 bytes */ + size_t write = maxresp - 8, wrote = 0; + sc_apdu_t apdu; + struct iso_sm_ctx *iso_sm_ctx = card->sm_ctx.info.cmd_data; + + if (!card) { + r = SC_ERROR_INVALID_ARGUMENTS; + goto err; + } + + if (write > SC_MAX_APDU_BUFFER_SIZE-2 + || (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT + && write > (((SC_MAX_APDU_BUFFER_SIZE-2 + /* for encrypted APDUs we usually get authenticated status + * bytes (4B), a MAC (11B) and a cryptogram with padding + * indicator (3B without data). The cryptogram is always + * padded to the block size. */ + -18) / iso_sm_ctx->block_length) + * iso_sm_ctx->block_length - 1))) + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, + ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); + else + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, + ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0); + + if (write > ef_len) { + apdu.datalen = ef_len; + apdu.lc = ef_len; + } else { + apdu.datalen = write; + apdu.lc = write; + } + apdu.data = ef; + + + r = sc_transmit_apdu(card, &apdu); + /* emulate the behaviour of sc_write_binary */ + if (r >= 0) + r = apdu.datalen; + + while (1) { + if (r < 0 || r > ef_len) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not write EF."); + goto err; + } + wrote += r; + apdu.data += r; + if (wrote >= ef_len) + break; + + r = sc_write_binary(card, wrote, ef, write, 0); + } + + r = SC_SUCCESS; + +err: + return r; +}