diff --git a/npa/src/npa-tool.c b/npa/src/npa-tool.c index e86851e..df78637 100644 --- a/npa/src/npa-tool.c +++ b/npa/src/npa-tool.c @@ -207,8 +207,8 @@ int npa_translate_apdus(sc_card_t *card, FILE *input) return r; } -static int add_to_CVC_DISCRETIONARY_DATA_TEMPLATES( - CVC_DISCRETIONARY_DATA_TEMPLATES **templates, +static int add_to_ASN1_AUXILIARY_DATA( + ASN1_AUXILIARY_DATA **templates, int nid, const unsigned char *data, size_t data_len) { int r; @@ -220,7 +220,7 @@ static int add_to_CVC_DISCRETIONARY_DATA_TEMPLATES( } if (!*templates) { - *templates = CVC_DISCRETIONARY_DATA_TEMPLATES_new(); + *templates = ASN1_AUXILIARY_DATA_new(); if (!*templates) { r = SC_ERROR_INTERNAL; goto err; @@ -298,7 +298,7 @@ main (int argc, char **argv) unsigned char *certs_chat = NULL; unsigned char *dg = NULL; size_t dg_len = 0; - CVC_DISCRETIONARY_DATA_TEMPLATES *templates = NULL; + ASN1_AUXILIARY_DATA *templates = NULL; struct gengetopt_args_info cmdline; @@ -577,7 +577,7 @@ main (int argc, char **argv) } } else { if (cmdline.older_than_given) { - r = add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(&templates, + r = add_to_ASN1_AUXILIARY_DATA(&templates, NID_id_DateOfBirth, (unsigned char *) cmdline.older_than_arg, strlen(cmdline.older_than_arg)); @@ -585,30 +585,32 @@ main (int argc, char **argv) goto err; } if (cmdline.verify_validity_given) { - r = add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(&templates, + r = add_to_ASN1_AUXILIARY_DATA(&templates, NID_id_DateOfExpiry, NULL, 0); if (r < 0) goto err; } if (cmdline.verify_community_given) { - r = add_to_CVC_DISCRETIONARY_DATA_TEMPLATES(&templates, + r = add_to_ASN1_AUXILIARY_DATA(&templates, NID_id_CommunityID, (unsigned char *) cmdline.verify_community_arg, strlen(cmdline.verify_community_arg)); if (r < 0) goto err; } - unsigned char *p = NULL; - auxiliary_data_len = i2d_CVC_DISCRETIONARY_DATA_TEMPLATES( - templates, &p); - if (0 >= (int) auxiliary_data_len - || auxiliary_data_len > sizeof auxiliary_data) { + if (templates) { + unsigned char *p = NULL; + auxiliary_data_len = i2d_ASN1_AUXILIARY_DATA( + templates, &p); + if (0 > (int) auxiliary_data_len + || auxiliary_data_len > sizeof auxiliary_data) { + free(p); + r = SC_ERROR_INTERNAL; + goto err; + } + memcpy(auxiliary_data, p, auxiliary_data_len); free(p); - r = SC_ERROR_INTERNAL; - goto err; } - memcpy(auxiliary_data, p, auxiliary_data_len); - free(p); } } @@ -782,7 +784,7 @@ err: free(privkey); free(dg); if (templates) - CVC_DISCRETIONARY_DATA_TEMPLATES_free(templates); + ASN1_AUXILIARY_DATA_free(templates); sm_stop(card); sc_reset(card, 1); diff --git a/npa/src/npa.c b/npa/src/npa.c index 3f46632..59f2709 100644 --- a/npa/src/npa.c +++ b/npa/src/npa.c @@ -44,6 +44,15 @@ #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) +/* 0x67 + * Auxiliary authenticated data */ +ASN1_ITEM_TEMPLATE(ASN1_AUXILIARY_DATA) = + ASN1_EX_TEMPLATE_TYPE( + ASN1_TFLG_IMPTAG|ASN1_TFLG_APPLICATION, + 7, ASN1_AUXILIARY_DATA, CVC_DISCRETIONARY_DATA_TEMPLATES) +ASN1_ITEM_TEMPLATE_END(ASN1_AUXILIARY_DATA) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) + /* * MSE:Set AT */ @@ -53,7 +62,7 @@ typedef struct npa_mse_cd_st { ASN1_OCTET_STRING *key_reference1; ASN1_OCTET_STRING *key_reference2; ASN1_OCTET_STRING *eph_pub_key; - CVC_DISCRETIONARY_DATA_TEMPLATES *auxiliary_data; + ASN1_AUXILIARY_DATA *auxiliary_data; CVC_CHAT *chat; } NPA_MSE_C; ASN1_SEQUENCE(NPA_MSE_C) = { @@ -71,8 +80,7 @@ ASN1_SEQUENCE(NPA_MSE_C) = { ASN1_IMP_OPT(NPA_MSE_C, eph_pub_key, ASN1_OCTET_STRING, 0x11), /* 0x67 * Auxiliary authenticated data */ - ASN1_APP_IMP_OPT(NPA_MSE_C, auxiliary_data, CVC_DISCRETIONARY_DATA_TEMPLATES, 7), - /*ASN1_APP_IMP_OPT(NPA_MSE_C, auxiliary_data, ASN1_OCTET_STRING, 7),*/ + ASN1_OPT(NPA_MSE_C, auxiliary_data, ASN1_AUXILIARY_DATA), /* Certificate Holder Authorization Template */ ASN1_OPT(NPA_MSE_C, chat, CVC_CHAT), } ASN1_SEQUENCE_END(NPA_MSE_C) @@ -516,9 +524,8 @@ static int format_mse_cdata(struct sc_context *ctx, int protocol, } if (auxiliary_data && auxiliary_data_len) { - bin_log(ctx, SC_LOG_DEBUG_NORMAL, "test", 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"); + if (!d2i_ASN1_AUXILIARY_DATA(&data->auxiliary_data, &auxiliary_data, auxiliary_data_len)) { + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Error setting authenticated auxiliary data of MSE:Set AT data"); r = SC_ERROR_INTERNAL; goto err; } @@ -1749,10 +1756,6 @@ int perform_terminal_authentication(sc_card_t *card, BUF_MEM_free(eacsmctx->auxiliary_data); eacsmctx->auxiliary_data = BUF_MEM_create_init(auxiliary_data, auxiliary_data_len); - /* FIXME this is a workaround for fixing 0x30 tag of - * CVC_DISCRETIONARY_DATA_TEMPLATES. */ - if (eacsmctx->auxiliary_data->data && eacsmctx->auxiliary_data->length) - eacsmctx->auxiliary_data->data[0] = 0x67; signature = TA_STEP5_sign(eacsmctx->ctx, eacsmctx->eph_pub_key, eacsmctx->id_icc, eacsmctx->auxiliary_data); if (!signature) { @@ -2222,8 +2225,7 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, int r; CVC_CERT *cvc_cert = NULL; unsigned char *cert = NULL; - int len, tag, class; - long int llen; + int len; BUF_MEM *signature = NULL; unsigned char *sequence = NULL, *templates = NULL; NPA_MSE_C *msesetat = NULL; @@ -2333,31 +2335,15 @@ npa_sm_pre_transmit(sc_card_t *card, const struct iso_sm_ctx *ctx, 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_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))) { + eacsmctx->auxiliary_data->length = i2d_ASN1_AUXILIARY_DATA( + msesetat->auxiliary_data, + (unsigned char **) &eacsmctx->auxiliary_data->data); + if ((int) eacsmctx->auxiliary_data->length < 0) { 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) { diff --git a/npa/src/npa/npa.h b/npa/src/npa/npa.h index a619219..04806e2 100644 --- a/npa/src/npa/npa.h +++ b/npa/src/npa/npa.h @@ -26,6 +26,7 @@ #ifndef _CCID_NPA_H #define _CCID_NPA_H +#include #include #include #include @@ -155,8 +156,8 @@ int perform_pace(sc_card_t *card, * @param[in] privkey The terminal's private key * @param[in] privkey_len length of \a privkey * @param[in] auxiliary_data auxiliary data for age/validity/community ID - * verification. Should be formatted as buffer of - * \c CVC_DISCRETIONARY_DATA_TEMPLATES + * verification. Should be an ASN1 object tagged + * with \c 0x67 * @param[in] auxiliary_data_len length of \a auxiliary_data * * @return \c SC_SUCCESS or error code if an error occurred @@ -223,6 +224,10 @@ int npa_reset_retry_counter(sc_card_t *card, /** Use \c npa_default_flags to disable checks for EAC/SM */ extern char npa_default_flags; +/** ASN.1 type for authenticated auxiliary data for terminal authentication */ +typedef CVC_DISCRETIONARY_DATA_TEMPLATES ASN1_AUXILIARY_DATA; +DECLARE_ASN1_FUNCTIONS(ASN1_AUXILIARY_DATA) + #ifdef __cplusplus } #endif