libnpa: Implementation of TA

This commit is contained in:
Frank Morgner
2012-09-18 02:54:19 +02:00
parent 66ffb3675d
commit 7145984d5f

View File

@@ -38,41 +38,42 @@
#define ASN1_APP_IMP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type) #define ASN1_APP_IMP_OPT(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION|ASN1_TFLG_OPTIONAL, tag, stname, field, type)
#define ASN1_APP_IMP(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, tag, stname, field, type) #define ASN1_APP_IMP(stname, field, type, tag) ASN1_EX_TYPE(ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, tag, stname, field, type)
IMPLEMENT_ASN1_FUNCTIONS(CVC_DISCRETIONARY_DATA_TEMPLATES)
/* /*
* MSE:Set AT * MSE:Set AT
*/ */
typedef struct npa_mse_set_at_cd_st { typedef struct npa_mse_cd_st {
ASN1_OBJECT *cryptographic_mechanism_reference; ASN1_OBJECT *cryptographic_mechanism_reference;
ASN1_OCTET_STRING *key_reference1; ASN1_OCTET_STRING *key_reference1;
ASN1_OCTET_STRING *key_reference2; ASN1_OCTET_STRING *key_reference2;
ASN1_OCTET_STRING *eph_pub_key; ASN1_OCTET_STRING *eph_pub_key;
CVC_DISCRETIONARY_DATA_TEMPLATES *auxiliary_data; CVC_DISCRETIONARY_DATA_TEMPLATES *auxiliary_data;
CVC_CHAT *chat; CVC_CHAT *chat;
} NPA_MSE_SET_AT_C; } NPA_MSE_C;
ASN1_SEQUENCE(NPA_MSE_SET_AT_C) = { ASN1_SEQUENCE(NPA_MSE_C) = {
/* 0x80 /* 0x80
* Cryptographic mechanism reference */ * Cryptographic mechanism reference */
ASN1_IMP_OPT(NPA_MSE_SET_AT_C, cryptographic_mechanism_reference, ASN1_OBJECT, 0), ASN1_IMP_OPT(NPA_MSE_C, cryptographic_mechanism_reference, ASN1_OBJECT, 0),
/* 0x83 /* 0x83
* Reference of a public key / secret key */ * Reference of a public key / secret key */
ASN1_IMP_OPT(NPA_MSE_SET_AT_C, key_reference1, ASN1_OCTET_STRING, 3), ASN1_IMP_OPT(NPA_MSE_C, key_reference1, ASN1_OCTET_STRING, 3),
/* 0x84 /* 0x84
* Reference of a private key / Reference for computing a session key */ * Reference of a private key / Reference for computing a session key */
ASN1_IMP_OPT(NPA_MSE_SET_AT_C, key_reference2, ASN1_OCTET_STRING, 4), ASN1_IMP_OPT(NPA_MSE_C, key_reference2, ASN1_OCTET_STRING, 4),
/* 0x91 /* 0x91
* Ephemeral Public Key */ * Ephemeral Public Key */
ASN1_IMP_OPT(NPA_MSE_SET_AT_C, eph_pub_key, ASN1_OCTET_STRING, 0x11), ASN1_IMP_OPT(NPA_MSE_C, eph_pub_key, ASN1_OCTET_STRING, 0x11),
/* 0x67 /* 0x67
* Auxiliary authenticated data */ * Auxiliary authenticated data */
ASN1_APP_IMP_OPT(NPA_MSE_SET_AT_C, auxiliary_data, CVC_DISCRETIONARY_DATA_TEMPLATES, 7), ASN1_APP_IMP_OPT(NPA_MSE_C, auxiliary_data, CVC_DISCRETIONARY_DATA_TEMPLATES, 7),
/*ASN1_APP_IMP_OPT(NPA_MSE_SET_AT_C, auxiliary_data, ASN1_OCTET_STRING, 7),*/ /*ASN1_APP_IMP_OPT(NPA_MSE_C, auxiliary_data, ASN1_OCTET_STRING, 7),*/
/* Certificate Holder Authorization Template */ /* Certificate Holder Authorization Template */
ASN1_OPT(NPA_MSE_SET_AT_C, chat, CVC_CHAT), ASN1_OPT(NPA_MSE_C, chat, CVC_CHAT),
} ASN1_SEQUENCE_END(NPA_MSE_SET_AT_C) } ASN1_SEQUENCE_END(NPA_MSE_C)
DECLARE_ASN1_FUNCTIONS(NPA_MSE_SET_AT_C) DECLARE_ASN1_FUNCTIONS(NPA_MSE_C)
IMPLEMENT_ASN1_FUNCTIONS(NPA_MSE_SET_AT_C) IMPLEMENT_ASN1_FUNCTIONS(NPA_MSE_C)
/* /*
@@ -177,6 +178,7 @@ struct npa_sm_ctx {
/* included in OpenPACE, but not propagated */ /* included in OpenPACE, but not propagated */
extern BUF_MEM *BUF_MEM_create(size_t len);
extern BUF_MEM *BUF_MEM_create_init(const void *buf, size_t len); extern BUF_MEM *BUF_MEM_create_init(const void *buf, size_t len);
@@ -339,69 +341,146 @@ err:
return r; return r;
} }
static int npa_mse_set_at(struct sm_ctx *oldnpactx, sc_card_t *card, static int format_mse_cdata(struct sc_context *ctx, int protocol,
int protocol, int secret_key, const CVC_CHAT *chat, u8 *sw1, u8 *sw2) const unsigned char *key_reference1, size_t key_reference1_len,
const unsigned char *key_reference2, size_t key_reference2_len,
const unsigned char *eph_pub_key, size_t eph_pub_key_len,
const unsigned char *auxiliary_data, size_t auxiliary_data_len,
const CVC_CHAT *chat, unsigned char **cdata)
{ {
sc_apdu_t apdu; NPA_MSE_C *data = NULL;
unsigned char *d = NULL; unsigned char *data_sequence;
NPA_MSE_SET_AT_C *data = NULL; const unsigned char *data_no_sequence, *p;
int r, tries, class, tag;
long length; long length;
const unsigned char *p; int r, class, tag;
memset(&apdu, 0, sizeof apdu); if (!cdata) {
if (!card || !sw1 || !sw2) {
r = SC_ERROR_INVALID_ARGUMENTS; r = SC_ERROR_INVALID_ARGUMENTS;
goto err; goto err;
} }
apdu.ins = 0x22; data = NPA_MSE_C_new();
apdu.p1 = 0xc1;
apdu.p2 = 0xa4;
apdu.cse = SC_APDU_CASE_3_SHORT;
apdu.flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
data = NPA_MSE_SET_AT_C_new();
if (!data) { if (!data) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err; goto err;
} }
data->cryptographic_mechanism_reference = OBJ_nid2obj(protocol); if (protocol) {
data->key_reference1 = ASN1_INTEGER_new(); data->cryptographic_mechanism_reference = OBJ_nid2obj(protocol);
if (!data->cryptographic_mechanism_reference) {
if (!data->cryptographic_mechanism_reference sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting Cryptographic mechanism reference of MSE:Set AT data");
|| !data->key_reference1) { r = SC_ERROR_INTERNAL;
r = SC_ERROR_OUT_OF_MEMORY; goto err;
goto err; }
} }
if (!ASN1_INTEGER_set(data->key_reference1, secret_key)) { if (key_reference1 && key_reference1_len) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 1 of MSE:Set AT data"); data->key_reference1 = ASN1_OCTET_STRING_new();
ssl_error(card->ctx); if (!data->key_reference1
r = SC_ERROR_INTERNAL; || !M_ASN1_OCTET_STRING_set(
goto err; data->key_reference1, key_reference1, key_reference1_len)) {
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 1 of MSE:Set AT data");
r = SC_ERROR_INTERNAL;
goto err;
}
}
if (key_reference2 && key_reference2_len) {
data->key_reference2 = ASN1_OCTET_STRING_new();
if (!data->key_reference2
|| !M_ASN1_OCTET_STRING_set(
data->key_reference2, key_reference2, key_reference2_len)) {
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting key reference 2 of MSE:Set AT data");
r = SC_ERROR_INTERNAL;
goto err;
}
}
if (eph_pub_key && eph_pub_key_len) {
data->eph_pub_key = ASN1_OCTET_STRING_new();
if (!data->eph_pub_key
|| !M_ASN1_OCTET_STRING_set(
data->eph_pub_key, eph_pub_key, eph_pub_key_len)) {
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting ephemeral Public Key of MSE:Set AT data");
r = SC_ERROR_INTERNAL;
goto err;
}
}
if (auxiliary_data && auxiliary_data_len) {
if (!d2i_CVC_DISCRETIONARY_DATA_TEMPLATES(&data->auxiliary_data, &auxiliary_data, auxiliary_data_len)) {
sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting auxiliary authenticated data of MSE:Set AT data");
r = SC_ERROR_INTERNAL;
goto err;
}
} }
data->chat = (CVC_CHAT *) chat; data->chat = (CVC_CHAT *) chat;
r = i2d_NPA_MSE_SET_AT_C(data, &d); length = i2d_NPA_MSE_C(data, &data_sequence);
p = d; data_no_sequence = data_sequence;
if (r < 0 if (length < 0
|| (0x80 & ASN1_get_object(&p, &length, &tag, &class, r))) { || (0x80 & ASN1_get_object(&data_no_sequence, &length, &tag, &class, length))) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding MSE:Set AT APDU data"); sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error encoding MSE:Set AT APDU data");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
goto err; goto err;
} }
apdu.data = p; if (length < 0) {
apdu.datalen = length; r = SC_ERROR_INTERNAL;
apdu.lc = length; goto err;
}
bin_log(ctx, SC_LOG_DEBUG_NORMAL, "MSE command data", data_no_sequence, length);
p = realloc(*cdata, length);
if (!p) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
memcpy(*cdata, data_no_sequence, length);
r = length;
err:
if (data) {
/* do not free the functions parameter chat */
data->chat = NULL;
NPA_MSE_C_free(data);
}
if (data_sequence)
free(data_sequence);
return r;
}
static int npa_mse(struct sm_ctx *oldnpactx, sc_card_t *card, unsigned char p1,
int protocol, const unsigned char *secret_key, size_t secret_key_len,
const CVC_CHAT *chat, u8 *sw1, u8 *sw2)
{
sc_apdu_t apdu;
unsigned char *d = NULL;
int r, tries, class, tag;
memset(&apdu, 0, sizeof apdu);
if (!card) {
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
apdu.ins = 0x22;
apdu.p1 = p1;
apdu.p2 = 0xa4;
apdu.cse = SC_APDU_CASE_3_SHORT;
apdu.flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
r = format_mse_cdata(card->ctx, protocol, secret_key, secret_key_len, NULL,
0, NULL, 0, NULL, 0, chat, &d);
if (r < 0)
goto err;
apdu.data = d;
apdu.datalen = r;
apdu.lc = r;
bin_log(card->ctx, SC_LOG_DEBUG_NORMAL, "MSE:Set AT command data", apdu.data, apdu.datalen);
if (oldnpactx) if (oldnpactx)
r = sm_transmit_apdu(oldnpactx, card, &apdu); r = sm_transmit_apdu(oldnpactx, card, &apdu);
@@ -417,12 +496,30 @@ static int npa_mse_set_at(struct sm_ctx *oldnpactx, sc_card_t *card,
goto err; goto err;
} }
*sw1 = apdu.sw1; if (sw1)
*sw2 = apdu.sw2; *sw1 = apdu.sw1;
if (sw2)
*sw2 = apdu.sw2;
if (apdu.sw1 == 0x63) { err:
if ((apdu.sw2 & 0xc0) == 0xc0) { if (d)
tries = apdu.sw2 & 0x0f; free(d);
return r;
}
static int npa_mse_set_at_pace(struct sm_ctx *oldnpactx, sc_card_t *card,
int protocol, enum s_type secret_key, const CVC_CHAT *chat, u8 *sw1,
u8 *sw2)
{
int r, tries;
char key = secret_key;
r = npa_mse(oldnpactx, card, 0xC1, protocol, &key, sizeof key, chat, sw1, sw2);
if (*sw1 == 0x63) {
if ((*sw2 & 0xc0) == 0xc0) {
tries = *sw2 & 0x0f;
if (tries <= 1) { if (tries <= 1) {
/* this is only a warning... */ /* this is only a warning... */
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Remaining tries: %d (%s must be %s)\n", sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Remaining tries: %d (%s must be %s)\n",
@@ -432,32 +529,20 @@ static int npa_mse_set_at(struct sm_ctx *oldnpactx, sc_card_t *card,
r = SC_SUCCESS; r = SC_SUCCESS;
} else { } else {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unknown status bytes: SW1=%02X, SW2=%02X\n", sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unknown status bytes: SW1=%02X, SW2=%02X\n",
apdu.sw1, apdu.sw2); *sw1, *sw2);
r = SC_ERROR_CARD_CMD_FAILED; r = SC_ERROR_CARD_CMD_FAILED;
goto err;
} }
} else if (apdu.sw1 == 0x62 && apdu.sw2 == 0x83) { } else if (*sw1 == 0x62 && *sw2 == 0x83) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Password is deactivated\n"); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Password is deactivated\n");
r = SC_ERROR_AUTH_METHOD_BLOCKED; r = SC_ERROR_AUTH_METHOD_BLOCKED;
goto err;
} else { } else {
r = sc_check_sw(card, apdu.sw1, apdu.sw2); r = sc_check_sw(card, *sw1, *sw2);
} }
err:
if (apdu.resp)
free(apdu.resp);
if (data) {
/* do not free the functions parameter chat */
data->chat = NULL;
NPA_MSE_SET_AT_C_free(data);
}
if (d)
free(d);
return r; return r;
} }
static int npa_gen_auth_1_encrypted_nonce(struct sm_ctx *oldnpactx, static int npa_gen_auth_1_encrypted_nonce(struct sm_ctx *oldnpactx,
sc_card_t *card, u8 **enc_nonce, size_t *enc_nonce_len) sc_card_t *card, u8 **enc_nonce, size_t *enc_nonce_len)
{ {
@@ -1098,13 +1183,15 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
eac_ctx->tr_version = tr_version; eac_ctx->tr_version = tr_version;
r = npa_mse_set_at(oldnpactx, card, eac_ctx->pace_ctx->protocol, pace_input.pin_id, r = npa_mse_set_at_pace(oldnpactx, card, eac_ctx->pace_ctx->protocol,
chat, &pace_output->mse_set_at_sw1, &pace_output->mse_set_at_sw2); pace_input.pin_id, chat, &pace_output->mse_set_at_sw1,
&pace_output->mse_set_at_sw2);
if (r < 0) { if (r < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties " sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties "
"(MSE: Set AT failed)."); "(MSE: Set AT failed).");
goto err; goto err;
} }
enc_nonce = BUF_MEM_new(); enc_nonce = BUF_MEM_new();
if (!enc_nonce) { if (!enc_nonce) {
ssl_error(card->ctx); ssl_error(card->ctx);
@@ -1317,6 +1404,248 @@ err:
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
} }
static int npa_mse_set_dst_ta(struct sm_ctx *npactx, sc_card_t *card,
const unsigned char *car, size_t car_len)
{
return npa_mse(npactx, card, 0x81, 0, car, car_len, NULL,
NULL, NULL);
}
static int npa_mse_set_at_ta(struct sm_ctx *npactx, sc_card_t *card,
const unsigned char *chr, size_t chr_len)
{
return npa_mse(npactx, card, 0xa1, 0, chr, chr_len, NULL,
NULL, NULL);
}
static int npa_get_challenge(struct sm_ctx *npactx, sc_card_t *card,
unsigned char *challenge, size_t len)
{
sc_apdu_t apdu;
int r, class, tag;
long int length;
memset(&apdu, 0, sizeof apdu);
if (!card) {
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
apdu.ins = 0x84;
apdu.cse = SC_APDU_CASE_2_SHORT;
apdu.flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
apdu.resplen = len;
apdu.resp = challenge;
if (npactx)
r = sm_transmit_apdu(npactx, card, &apdu);
else
r = sc_transmit_apdu(card, &apdu);
if (r < 0)
goto err;
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
err:
return r;
}
static int npa_verify(struct sm_ctx *npactx, sc_card_t *card,
const unsigned char *cert, size_t cert_len)
{
sc_apdu_t apdu;
int r, class, tag;
long int length;
memset(&apdu, 0, sizeof apdu);
if (!card) {
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
apdu.ins = 0x2A;
apdu.p1 = 0x00;
apdu.p2 = 0xbe;
apdu.cse = SC_APDU_CASE_4_EXT;
apdu.flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
apdu.data = cert;
if (0x80 & ASN1_get_object(&apdu.data, &length, &tag,
&class, cert_len)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error decoding Certificate");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
apdu.datalen = length;
apdu.lc = length;
if (npactx)
r = sm_transmit_apdu(npactx, card, &apdu);
else
r = sc_transmit_apdu(card, &apdu);
if (r < 0)
goto err;
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
err:
return r;
}
static int npa_external_authenticate(struct sm_ctx *npactx, sc_card_t *card,
const unsigned char *signature, size_t signature_len)
{
int r;
sc_apdu_t apdu;
memset(&apdu, 0, sizeof apdu);
if (!card) {
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
apdu.ins = 0x82;
apdu.cse = SC_APDU_CASE_4_SHORT;
apdu.flags = SC_APDU_FLAGS_NO_GET_RESP|SC_APDU_FLAGS_NO_RETRY_WL;
apdu.data = signature;
apdu.datalen = signature_len;
apdu.lc = signature_len;
if (npactx)
r = sm_transmit_apdu(npactx, card, &apdu);
else
r = sc_transmit_apdu(card, &apdu);
if (r < 0)
goto err;
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
err:
return r;
}
int perform_terminal_authentication(struct sm_ctx *ctx, sc_card_t *card,
const unsigned char **certs, const size_t *certs_lens,
const unsigned char *privkey, size_t privkey_len,
const unsigned char *auxiliary_data, size_t auxiliary_data_len)
{
int r;
const unsigned char *cert;
size_t cert_len, num_certs = 0;
CVC_CERT *cvc_cert = NULL;
BUF_MEM *my_ta_comp_eph_pubkey = NULL, *nonce = NULL, *signature = NULL;
if (!card || !ctx->priv_data || !certs_lens || !certs) {
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
struct npa_sm_ctx *eacsmctx = ctx->priv_data;
eacsmctx->flags = 0;
cert = *certs;
cert_len = *certs_lens;
while (cert && cert_len) {
if (!CVC_d2i_CVC_CERT(&cvc_cert, &cert, cert_len) || !cvc_cert
|| !cvc_cert->body || !cvc_cert->body->certificate_authority_reference
|| !cvc_cert->body->certificate_holder_reference) {
r = SC_ERROR_INVALID_DATA;
goto err;
}
r = npa_mse_set_dst_ta(ctx, card,
cvc_cert->body->certificate_authority_reference->data,
cvc_cert->body->certificate_authority_reference->length);
if (r < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties "
"(MSE: Set AT failed).");
goto err;
}
r = npa_verify(ctx, card, cert, cert_len);
if (r < 0)
goto err;
cert++;
cert_len++;
CVC_CERT_free(cvc_cert);
cvc_cert = NULL;
}
if (!EAC_CTX_init_ta(eacsmctx->ctx, privkey, privkey_len, cert, cert_len,
NULL, 0)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize TA.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
my_ta_comp_eph_pubkey = TA_STEP3_generate_ephemeral_key(eacsmctx->ctx);
if (!my_ta_comp_eph_pubkey) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate CA ephemeral key.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
r = npa_mse_set_at_ta(ctx, card,
cvc_cert->body->certificate_holder_reference->data,
cvc_cert->body->certificate_holder_reference->length);
if (r < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties "
"(MSE: Set AT failed).");
goto err;
}
nonce = BUF_MEM_create(8);
if (!nonce) {
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
r = npa_get_challenge(ctx, card, nonce->data, nonce->length);
if (r < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get nonce for TA.");
goto err;
}
if (!TA_STEP4_set_nonce(eacsmctx->ctx, nonce)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not set nonce for TA.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
eacsmctx->auxiliary_data = BUF_MEM_create_init(auxiliary_data,
auxiliary_data_len);
signature = TA_STEP5_sign(eacsmctx->ctx, my_ta_comp_eph_pubkey,
eacsmctx->id_icc, eacsmctx->auxiliary_data);
if (!signature) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not generate signature.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
r = npa_external_authenticate(ctx, card, signature->data, signature->length);
err:
if (cvc_cert)
CVC_CERT_free(cvc_cert);
if (my_ta_comp_eph_pubkey)
BUF_MEM_free(my_ta_comp_eph_pubkey);
if (nonce)
BUF_MEM_free(nonce);
if (signature)
BUF_MEM_free(signature);
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
static const char *MRZ_name = "MRZ"; static const char *MRZ_name = "MRZ";
static const char *PIN_name = "PIN"; static const char *PIN_name = "PIN";
static const char *PUK_name = "PUK"; static const char *PUK_name = "PUK";
@@ -1594,7 +1923,7 @@ npa_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
long int llen; long int llen;
BUF_MEM *signature = NULL; BUF_MEM *signature = NULL;
unsigned char *sequence = NULL, *templates = NULL; unsigned char *sequence = NULL, *templates = NULL;
NPA_MSE_SET_AT_C *msesetat = NULL; NPA_MSE_C *msesetat = NULL;
const unsigned char *p; const unsigned char *p;
if (!card) if (!card)
@@ -1681,7 +2010,7 @@ npa_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
len = add_tag(&sequence, 1, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, apdu->data, apdu->datalen); len = add_tag(&sequence, 1, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, apdu->data, apdu->datalen);
p = sequence; p = sequence;
if (len < 0 || !d2i_NPA_MSE_SET_AT_C(&msesetat, &p, len)) { if (len < 0 || !d2i_NPA_MSE_C(&msesetat, &p, len)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse MSE:Set AT."); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse MSE:Set AT.");
ssl_error(card->ctx); ssl_error(card->ctx);
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
@@ -1705,7 +2034,7 @@ npa_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
* item template with the correct tag. Due to limitations of * item template with the correct tag. Due to limitations of
* OpenSSL it is not possible to *encode* an optional item template * OpenSSL it is not possible to *encode* an optional item template
* (such as APDU_DISCRETIONARY_DATA_TEMPLATES) in an other item * (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 * template (such as NPA_MSE_C). So what we have to do here
* is manually adding the correct tag to the saved * is manually adding the correct tag to the saved
* CVC_DISCRETIONARY_DATA_TEMPLATES. * CVC_DISCRETIONARY_DATA_TEMPLATES.
* See also openssl/crypto/asn1/tasn_dec.c:183 * See also openssl/crypto/asn1/tasn_dec.c:183