diff --git a/src/iso7816_strings.c b/src/iso7816_strings.c index 046da2c..6697c66 100644 --- a/src/iso7816_strings.c +++ b/src/iso7816_strings.c @@ -65,6 +65,11 @@ const char* iso7816_sw1sw2_get_string(uint8_t SW1, uint8_t SW2, char* str, size_ int r; char* str_ptr = str; + if (!str || !str_len) { + // Invalid parameters + return NULL; + } + // Normal processing (see ISO 7816-4:2005, 5.1.3) if (SW1 == 0x90 && SW2 == 0x00) { snprintf(str, str_len, "Normal"); diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 491f957..e23c90c 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -81,7 +81,7 @@ if(BUILD_EMV_TOOL) endif() add_executable(emv-tool emv-tool.c ../src/pcsc.c) - target_link_libraries(emv-tool PRIVATE print_helpers iso7816 emv emv_strings) + target_link_libraries(emv-tool PRIVATE print_helpers emv emv_strings) if(TARGET libargp::argp) target_link_libraries(emv-tool PRIVATE libargp::argp) endif() diff --git a/tools/print_helpers.c b/tools/print_helpers.c index 1a4501f..88af740 100644 --- a/tools/print_helpers.c +++ b/tools/print_helpers.c @@ -246,6 +246,42 @@ void print_atr_historical_bytes(const struct iso7816_atr_info_t* atr_info) } } +void print_rapdu(const void* r_apdu, size_t r_apdu_len) +{ + const uint8_t* ptr = r_apdu; + char str[1024]; + const char* s; + + if (!r_apdu || !r_apdu_len) { + printf("(null)\n"); + return; + } + + for (size_t i = 0; i < r_apdu_len; i++) { + printf("%02X", ptr[i]); + } + + if (r_apdu_len < 2) { + // No status + printf("\n"); + return; + } + + s = iso7816_sw1sw2_get_string( + ptr[r_apdu_len - 2], + ptr[r_apdu_len - 1], + str, + sizeof(str) + ); + if (!s || !s[0]) { + // No string or empty string + printf("\n"); + return; + } + + printf(" (%s)\n", s); +} + void print_sw1sw2(uint8_t SW1, uint8_t SW2) { char str[1024]; @@ -524,6 +560,11 @@ static void print_emv_debug_internal( print_atr(buf); return; + case EMV_DEBUG_TYPE_RAPDU: + printf("%s: ", str); + print_rapdu(buf, buf_len); + return; + default: print_buf(str, buf, buf_len); return; diff --git a/tools/print_helpers.h b/tools/print_helpers.h index 018af5f..2abe96f 100644 --- a/tools/print_helpers.h +++ b/tools/print_helpers.h @@ -2,7 +2,7 @@ * @file print_helpers.h * @brief Helper functions for command line output * - * Copyright (c) 2021, 2022 Leon Lynch + * Copyright (c) 2021-2022, 2024 Leon Lynch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -71,6 +71,13 @@ void print_atr(const struct iso7816_atr_info_t* atr_info); */ void print_atr_historical_bytes(const struct iso7816_atr_info_t* atr_info); +/** + * Print R-APDU + * @param r_apdu Response Application Protocol Data Unit (C-APDU) + * @param r_apdu_len Length of Response Application Protocol Data Unit (C-APDU). Must be at least 4 bytes. + */ +void print_rapdu(const void* r_apdu, size_t r_apdu_len); + /** * Print status bytes SW1-SW2 * @param SW1 Status byte 1