- dropped pace_transmit_apdu in favour of a solution with sm_transmit_apdu.
post_transmit and pre_transmit can be used to perform actions before encrypting/decrypting a sm apdu (such as incrementing the ssc for pace). - fixed ssc problems. encrypted communication with more than one apdu (e.g. resuming the pin) is now working. - fixed uninitialized pointer in sm_decrypt git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@131 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user