Skip to content

Commit

Permalink
Implement R-APDU print helper
Browse files Browse the repository at this point in the history
* iso7816_sw1sw2_get_string() already provides a one-line description of
  the R-APDU status bytes.
* print_rapdu() will print the R-APDU buffer followed by the one-line
  description provided by iso7816_sw1sw2_get_string() in parentheses.
  The decoded response data should be printed separately using other
  helper functions.
* emv-tool does not use iso7816 directly and therefore should not link
  it. Instead, print_helpers already links iso7816,
  • Loading branch information
leonlynch committed Mar 29, 2024
1 parent 4d87870 commit d5170b7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/iso7816_strings.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
41 changes: 41 additions & 0 deletions tools/print_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 8 additions & 1 deletion tools/print_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d5170b7

Please sign in to comment.