Skip to content

Commit

Permalink
Add emv_tlv_list_find_const() alternative for emv_tlv_list_find()
Browse files Browse the repository at this point in the history
* emv_tlv_list_find_const() is intentionally an inline header function
  that will not be an external library symbol
* Convert as many variables and parameters to be const pointers by using
  emv_tlv_list_find_const() whenever possible
  • Loading branch information
leonlynch committed Mar 21, 2024
1 parent 9d1aa0c commit 0e1ab29
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 39 deletions.
8 changes: 4 additions & 4 deletions src/emv.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ int emv_initiate_application_processing(

// Process PDOL, if available
// See EMV 4.4 Book 3, 10.1
pdol = emv_tlv_list_find(&selected_app->tlv_list, EMV_TAG_9F38_PDOL);
pdol = emv_tlv_list_find_const(&selected_app->tlv_list, EMV_TAG_9F38_PDOL);
if (pdol) {
int dol_data_len;
size_t gpo_data_offset;
Expand Down Expand Up @@ -494,8 +494,8 @@ int emv_initiate_application_processing(
r = emv_dol_build_data(
pdol->value,
pdol->length,
(struct emv_tlv_list_t*)source1,
(struct emv_tlv_list_t*)source2,
source1,
source2,
gpo_data + gpo_data_offset,
&gpo_data_len
);
Expand Down Expand Up @@ -595,7 +595,7 @@ int emv_read_application_data(

// Process Application File Locator (AFL)
// See EMV 4.4 Book 3, 10.2
afl = emv_tlv_list_find(icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
afl = emv_tlv_list_find_const(icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
if (!afl) {
// AFL not found; terminate session
// See EMV 4.4 Book 3, 6.5.8.4
Expand Down
24 changes: 12 additions & 12 deletions src/emv_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include <assert.h>

// Helper functions
static int emv_app_extract_display_name(struct emv_app_t* app, struct emv_tlv_list_t* pse_tlv_list);
static int emv_app_extract_display_name(struct emv_app_t* app, const struct emv_tlv_list_t* pse_tlv_list);
static int emv_app_extract_priority_indicator(struct emv_app_t* app);
static inline bool emv_app_list_is_valid(const struct emv_app_list_t* list);

Expand Down Expand Up @@ -62,7 +62,7 @@ struct emv_app_t* emv_app_create_from_pse(
}

// Use ADF Name field for AID
app->aid = emv_tlv_list_find(&app->tlv_list, EMV_TAG_4F_APPLICATION_DF_NAME);
app->aid = emv_tlv_list_find_const(&app->tlv_list, EMV_TAG_4F_APPLICATION_DF_NAME);
if (!app->aid) {
// Invalid FCI
goto error;
Expand Down Expand Up @@ -120,7 +120,7 @@ struct emv_app_t* emv_app_create_from_fci(const void* fci, size_t fci_len)
}

// Use DF Name field for AID
app->aid = emv_tlv_list_find(&app->tlv_list, EMV_TAG_84_DF_NAME);
app->aid = emv_tlv_list_find_const(&app->tlv_list, EMV_TAG_84_DF_NAME);
if (!app->aid) {
// Invalid FCI
goto error;
Expand All @@ -143,12 +143,12 @@ struct emv_app_t* emv_app_create_from_fci(const void* fci, size_t fci_len)
return NULL;
}

static int emv_app_extract_display_name(struct emv_app_t* app, struct emv_tlv_list_t* pse_tlv_list)
static int emv_app_extract_display_name(struct emv_app_t* app, const struct emv_tlv_list_t* pse_tlv_list)
{
int r;
struct emv_tlv_t* issuer_code_table_index;
const struct emv_tlv_t* issuer_code_table_index;
unsigned int issuer_code_table = 0;
struct emv_tlv_t* tlv;
const struct emv_tlv_t* tlv;

if (!app) {
return -1;
Expand All @@ -159,9 +159,9 @@ static int emv_app_extract_display_name(struct emv_app_t* app, struct emv_tlv_li
* interpret Application Preferred Name
*/
if (pse_tlv_list) {
issuer_code_table_index = emv_tlv_list_find(pse_tlv_list, EMV_TAG_9F11_ISSUER_CODE_TABLE_INDEX);
issuer_code_table_index = emv_tlv_list_find_const(pse_tlv_list, EMV_TAG_9F11_ISSUER_CODE_TABLE_INDEX);
} else {
issuer_code_table_index = emv_tlv_list_find(&app->tlv_list, EMV_TAG_9F11_ISSUER_CODE_TABLE_INDEX);
issuer_code_table_index = emv_tlv_list_find_const(&app->tlv_list, EMV_TAG_9F11_ISSUER_CODE_TABLE_INDEX);
}
if (issuer_code_table_index && issuer_code_table_index->length == 1) {
// Assume Additional Terminal Capabilities (field 9F40) was correctly
Expand All @@ -173,7 +173,7 @@ static int emv_app_extract_display_name(struct emv_app_t* app, struct emv_tlv_li
}
if (issuer_code_table) {
// Use Application Preferred Name as display name
tlv = emv_tlv_list_find(&app->tlv_list, EMV_TAG_9F12_APPLICATION_PREFERRED_NAME);
tlv = emv_tlv_list_find_const(&app->tlv_list, EMV_TAG_9F12_APPLICATION_PREFERRED_NAME);
if (tlv) {
// Application Preferred Name is limited to non-control characters
// defined in the ISO/IEC 8859 part designated in the Issuer Code
Expand Down Expand Up @@ -207,7 +207,7 @@ static int emv_app_extract_display_name(struct emv_app_t* app, struct emv_tlv_li
}

// Otherwise use Application Label as display name
tlv = emv_tlv_list_find(&app->tlv_list, EMV_TAG_50_APPLICATION_LABEL);
tlv = emv_tlv_list_find_const(&app->tlv_list, EMV_TAG_50_APPLICATION_LABEL);
if (tlv) {
// Application Label is limited to a-z, A-Z, 0-9 and the space
// See EMV 4.4 Book 1, 4.3
Expand Down Expand Up @@ -242,7 +242,7 @@ static int emv_app_extract_display_name(struct emv_app_t* app, struct emv_tlv_li

static int emv_app_extract_priority_indicator(struct emv_app_t* app)
{
struct emv_tlv_t* tlv;
const struct emv_tlv_t* tlv;

if (!app) {
return -1;
Expand All @@ -251,7 +251,7 @@ static int emv_app_extract_priority_indicator(struct emv_app_t* app)
app->priority = 0;
app->confirmation_required = false;

tlv = emv_tlv_list_find(&app->tlv_list, EMV_TAG_87_APPLICATION_PRIORITY_INDICATOR);
tlv = emv_tlv_list_find_const(&app->tlv_list, EMV_TAG_87_APPLICATION_PRIORITY_INDICATOR);
if (!tlv || tlv->length < 1) {
// Application Priority Indicator is not available; ignore
return 0;
Expand Down
8 changes: 4 additions & 4 deletions src/emv_dol.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ int emv_dol_compute_data_length(const void* ptr, size_t len)
int emv_dol_build_data(
const void* ptr,
size_t len,
struct emv_tlv_list_t* source1,
struct emv_tlv_list_t* source2,
const struct emv_tlv_list_t* source1,
const struct emv_tlv_list_t* source2,
void* data,
size_t* data_len
)
Expand Down Expand Up @@ -156,9 +156,9 @@ int emv_dol_build_data(
}

// Find TLV
tlv = emv_tlv_list_find(source1, entry.tag);
tlv = emv_tlv_list_find_const(source1, entry.tag);
if (!tlv && source2) {
tlv = emv_tlv_list_find(source2, entry.tag);
tlv = emv_tlv_list_find_const(source2, entry.tag);
}
if (!tlv) {
// If TLV is not found, zero data output
Expand Down
4 changes: 2 additions & 2 deletions src/emv_dol.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ int emv_dol_compute_data_length(const void* ptr, size_t len);
int emv_dol_build_data(
const void* ptr,
size_t len,
struct emv_tlv_list_t* source1,
struct emv_tlv_list_t* source2,
const struct emv_tlv_list_t* source1,
const struct emv_tlv_list_t* source2,
void* data,
size_t* data_len
);
Expand Down
14 changes: 7 additions & 7 deletions src/emv_tal.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ int emv_tal_read_pse(

// Find Short File Identifier (SFI) for PSE directory Application Elementary File (AEF)
// See EMV 4.4 Book 1, 11.3.4, table 8
pse_sfi = emv_tlv_list_find(&pse_tlv_list, EMV_TAG_88_SFI);
pse_sfi = emv_tlv_list_find_const(&pse_tlv_list, EMV_TAG_88_SFI);
if (!pse_sfi) {
emv_debug_trace_msg("emv_tlv_list_find() failed; pse_sfi=%p", pse_sfi);
emv_debug_trace_msg("emv_tlv_list_find_const() failed; pse_sfi=%p", pse_sfi);

// Failed to find SFI for PSE records; terminal may continue session
// See EMV 4.4 Book 1, 12.3.2, step 1
Expand Down Expand Up @@ -544,8 +544,8 @@ int emv_tal_get_processing_options(
const void* data,
size_t data_len,
struct emv_tlv_list_t* list,
struct emv_tlv_t** aip,
struct emv_tlv_t** afl
const struct emv_tlv_t** aip,
const struct emv_tlv_t** afl
)
{
int r;
Expand All @@ -554,7 +554,7 @@ int emv_tal_get_processing_options(
uint16_t sw1sw2;
struct iso8825_tlv_t gpo_tlv;
struct emv_tlv_list_t gpo_list = EMV_TLV_LIST_INIT;
struct emv_tlv_t* tlv;
const struct emv_tlv_t* tlv;

if (!ttl || !list) {
// Invalid parameters; terminate session
Expand Down Expand Up @@ -696,7 +696,7 @@ int emv_tal_get_processing_options(
}

// Populate AIP pointer
tlv = emv_tlv_list_find(&gpo_list, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
tlv = emv_tlv_list_find_const(&gpo_list, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
if (!tlv) {
// Mandatory field missing; terminate session
// See EMV 4.4 Book 3, 6.5.8.4
Expand All @@ -709,7 +709,7 @@ int emv_tal_get_processing_options(
}

// Populate AFL pointer
tlv = emv_tlv_list_find(&gpo_list, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
tlv = emv_tlv_list_find_const(&gpo_list, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
if (!tlv) {
// Mandatory field missing; terminate session
// See EMV 4.4 Book 3, 6.5.8.4
Expand Down
4 changes: 2 additions & 2 deletions src/emv_tal.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ int emv_tal_get_processing_options(
const void* data,
size_t data_len,
struct emv_tlv_list_t* list,
struct emv_tlv_t** aip,
struct emv_tlv_t** afl
const struct emv_tlv_t** aip,
const struct emv_tlv_t** afl
);

/**
Expand Down
17 changes: 17 additions & 0 deletions src/emv_tlv.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ struct emv_tlv_t* emv_tlv_list_pop(struct emv_tlv_list_t* list);
*/
struct emv_tlv_t* emv_tlv_list_find(struct emv_tlv_list_t* list, unsigned int tag);

/**
* Const alternative for @ref emv_tlv_list_find
* @param list EMV TLV list
* @param tag EMV tag to find
* @return EMV TLV field. Do NOT free. NULL if not found.
*/
#ifdef __GNUC__
__attribute__((always_inline))
#endif
inline const struct emv_tlv_t* emv_tlv_list_find_const(
const struct emv_tlv_list_t* list,
unsigned int tag
)
{
return emv_tlv_list_find((struct emv_tlv_list_t*)list, tag);
}

/**
* Determine whether EMV TLV list contains duplicate fields
* @param list EMV TLV list
Expand Down
16 changes: 8 additions & 8 deletions tests/emv_initiate_application_processing_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ int main(void)
struct emv_tlv_list_t source2 = EMV_TLV_LIST_INIT;
struct emv_app_t* app = NULL;
struct emv_tlv_list_t icc = EMV_TLV_LIST_INIT;
struct emv_tlv_t* aip;
struct emv_tlv_t* afl;
const struct emv_tlv_t* aip;
const struct emv_tlv_t* afl;

ttl.cardreader.mode = EMV_CARDREADER_MODE_APDU;
ttl.cardreader.ctx = &emul_ctx;
Expand Down Expand Up @@ -193,7 +193,7 @@ int main(void)
r = 1;
goto exit;
}
aip = emv_tlv_list_find(&icc, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
aip = emv_tlv_list_find_const(&icc, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
if (!aip) {
fprintf(stderr, "Failed to find AIP\n");
r = 1;
Expand All @@ -208,7 +208,7 @@ int main(void)
r = 1;
goto exit;
}
afl = emv_tlv_list_find(&icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
afl = emv_tlv_list_find_const(&icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
if (!afl) {
fprintf(stderr, "Failed to find AFL\n");
r = 1;
Expand Down Expand Up @@ -259,7 +259,7 @@ int main(void)
r = 1;
goto exit;
}
aip = emv_tlv_list_find(&icc, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
aip = emv_tlv_list_find_const(&icc, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
if (!aip) {
fprintf(stderr, "Failed to find AIP\n");
r = 1;
Expand All @@ -274,7 +274,7 @@ int main(void)
r = 1;
goto exit;
}
afl = emv_tlv_list_find(&icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
afl = emv_tlv_list_find_const(&icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
if (!afl) {
fprintf(stderr, "Failed to find AFL\n");
r = 1;
Expand Down Expand Up @@ -361,7 +361,7 @@ int main(void)
r = 1;
goto exit;
}
aip = emv_tlv_list_find(&icc, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
aip = emv_tlv_list_find_const(&icc, EMV_TAG_82_APPLICATION_INTERCHANGE_PROFILE);
if (!aip) {
fprintf(stderr, "Failed to find AIP\n");
r = 1;
Expand All @@ -376,7 +376,7 @@ int main(void)
r = 1;
goto exit;
}
afl = emv_tlv_list_find(&icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
afl = emv_tlv_list_find_const(&icc, EMV_TAG_94_APPLICATION_FILE_LOCATOR);
if (!afl) {
fprintf(stderr, "Failed to find AFL\n");
r = 1;
Expand Down

0 comments on commit 0e1ab29

Please sign in to comment.