Skip to content

Commit

Permalink
Refactor emv_initiate_application_processing() to use emv_ctx_t
Browse files Browse the repository at this point in the history
Note that emv_initiate_application_processing() will now clear the ICC
data list in case it was populated by a previous application selection
attempt.

Also, emv_initiate_application_processing() no longer has separate TLV
source lists as parameters and will instead search the TLV lists when
building the PDOL data for GET PROCESSING OPTIONS in this order:
* emv_ctx_t.params
* emv_ctx_t.config

In future, a more advanced per-AID configuration mechanism will impact
the above order.
  • Loading branch information
leonlynch committed May 5, 2024
1 parent a547b17 commit 71c3542
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 146 deletions.
30 changes: 13 additions & 17 deletions src/emv.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,13 +486,7 @@ int emv_select_application(
return r;
}

int emv_initiate_application_processing(
struct emv_ttl_t* ttl,
struct emv_app_t* selected_app,
const struct emv_tlv_list_t* source1,
const struct emv_tlv_list_t* source2,
struct emv_tlv_list_t* icc
)
int emv_initiate_application_processing(struct emv_ctx_t* ctx)
{
int r;
const struct emv_tlv_t* pdol;
Expand All @@ -501,15 +495,18 @@ int emv_initiate_application_processing(
size_t gpo_data_len;
struct emv_tlv_list_t gpo_output = EMV_TLV_LIST_INIT;

if (!ttl || !selected_app || !source1) {
emv_debug_trace_msg("ttl=%p, selected_app=%p, source1=%p, source2=%p", ttl, selected_app, source1, source2);
if (!ctx || !ctx->selected_app) {
emv_debug_trace_msg("ctx=%p, selected_app=%p", ctx, ctx->selected_app);
emv_debug_error("Invalid parameter");
return EMV_ERROR_INVALID_PARAMETER;
}

// Clear existing ICC data list to avoid ambiguity
emv_tlv_list_clear(&ctx->icc);

// Process PDOL, if available
// See EMV 4.4 Book 3, 10.1
pdol = emv_tlv_list_find_const(&selected_app->tlv_list, EMV_TAG_9F38_PDOL);
pdol = emv_tlv_list_find_const(&ctx->selected_app->tlv_list, EMV_TAG_9F38_PDOL);
if (pdol) {
int dol_data_len;
size_t gpo_data_offset;
Expand Down Expand Up @@ -545,8 +542,8 @@ int emv_initiate_application_processing(
r = emv_dol_build_data(
pdol->value,
pdol->length,
source1,
source2,
&ctx->params,
&ctx->config,
gpo_data + gpo_data_offset,
&gpo_data_len
);
Expand All @@ -569,7 +566,7 @@ int emv_initiate_application_processing(
gpo_data_len = 0;
}

r = emv_tal_get_processing_options(ttl, gpo_data, gpo_data_len, &gpo_output, NULL, NULL);
r = emv_tal_get_processing_options(ctx->ttl, gpo_data, gpo_data_len, &gpo_output, NULL, NULL);
if (r) {
emv_debug_trace_msg("emv_tal_get_processing_options() failed; r=%d", r);
if (r < 0) {
Expand Down Expand Up @@ -600,11 +597,11 @@ int emv_initiate_application_processing(
}

// Move application data to ICC data list
*icc = selected_app->tlv_list;
selected_app->tlv_list = EMV_TLV_LIST_INIT;
ctx->icc = ctx->selected_app->tlv_list;
ctx->selected_app->tlv_list = EMV_TLV_LIST_INIT;

// Append GPO output to ICC data list
r = emv_tlv_list_append(icc, &gpo_output);
r = emv_tlv_list_append(&ctx->icc, &gpo_output);
if (r) {
emv_debug_trace_msg("emv_tlv_list_append() failed; r=%d", r);

Expand All @@ -619,7 +616,6 @@ int emv_initiate_application_processing(
goto exit;

error:
emv_tlv_list_clear(icc);
emv_tlv_list_clear(&gpo_output);
exit:
return r;
Expand Down
26 changes: 12 additions & 14 deletions src/emv.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ struct emv_ctx_t {
/**
* @brief Currently selected application
*
* Populated by @ref emv_select_application().
* Populated by @ref emv_select_application() and used by
* @ref emv_initiate_application_processing().
*/
struct emv_app_t* selected_app;

Expand Down Expand Up @@ -261,29 +262,26 @@ int emv_select_application(
/**
* Initiate EMV application processing by assessing the Processing Options
* Data Object List (PDOL) and performing GET PROCESSING OPTIONS.
*
* When building the PDOL data required for GET PROCESSING OPTIONS, this
* function will search the TLV lists in this order:
* - @ref emv_ctx_t.params
* - @ref emv_ctx_t.config
*
* @note Upon success, this function will also move the selected application's
* TLV data to the ICC data output and append the output of
* TLV data to the ICC data list and append the output of
* GET PROCESSING OPTIONS.
*
* @remark See EMV 4.4 Book 3, 10.1
* @remark See EMV 4.4 Book 4, 6.3.1
*
* @param ttl EMV Terminal Transport Layer context
* @param selected_app Selected EMV application
* @param source1 EMV TLV list used as primary source. Required.
* @param source2 EMV TLV list used as secondary source. NULL to ignore.
* @param icc ICC data output
* @param ctx EMV processing context
*
* @return Zero for success
* @return Less than zero for errors. See @ref emv_error_t
* @return Greater than zero for EMV processing outcome. See @ref emv_outcome_t
*/
int emv_initiate_application_processing(
struct emv_ttl_t* ttl,
struct emv_app_t* selected_app,
const struct emv_tlv_list_t* source1,
const struct emv_tlv_list_t* source2,
struct emv_tlv_list_t* icc
);
int emv_initiate_application_processing(struct emv_ctx_t* ctx);

/**
* Read EMV application data by performing READ RECORD for all records
Expand Down
Loading

0 comments on commit 71c3542

Please sign in to comment.