fetch CAR for TA from MSE:Set AT

This commit is contained in:
Frank Morgner
2012-09-18 01:06:28 +02:00
parent 70a108dfe3
commit 00f262ad68

View File

@@ -1255,15 +1255,6 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "ID PCD", pace_output->id_pcd,
pace_output->id_pcd_length);
if(pace_output->recent_car && pace_output->recent_car_length
&& !EAC_CTX_init_ta(eac_ctx, NULL, 0, NULL, 0,
pace_output->recent_car, pace_output->recent_car_length)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize TA.\n");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
sctx->priv_data = npa_sm_ctx_create(eac_ctx,
pace_input.certificate_description,
pace_input.certificate_description_length,
@@ -1680,10 +1671,8 @@ npa_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
goto err;
}
} else if (apdu->ins == 0x22 && apdu->p1 == 0x81 && apdu->p2 == 0xa4) {
/* MSE:Set AT
* fetch auxiliary data and terminal's compressed ephemeral public key
* for CA */
} else if (apdu->ins == 0x22 && apdu->p2 == 0xa4) {
/* MSE:Set AT */
len = add_tag(&sequence, 1, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, apdu->data, apdu->datalen);
p = sequence;
@@ -1693,55 +1682,74 @@ npa_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
r = SC_ERROR_INTERNAL;
goto err;
}
if (msesetat->auxiliary_data) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Saving terminal's auxiliary data");
if (eacsmctx->auxiliary_data)
BUF_MEM_free(eacsmctx->auxiliary_data);
eacsmctx->auxiliary_data = BUF_MEM_new();
if (!eacsmctx->auxiliary_data) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
/* Note that we can not define CVC_DISCRETIONARY_DATA_TEMPLATES as
* item template with the correct tag. Due to limitations of
* OpenSSL it is not possible to *encode* an optional item template
* (such as APDU_DISCRETIONARY_DATA_TEMPLATES) in an other item
* template (such as NPA_MSE_SET_AT_C). So what we have to do here
* is manually adding the correct tag to the saved
* CVC_DISCRETIONARY_DATA_TEMPLATES.
* See also openssl/crypto/asn1/tasn_dec.c:183
*/
len = i2d_CVC_DISCRETIONARY_DATA_TEMPLATES(msesetat->auxiliary_data, &templates);
p = templates;
if (len < 0 ||
(0x80 & ASN1_get_object(&p, &llen, &tag, &class, len))) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding auxiliary data.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
eacsmctx->auxiliary_data->length = add_tag(
(unsigned char **) &eacsmctx->auxiliary_data->data, 1,
7, V_ASN1_APPLICATION, p, llen);
if ((int) eacsmctx->auxiliary_data->length < 0) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
eacsmctx->auxiliary_data->max = eacsmctx->auxiliary_data->length;
}
if (msesetat->eph_pub_key) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Saving terminal's compressed ephemeral public key");
if (eacsmctx->eph_pub_key)
BUF_MEM_free(eacsmctx->eph_pub_key);
eacsmctx->eph_pub_key =
BUF_MEM_create_init(msesetat->eph_pub_key->data,
msesetat->eph_pub_key->length);
if (!eacsmctx->eph_pub_key) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
}
if (apdu->p1 == 0x81) {
/* CA: fetch auxiliary data and terminal's compressed ephemeral
* public key */
if (msesetat->auxiliary_data) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Saving terminal's auxiliary data");
if (eacsmctx->auxiliary_data)
BUF_MEM_free(eacsmctx->auxiliary_data);
eacsmctx->auxiliary_data = BUF_MEM_new();
if (!eacsmctx->auxiliary_data) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
/* Note that we can not define CVC_DISCRETIONARY_DATA_TEMPLATES as
* item template with the correct tag. Due to limitations of
* OpenSSL it is not possible to *encode* an optional item template
* (such as APDU_DISCRETIONARY_DATA_TEMPLATES) in an other item
* template (such as NPA_MSE_SET_AT_C). So what we have to do here
* is manually adding the correct tag to the saved
* CVC_DISCRETIONARY_DATA_TEMPLATES.
* See also openssl/crypto/asn1/tasn_dec.c:183
*/
len = i2d_CVC_DISCRETIONARY_DATA_TEMPLATES(msesetat->auxiliary_data, &templates);
p = templates;
if (len < 0 ||
(0x80 & ASN1_get_object(&p, &llen, &tag, &class, len))) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding auxiliary data.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
eacsmctx->auxiliary_data->length = add_tag(
(unsigned char **) &eacsmctx->auxiliary_data->data, 1,
7, V_ASN1_APPLICATION, p, llen);
if ((int) eacsmctx->auxiliary_data->length < 0) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
eacsmctx->auxiliary_data->max = eacsmctx->auxiliary_data->length;
}
if (msesetat->eph_pub_key) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Saving terminal's compressed ephemeral public key");
if (eacsmctx->eph_pub_key)
BUF_MEM_free(eacsmctx->eph_pub_key);
eacsmctx->eph_pub_key =
BUF_MEM_create_init(msesetat->eph_pub_key->data,
msesetat->eph_pub_key->length);
if (!eacsmctx->eph_pub_key) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
}
} else if (apdu->p1 == 0x41) {
/* TA: Set CAR */
if (msesetat->key_reference1 && msesetat->key_reference1->data &&
msesetat->key_reference1->length) {
if (!EAC_CTX_init_ta(eacsmctx->ctx, NULL, 0, NULL, 0,
msesetat->key_reference1->data,
msesetat->key_reference1->length)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize TA.\n");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
}
}
} else if (apdu->ins == 0x82 && apdu->p1 == 0x00 && apdu->p2 == 0x00) {
/* External Authenticate
* check terminal's signature */