diff --git a/ccid/ccid.c b/ccid/ccid.c index 86f436e..4654736 100644 --- a/ccid/ccid.c +++ b/ccid/ccid.c @@ -29,7 +29,6 @@ #include "ccid.h" #include "pace.h" -//static const char *app_name = "ccid"; static sc_context_t *ctx = NULL; static sc_card_t *card_in_slot[SC_MAX_SLOTS]; static sc_reader_t *reader; @@ -118,7 +117,11 @@ int ccid_initialize(int reader_id, int verbose) { unsigned int i, reader_count; - SC_TEST_RET(ctx, sc_context_create(&ctx, NULL), "Failed to create initial context."); + int r = sc_context_create(&ctx, NULL); + if (r < 0) { + printf("Failed to create initial context: %s", sc_strerror(r)); + return r; + } ctx->debug = verbose; diff --git a/ccid/pace.c b/ccid/pace.c index d501842..2eb1d0e 100644 --- a/ccid/pace.c +++ b/ccid/pace.c @@ -201,24 +201,34 @@ static int get_ef_card_access(sc_card_t *card, { int r; sc_path_t path; - sc_file_t *file; + sc_file_t *file = NULL; __u8 *p; memset(&path, 0, sizeof path); - SC_TEST_RET(card->ctx, sc_append_file_id(&path, FID_EF_CARDACCESS), - "Could not create path object."); - SC_TEST_RET(card->ctx, sc_concatenate_path(&path, sc_get_mf_path(), &path), - "Could not create path object."); + r = sc_append_file_id(&path, FID_EF_CARDACCESS); + if (r < 0) { + sc_error(card->ctx, "Could not create path object."); + goto err; + } + r = sc_concatenate_path(&path, sc_get_mf_path(), &path); + if (r < 0) { + sc_error(card->ctx, "Could not create path object."); + goto err; + } + + r = sc_select_file(card, &path, &file); + if (r < 0) { + sc_error(card->ctx, "Could not select EF.CardAccess."); + goto err; + } - memset(&file, 0, sizeof file); - SC_TEST_RET(card->ctx, sc_select_file(card, &path, &file), - "Could not select EF.CardAccess."); *length_ef_cardaccess = 0; - while(1) { p = realloc(*ef_cardaccess, *length_ef_cardaccess + maxresp); - if (!p) - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY); + if (!p) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } *ef_cardaccess = p; r = sc_read_binary(card, *length_ef_cardaccess, @@ -229,17 +239,29 @@ static int get_ef_card_access(sc_card_t *card, break; } - SC_TEST_RET(card->ctx, r, "Could not read EF.CardAccess."); + if (r < 0) { + sc_error(card->ctx, "Could not read EF.CardAccess."); + goto err; + } *length_ef_cardaccess += r; } /* test cards only return an empty FCI template, * so we can't determine any file proberties */ - if (*length_ef_cardaccess < file->size) - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_FILE_TOO_SMALL); + if (*length_ef_cardaccess < file->size) { + r = SC_ERROR_FILE_TOO_SMALL; + goto err; + } - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS); + r = SC_SUCCESS; + +err: + if (file) { + free(file); + } + + SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r); } static int pace_mse_set_at(sc_card_t *card, @@ -324,6 +346,8 @@ static int pace_mse_set_at(sc_card_t *card, } err: + if (apdu.resp) + free(apdu.resp); if (data) { // XXX //if (data->cryptographic_mechanism_reference) @@ -336,8 +360,6 @@ err: } if (d) free(d); - if (apdu.resplen) - free(apdu.resp); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r); } @@ -523,9 +545,9 @@ err: ASN1_OCTET_STRING_free(r_data->auth_token);*/ PACE_GEN_AUTH_R_free(r_data); } - // XXX - //if (apdu.resplen) - //free(apdu.resp); + /* XXX */ + /*if (apdu.resp)*/ + /*free(apdu.resp);*/ SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r); } @@ -753,6 +775,8 @@ int EstablishPACEChannel(sc_card_t *card, const __u8 *in, r = reset_ssc(sctx); err: + if (ef_cardaccess) + free(ef_cardaccess); if (info) PACEInfo_free(info); if (static_dp) @@ -965,6 +989,8 @@ update_iv(struct sm_ctx *ctx) r = SC_SUCCESS; err: + if (ssc) + free(ssc); if (sscbuf) BUF_MEM_free(sscbuf); if (ivbuf) diff --git a/ccid/sm.c b/ccid/sm.c index 77ac46f..623f6b4 100644 --- a/ccid/sm.c +++ b/ccid/sm.c @@ -177,7 +177,7 @@ static int prefix_buf(u8 prefix, u8 *buf, size_t buflen, u8 **cat) return SC_ERROR_OUT_OF_MEMORY; if (*cat == buf) { - memmove(p + 1, buf, buflen); + memmove(p + 1, p, buflen); } else { memcpy(p + 1, buf, buflen); } @@ -420,7 +420,12 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card, r = sc_asn1_encode(card->ctx, sm_capdu, (u8 **) &sm_data, &sm_data_len); if (r < 0) goto err; - sm_apdu->data = sm_data; + if (sm_apdu->datalen < sm_data_len) { + sc_error(card->ctx, "Data for SM APDU too long"); + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + memcpy((u8 *) sm_apdu->data, sm_data, sm_data_len); sm_apdu->datalen = sm_data_len; sm_apdu->lc = sm_apdu->datalen; sm_apdu->le = 0; @@ -428,21 +433,18 @@ static int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card, bin_log(card->ctx, "ASN.1 encoded APDU data", sm_apdu->data, sm_apdu->datalen); err: - if (fdata) { + if (fdata) free(fdata); - } - if (asn1) { + if (asn1) free(asn1); - } - if (mac_data) { + if (mac_data) free(mac_data); - } - if (mac) { + if (mac) free(mac); - } - if (le) { + if (le) free(le); - } + if (sm_data) + free(sm_data); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r); } @@ -538,16 +540,17 @@ int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card, sc_apdu_t *apdu) { sc_apdu_t sm_apdu; - u8 buf[SC_MAX_APDU_BUFFER_SIZE - 2]; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE - 2], sbuf[SC_MAX_APDU_BUFFER_SIZE - 4]; + + sm_apdu.data = sbuf; + sm_apdu.datalen = sizeof sbuf; + sm_apdu.resp = rbuf; + sm_apdu.resplen = sizeof rbuf; SC_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, &sm_apdu), "Could not encrypt APDU."); - - sm_apdu.resplen = sizeof *buf; - sm_apdu.resp = buf; SC_TEST_RET(card->ctx, my_transmit_apdu(card, &sm_apdu), "Could not send SM APDU."); - SC_TEST_RET(card->ctx, sc_check_sw(card, sm_apdu.sw1, sm_apdu.sw2), "Card returned error."); SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu), diff --git a/ccid/usb.c b/ccid/usb.c index a8b079b..75a94af 100644 --- a/ccid/usb.c +++ b/ccid/usb.c @@ -1798,7 +1798,9 @@ main (int argc, char **argv) } if (dotest) { - return ccid_testpace(); + i = ccid_testpace(); + ccid_shutdown(); + return i; } fd = init_device ();