int sc_sm_single_transmit(struct sc_card *card, struct sc_apdu *apdu) { struct sc_context *ctx = card->ctx; struct sc_apdu *sm_apdu = NULL; int rv; LOG_FUNC_CALLED(ctx); sc_log(ctx, "SM_MODE:%X", card->sm_ctx.sm_mode); if (!card->sm_ctx.ops.get_sm_apdu || !card->sm_ctx.ops.free_sm_apdu) LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); /* get SM encoded APDU */ rv = card->sm_ctx.ops.get_sm_apdu(card, apdu, &sm_apdu); if (rv == SC_ERROR_SM_NOT_APPLIED) { /* SM wrap of this APDU is ignored by card driver. * Send plain APDU to the reader driver */ rv = card->reader->ops->transmit(card->reader, apdu); LOG_FUNC_RETURN(ctx, rv); } else { if (rv < 0) sc_sm_stop(card); } LOG_TEST_RET(ctx, rv, "get SM APDU error"); /* check if SM APDU is still valid */ rv = sc_check_apdu(card, sm_apdu); if (rv < 0) { card->sm_ctx.ops.free_sm_apdu(card, apdu, &sm_apdu); sc_sm_stop(card); LOG_TEST_RET(ctx, rv, "cannot validate SM encoded APDU"); } /* send APDU flagged as NO_SM */ sm_apdu->flags |= SC_APDU_FLAGS_NO_SM | SC_APDU_FLAGS_NO_RETRY_WL; rv = sc_transmit_apdu(card, sm_apdu); if (rv < 0) { card->sm_ctx.ops.free_sm_apdu(card, apdu, &sm_apdu); sc_sm_stop(card); LOG_TEST_RET(ctx, rv, "unable to transmit APDU"); } /* decode SM answer and free temporary SM related data */ rv = card->sm_ctx.ops.free_sm_apdu(card, apdu, &sm_apdu); if (rv < 0) sc_sm_stop(card); LOG_FUNC_RETURN(ctx, rv); }
static int npa_finish(sc_card_t * card) { sc_sm_stop(card); npa_drv_data_free(card->drv_data); card->drv_data = NULL; return SC_SUCCESS; }
static int npa_finish(sc_card_t * card) { sc_sm_stop(card); npa_drv_data_free(card->drv_data); card->drv_data = NULL; #ifdef ENABLE_OPENPACE EAC_cleanup(); #endif return SC_SUCCESS; }
static int npa_logout(sc_card_t *card) { struct sc_apdu apdu; sc_sm_stop(card); if (card->reader->capabilities & SC_READER_CAP_PACE_GENERIC) { /* If PACE is done between reader and card, SM is transparent to us as * it ends at the reader. With CLA=0x0C we provoque a SM error to * disable SM on the reader. */ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xA4, 0x00, 0x00); apdu.cla = 0x0C; sc_transmit_apdu(card, &apdu); /* ignore result */ } return sc_select_file(card, sc_get_mf_path(), NULL); }