Skip to content

Commit d5170b7

Browse files
committed
Implement R-APDU print helper
* 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,
1 parent 4d87870 commit d5170b7

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

src/iso7816_strings.c

+5
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ const char* iso7816_sw1sw2_get_string(uint8_t SW1, uint8_t SW2, char* str, size_
6565
int r;
6666
char* str_ptr = str;
6767

68+
if (!str || !str_len) {
69+
// Invalid parameters
70+
return NULL;
71+
}
72+
6873
// Normal processing (see ISO 7816-4:2005, 5.1.3)
6974
if (SW1 == 0x90 && SW2 == 0x00) {
7075
snprintf(str, str_len, "Normal");

tools/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ if(BUILD_EMV_TOOL)
8181
endif()
8282

8383
add_executable(emv-tool emv-tool.c ../src/pcsc.c)
84-
target_link_libraries(emv-tool PRIVATE print_helpers iso7816 emv emv_strings)
84+
target_link_libraries(emv-tool PRIVATE print_helpers emv emv_strings)
8585
if(TARGET libargp::argp)
8686
target_link_libraries(emv-tool PRIVATE libargp::argp)
8787
endif()

tools/print_helpers.c

+41
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,42 @@ void print_atr_historical_bytes(const struct iso7816_atr_info_t* atr_info)
246246
}
247247
}
248248

249+
void print_rapdu(const void* r_apdu, size_t r_apdu_len)
250+
{
251+
const uint8_t* ptr = r_apdu;
252+
char str[1024];
253+
const char* s;
254+
255+
if (!r_apdu || !r_apdu_len) {
256+
printf("(null)\n");
257+
return;
258+
}
259+
260+
for (size_t i = 0; i < r_apdu_len; i++) {
261+
printf("%02X", ptr[i]);
262+
}
263+
264+
if (r_apdu_len < 2) {
265+
// No status
266+
printf("\n");
267+
return;
268+
}
269+
270+
s = iso7816_sw1sw2_get_string(
271+
ptr[r_apdu_len - 2],
272+
ptr[r_apdu_len - 1],
273+
str,
274+
sizeof(str)
275+
);
276+
if (!s || !s[0]) {
277+
// No string or empty string
278+
printf("\n");
279+
return;
280+
}
281+
282+
printf(" (%s)\n", s);
283+
}
284+
249285
void print_sw1sw2(uint8_t SW1, uint8_t SW2)
250286
{
251287
char str[1024];
@@ -524,6 +560,11 @@ static void print_emv_debug_internal(
524560
print_atr(buf);
525561
return;
526562

563+
case EMV_DEBUG_TYPE_RAPDU:
564+
printf("%s: ", str);
565+
print_rapdu(buf, buf_len);
566+
return;
567+
527568
default:
528569
print_buf(str, buf, buf_len);
529570
return;

tools/print_helpers.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @file print_helpers.h
33
* @brief Helper functions for command line output
44
*
5-
* Copyright (c) 2021, 2022 Leon Lynch
5+
* Copyright (c) 2021-2022, 2024 Leon Lynch
66
*
77
* This library is free software; you can redistribute it and/or
88
* 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);
7171
*/
7272
void print_atr_historical_bytes(const struct iso7816_atr_info_t* atr_info);
7373

74+
/**
75+
* Print R-APDU
76+
* @param r_apdu Response Application Protocol Data Unit (C-APDU)
77+
* @param r_apdu_len Length of Response Application Protocol Data Unit (C-APDU). Must be at least 4 bytes.
78+
*/
79+
void print_rapdu(const void* r_apdu, size_t r_apdu_len);
80+
7481
/**
7582
* Print status bytes SW1-SW2
7683
* @param SW1 Status byte 1

0 commit comments

Comments
 (0)