Skip to content

Commit

Permalink
Implement ATR debug event
Browse files Browse the repository at this point in the history
* Add ATR debug event content type
* Add debug macros for trace data and parsed ATR info
* Move logging of parsed ATR to emv_atr_parse()
  • Loading branch information
leonlynch committed Apr 13, 2023
1 parent 23bacea commit 6c08565
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/emv.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ int emv_atr_parse(const void* atr, size_t atr_len)
return EMV_OUTCOME_CARD_ERROR;
}
}
emv_debug_atr_info(&atr_info);

// The intention of this function is to validate the ATR in accordance with
// EMV Level 1 Contact Interface Specification v1.0, 8.3. Some of the
Expand Down
25 changes: 24 additions & 1 deletion src/emv_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ enum emv_debug_level_t {

/// Debug event content type
enum emv_debug_type_t {
EMV_DEBUG_TYPE_MSG, ///< Debug event contains only a string message and no data
EMV_DEBUG_TYPE_MSG = 1, ///< Debug event contains only a string message and no data
EMV_DEBUG_TYPE_DATA, ///< Debug event contains binary data
EMV_DEBUG_TYPE_TLV, ///< Debug event contains ISO 8825-1 BER encoded data
EMV_DEBUG_TYPE_ATR, ///< Debug event contains ISO 7816 Answer To Reset (ATR) data
EMV_DEBUG_TYPE_CAPDU, ///< Debug event contains ISO 7816 C-APDU (command APDU) data
EMV_DEBUG_TYPE_RAPDU, ///< Debug event contains ISO 7816 R-APDU (response APDU) data
EMV_DEBUG_TYPE_CTPDU, ///< Debug event contains ISO 7816 C-TPDU (request TPDU) data
Expand Down Expand Up @@ -161,6 +162,18 @@ void emv_debug_internal(
#define emv_debug_info_tlv(fmt, buf, buf_len, ...) do {} while (0)
#endif // EMV_DEBUG_ENABLED

#if defined(EMV_DEBUG_ENABLED) && !defined(EMV_DEBUG_CARD_DISABLED)

/**
* Emit debug event with decoded ISO 7816 ATR
* @param atr_info Pointer to parsed ATR info (@ref iso7816_atr_info_t)
*/
#define emv_debug_atr_info(atr_info) do { emv_debug_internal(EMV_DEBUG_SOURCE, EMV_DEBUG_CARD, EMV_DEBUG_TYPE_ATR, "ATR", atr_info, sizeof(*atr_info)); } while (0)

#else // EMV_DEBUG_ENABLED && !EMV_DEBUG_CARD_DISABLED
#define emv_debug_atr_info(atr_info) do {} while (0)
#endif // EMV_DEBUG_ENABLED && !EMV_DEBUG_CARD_DISABLED

#if defined(EMV_DEBUG_ENABLED) && !defined(EMV_DEBUG_CARD_DISABLED) && !defined(EMV_DEBUG_APDU_DISABLED)

/**
Expand Down Expand Up @@ -220,8 +233,18 @@ void emv_debug_internal(
*/
#define emv_debug_trace_msg(fmt, ...) do { emv_debug_internal(EMV_DEBUG_SOURCE, EMV_DEBUG_TRACE, EMV_DEBUG_TYPE_MSG, "%s[%u]: "fmt, NULL, 0, __FILE__, __LINE__, ##__VA_ARGS__); } while (0)

/**
* Emit debug trace data
* @param fmt Format string (printf-style)
* @param buf Debug event data
* @param buf_len Length of debug event data in bytes
* @param ... Variable arguments for @c fmt
*/
#define emv_debug_trace_data(fmt, buf, buf_len, ...) do { emv_debug_internal(EMV_DEBUG_SOURCE, EMV_DEBUG_TRACE, EMV_DEBUG_TYPE_DATA, fmt, buf, buf_len, ##__VA_ARGS__); } while (0)

#else // EMV_DEBUG_ENABLED && !EMV_DEBUG_TRACE_DISABLED
#define emv_debug_trace_msg(...) do {} while (0)
#define emv_debug_trace_data(...) do {} while (0)
#endif // EMV_DEBUG_ENABLED && !EMV_DEBUG_TRACE_DISABLED

__END_DECLS
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ if (BUILD_TESTING)
add_test(emv_debug_test emv_debug_test)
string(CONCAT emv_debug_test_regex
"\\[APP\\] asdf=1337[\r\n]"
"\\[APP\\] This is a trace message: DEADBEEF[\r\n]"
)
set_tests_properties(emv_debug_test
PROPERTIES
Expand Down
4 changes: 4 additions & 0 deletions tests/emv_debug_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ int main(void)
{
int r;
size_t asdf = 1337;
uint8_t foo[] = { 0xde, 0xad, 0xbe, 0xef };

// Enable debug output
r = emv_debug_init(EMV_DEBUG_SOURCE_ALL, EMV_DEBUG_ALL, &print_emv_debug);
Expand All @@ -40,4 +41,7 @@ int main(void)

// Test whether compiler supports length modifier z both at compile-time and runtime
emv_debug_error("asdf=%zu", asdf);

// Test trace logging and data output
emv_debug_trace_data("This is a trace message", foo, sizeof(foo));
}
11 changes: 1 addition & 10 deletions tools/emv-tool.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

#include "emv.h"
#include "pcsc.h"
#include "iso7816.h"
#include "print_helpers.h"
#include "emv_tags.h"
#include "emv_fields.h"
Expand Down Expand Up @@ -386,7 +385,6 @@ int main(int argc, char** argv)
size_t reader_idx;
uint8_t atr[PCSC_MAX_ATR_SIZE];
size_t atr_len = 0;
struct iso7816_atr_info_t atr_info;

if (argc == 1) {
// No command line arguments
Expand Down Expand Up @@ -492,14 +490,7 @@ int main(int argc, char** argv)
printf("Failed to retrieve ATR\n");
goto pcsc_exit;
}

r = iso7816_atr_parse(atr, atr_len, &atr_info);
if (r) {
printf("Failed to parse ATR\n");
goto pcsc_exit;
}

print_atr(&atr_info);
emv_debug_trace_data("ATR", atr, atr_len);

r = emv_atr_parse(atr, atr_len);
if (r < 0) {
Expand Down
11 changes: 8 additions & 3 deletions tools/print_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,15 +510,20 @@ static void print_emv_debug_internal(
printf("%s\n", str);
return;
} else {
printf("%s: ", str);
print_buf(NULL, buf, buf_len);

switch (debug_type) {
case EMV_DEBUG_TYPE_TLV:
printf("%s: ", str);
print_buf(NULL, buf, buf_len);
print_emv_buf(buf, buf_len, " ", 1);
return;

case EMV_DEBUG_TYPE_ATR:
print_atr(buf);
return;

default:
printf("%s: ", str);
print_buf(NULL, buf, buf_len);
return;
}
}
Expand Down

0 comments on commit 6c08565

Please sign in to comment.