diff --git a/ccid/src/pace-tool.c b/ccid/src/pace-tool.c index e291903..822142e 100644 --- a/ccid/src/pace-tool.c +++ b/ccid/src/pace-tool.c @@ -166,7 +166,7 @@ int pace_translate_apdus(struct sm_ctx *sctx, sc_card_t *card) apdu.resp = buf; apdu.resplen = sizeof(buf); - r = pace_transmit_apdu(sctx, card, &apdu); + r = sm_transmit_apdu(sctx, card, &apdu); if (r < 0) { sc_error(card->ctx, "Could not send APDU: %s", sc_strerror(r)); continue; @@ -307,18 +307,13 @@ main (int argc, char **argv) printf("Established PACE channel with CAN in %.0fs.\n", difftime(t_end, t_start)); - /*i = pace_reset_retry_counter(&tmpctx, card, PACE_PIN, 0, NULL, 0);*/ - /*if (i < 0)*/ - /*goto err;*/ - /*printf("Resumed PIN.\n");*/ - i = pace_get_channel(&tmpctx, card, PACE_PIN, pin, pin ? strlen(pin) : 0, &channeldata, &channeldatalen, &sctx); if (i < 0) goto err; t_start = time(NULL); - printf("Established PACE channel with PIN in %.0fs.\n", + printf("Established PACE channel with PIN in %.0fs. PIN resumed.\n", difftime(t_start, t_end)); } diff --git a/ccid/src/pace.c b/ccid/src/pace.c index a6ce778..3e7ae06 100644 --- a/ccid/src/pace.c +++ b/ccid/src/pace.c @@ -295,7 +295,7 @@ static int pace_mse_set_at(const struct sm_ctx *oldpacectx, sc_card_t *card, bin_log(card->ctx, "MSE:Set AT command data", apdu.data, apdu.datalen); if (oldpacectx) - r = pace_transmit_apdu(oldpacectx, card, &apdu); + r = sm_transmit_apdu(oldpacectx, card, &apdu); else r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -423,7 +423,7 @@ static int pace_gen_auth(const struct sm_ctx *oldpacectx, sc_card_t *card, apdu.resplen = maxresp; apdu.resp = malloc(apdu.resplen); if (oldpacectx) - r = pace_transmit_apdu(oldpacectx, card, &apdu); + r = sm_transmit_apdu(oldpacectx, card, &apdu); else r = sc_transmit_apdu(card, &apdu); if (r < 0) @@ -586,7 +586,7 @@ pace_reset_retry_counter(struct sm_ctx *ctx, sc_card_t *card, apdu.cse = SC_APDU_CASE_1; } - r = pace_transmit_apdu(ctx, card, &apdu); + r = sm_transmit_apdu(ctx, card, &apdu); if (p) { OPENSSL_cleanse(p, new_len); @@ -788,7 +788,7 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, } pub_opp->max = pub_opp->length; if (card->ctx->debug >= SC_LOG_TYPE_DEBUG) - bin_log(card->ctx, "Public key from MRTD", (u8 *) pub_opp->data, pub_opp->length); + bin_log(card->ctx, "Ephemeral public key from MRTD", (u8 *) pub_opp->data, pub_opp->length); key = PACE_STEP3B_compute_ephemeral_key(eph_dp, pctx, pub_opp); if (!key || @@ -834,6 +834,8 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, sctx->encrypt = pace_sm_encrypt; sctx->decrypt = pace_sm_decrypt; sctx->verify_authentication = pace_sm_verify_authentication; + sctx->pre_transmit = pace_sm_pre_transmit; + sctx->post_transmit = pace_sm_post_transmit; sctx->padding_indicator = SM_ISO_PADDING; sctx->block_length = EVP_CIPHER_block_size(pctx->cipher); @@ -1078,14 +1080,10 @@ int pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx, if (!ctx || !ctx->cipher_ctx) { r = SC_ERROR_INVALID_ARGUMENTS; - goto incerr; + goto err; } struct pace_sm_ctx *psmctx = ctx->cipher_ctx; - r = increment_ssc(psmctx); - if (r < 0) - goto incerr; - my_mac = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac, macdata, macdatalen); if (!my_mac) { @@ -1103,55 +1101,25 @@ int pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx, if (card->ctx->debug > SC_LOG_TYPE_DEBUG) sc_debug(card->ctx, "Authentication data verified"); + r = SC_SUCCESS; + err: if (my_mac) BUF_MEM_free(my_mac); - if (r >= 0) - decrement_ssc(psmctx); - else - r = decrement_ssc(psmctx); -incerr: SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r); } -int pace_transmit_apdu(const struct sm_ctx *ctx, sc_card_t *card, +int pace_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx, sc_apdu_t *apdu) { - int r; - - if ((apdu->cla & 0x0C) == 0x0C) { - sc_debug(card->ctx, "Given APDU is already protected with some secure messaging."); - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, sc_transmit_apdu(card, apdu)); - } - - if (!ctx || !ctx->cipher_ctx) { - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS); - } - - /* SW1 and SW2 are used to determine if really something has been sent and - * received. Only if this is the case, the send sequence counter needs to - * be incremented. */ - - apdu->sw1 = 0; - apdu->sw2 = 0; - - SC_TEST_RET(card->ctx, increment_ssc(ctx->cipher_ctx), - "Could not increment send sequence counter"); - - r = sm_transmit_apdu(ctx, card, apdu); - - if (apdu->sw1 || apdu->sw2) { - if (r < 0) { - if (increment_ssc(ctx->cipher_ctx) < 0) - sc_error(card->ctx, - "Could not increment send sequence counter"); - } else - r = increment_ssc(ctx->cipher_ctx); - } else - if (decrement_ssc(ctx->cipher_ctx) < 0) - sc_error(card->ctx, - "Could not decrement send sequence counter"); - - SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r); + SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, + increment_ssc(ctx->cipher_ctx)); +} + +int pace_sm_post_transmit(sc_card_t *card, const struct sm_ctx *ctx, + sc_apdu_t *sm_apdu) +{ + SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, + increment_ssc(ctx->cipher_ctx)); } diff --git a/ccid/src/pace.h b/ccid/src/pace.h index d10cff1..58dd456 100644 --- a/ccid/src/pace.h +++ b/ccid/src/pace.h @@ -58,14 +58,16 @@ int pace_sm_authenticate(sc_card_t *card, const struct sm_ctx *ctx, int pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx, const u8 *mac, size_t maclen, const u8 *macdata, size_t macdatalen); +int pace_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx, + sc_apdu_t *apdu); +int pace_sm_post_transmit(sc_card_t *card, const struct sm_ctx *ctx, + sc_apdu_t *sm_apdu); int GetReadersPACECapabilities(sc_card_t *card, const unsigned char *in, unsigned char **out, size_t *outlen); int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card, const unsigned char *in, unsigned char **out, size_t *outlen, struct sm_ctx *sctx); -int pace_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card, - sc_apdu_t *apdu); int pace_reset_retry_counter(struct sm_ctx *ctx, sc_card_t *card, enum s_type pin_id, int ask_for_secret, const char *new, size_t new_len); diff --git a/ccid/src/sm.c b/ccid/src/sm.c index 1436831..6c9e33a 100644 --- a/ccid/src/sm.c +++ b/ccid/src/sm.c @@ -578,10 +578,21 @@ int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card, sm_apdu.resp = rbuf; sm_apdu.resplen = sizeof rbuf; + if ((apdu->cla & 0x0C) == 0x0C) { + sc_debug(card->ctx, "Given APDU is already protected with some secure messaging."); + SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, sc_transmit_apdu(card, apdu)); + } + + if (sctx->pre_transmit) + SC_TEST_RET(card->ctx, sctx->pre_transmit(card, sctx, apdu), + "Could not complete SM specific pre transmit routine"); SC_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, &sm_apdu), "Could not encrypt APDU"); SC_TEST_RET(card->ctx, sc_transmit_apdu(card, &sm_apdu), "Could not transmit SM APDU"); + if (sctx->post_transmit) + SC_TEST_RET(card->ctx, sctx->post_transmit(card, sctx, &sm_apdu), + "Could not complete SM specific post transmit routine"); SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu), "Could not decrypt APDU"); diff --git a/ccid/src/sm.h b/ccid/src/sm.h index 7c6d21a..85c78b1 100644 --- a/ccid/src/sm.h +++ b/ccid/src/sm.h @@ -44,6 +44,11 @@ struct sm_ctx { const u8 *data, size_t datalen, u8 **enc); int (*decrypt)(sc_card_t *card, const struct sm_ctx *ctx, const u8 *enc, size_t enclen, u8 **data); + + int (*pre_transmit)(sc_card_t *card, const struct sm_ctx *ctx, + sc_apdu_t *apdu); + int (*post_transmit)(sc_card_t *card, const struct sm_ctx *ctx, + sc_apdu_t *sm_apdu); }; int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card,