From 45f93acf3d8d99ba6fbed12438392f37aadc785f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 13 Nov 2020 12:19:24 +0100 Subject: [PATCH] remove fprintf, fwrite in emv --- client/src/emv/cmdemv.c | 2 +- client/src/emv/emv_tags.c | 216 +++++++++++++++++++------------------- client/src/emv/emv_tags.h | 3 +- client/src/emv/emvcore.c | 2 +- 4 files changed, 113 insertions(+), 110 deletions(-) diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index 494956c51..3e0fec872 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -1153,7 +1153,7 @@ static int CmdEMVExec(const char *Cmd) { // 9F27: Cryptogram Information Data (CID) const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL); if (CID) { - emv_tag_dump(CID, stdout, 0); + emv_tag_dump(CID, 1); PrintAndLogEx(NORMAL, "------------------------------"); if (CID->len > 0) { switch (CID->value[0] & EMVAC_AC_MASK) { diff --git a/client/src/emv/emv_tags.c b/client/src/emv/emv_tags.c index 296dcdf82..661df0e5e 100644 --- a/client/src/emv/emv_tags.c +++ b/client/src/emv/emv_tags.c @@ -18,15 +18,10 @@ #endif #include "emv_tags.h" - #include #include - #include "commonutil.h" - -#ifndef PRINT_INDENT -# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} -#endif +#include "ui.h" enum emv_tag_t { EMV_TAG_GENERIC, @@ -455,19 +450,21 @@ static const char *bitstrings[] = { "1.......", }; -static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, int level) { const struct emv_tag_bit *bits = tag->data; unsigned bit, byte; for (byte = 1; byte <= tlv->len; byte ++) { unsigned char val = tlv->value[byte - 1]; - PRINT_INDENT(level); - fprintf(f, "\tByte %u (%02x)\n", byte, val); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Byte %u (%02x)", byte, val); for (bit = 8; bit > 0; bit--, val <<= 1) { if (val & 0x80) { - PRINT_INDENT(level); - fprintf(f, "\t\t%s - '%s'\n", bitstrings[bit - 1], - bits->bit == EMV_BIT(byte, bit) ? bits->name : "Unknown"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " %s - '%s'", + bitstrings[bit - 1], + (bits->bit == EMV_BIT(byte, bit)) ? bits->name : "Unknown" + ); } if (bits->bit == EMV_BIT(byte, bit)) bits ++; @@ -475,7 +472,7 @@ static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *ta } } -static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, int level) { const unsigned char *buf = tlv->value; size_t left = tlv->len; @@ -484,22 +481,20 @@ static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, F const struct emv_tag *doltag; if (!tlv_parse_tl(&buf, &left, &doltlv)) { - PRINT_INDENT(level); - fprintf(f, "Invalid Tag-Len\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, "Invalid Tag-Len"); continue; } doltag = emv_get_tag(&doltlv); - PRINT_INDENT(level); - fprintf(f, "\tTag %4x len %02zx ('%s')\n", doltlv.tag, doltlv.len, doltag->name); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Tag %4x len %02zx ('%s')", doltlv.tag, doltlv.len, doltag->name); } } -static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - fprintf(f, "\tString value '"); - fwrite(tlv->value, 1, tlv->len, f); - fprintf(f, "'\n"); +static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(NORMAL, " String value '%s'", sprint_hex_inrow(tlv->value, tlv->len)); } static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, unsigned end) { @@ -532,17 +527,18 @@ static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, un return ret; } -static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); - fprintf(f, "\tNumeric value %lu\n", emv_value_numeric(tlv, 0, tlv->len * 2)); +static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Numeric value %lu", emv_value_numeric(tlv, 0, tlv->len * 2)); } -static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); - fprintf(f, "\tDate: 20%02lu.%lu.%lu\n", +static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Date: 20%02lu.%lu.%lu", emv_value_numeric(tlv, 0, 2), emv_value_numeric(tlv, 2, 4), - emv_value_numeric(tlv, 4, 6)); + emv_value_numeric(tlv, 4, 6) + ); } static uint32_t emv_get_binary(const unsigned char *S) { @@ -550,44 +546,44 @@ static uint32_t emv_get_binary(const unsigned char *S) { } // https://github.com/binaryfoo/emv-bertlv/blob/master/src/main/resources/fields/visa-cvr.txt -static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - if (!tlv || tlv->len < 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); +static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, int level) { + if (tlv == NULL || tlv->len < 1) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID length!"); return; } if (tlv->len != tlv->value[0] + 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID length!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID length!"); return; } if (tlv->len >= 2) { // AC1 - PRINT_INDENT(level); - if ((tlv->value[1] & 0xC0) == 0x00) fprintf(f, "\tAC1: AAC (Transaction declined)\n"); - if ((tlv->value[1] & 0xC0) == 0x40) fprintf(f, "\tAC1: TC (Transaction approved)\n"); - if ((tlv->value[1] & 0xC0) == 0x80) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n"); - if ((tlv->value[1] & 0xC0) == 0xC0) fprintf(f, "\tAC1: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + if ((tlv->value[1] & 0xC0) == 0x00) PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)"); + if ((tlv->value[1] & 0xC0) == 0x40) PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)"); + if ((tlv->value[1] & 0xC0) == 0x80) PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)"); + if ((tlv->value[1] & 0xC0) == 0xC0) PrintAndLogEx(NORMAL, " AC1: RFU"); // AC2 - PRINT_INDENT(level); - if ((tlv->value[1] & 0x30) == 0x00) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); - if ((tlv->value[1] & 0x30) == 0x10) fprintf(f, "\tAC2: TC (Transaction approved)\n"); - if ((tlv->value[1] & 0x30) == 0x20) fprintf(f, "\tAC2: not requested (ARQC)\n"); - if ((tlv->value[1] & 0x30) == 0x30) fprintf(f, "\tAC2: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + if ((tlv->value[1] & 0x30) == 0x00) PrintAndLogEx(NORMAL, " AC2: AAC (Transaction declined)"); + if ((tlv->value[1] & 0x30) == 0x10) PrintAndLogEx(NORMAL, " AC2: TC (Transaction approved)"); + if ((tlv->value[1] & 0x30) == 0x20) PrintAndLogEx(NORMAL, " AC2: not requested (ARQC)"); + if ((tlv->value[1] & 0x30) == 0x30) PrintAndLogEx(NORMAL, " AC2: RFU"); } if (tlv->len >= 3 && (tlv->value[2] >> 4)) { - PRINT_INDENT(level); - fprintf(f, "\tPIN try: %x\n", tlv->value[2] >> 4); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " PIN try: %x", tlv->value[2] >> 4); } if (tlv->len >= 4 && (tlv->value[3] & 0x0F)) { - PRINT_INDENT(level); - fprintf(f, "\tIssuer discretionary bits: %x\n", tlv->value[3] & 0x0F); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Issuer discretionary bits: %x", tlv->value[3] & 0x0F); } if (tlv->len >= 5 && (tlv->value[4] >> 4)) { - PRINT_INDENT(level); - fprintf(f, "\tSuccessfully processed issuer script commands: %x\n", tlv->value[4] >> 4); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Successfully processed issuer script commands: %x", tlv->value[4] >> 4); } // mask 0F 0F F0 0F @@ -610,68 +606,73 @@ static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, F }; if (data[0] || data[1] || data[2] || data[3]) - emv_tag_dump_bitmask(&bit_tlv, &bit_tag, f, level); + emv_tag_dump_bitmask(&bit_tlv, &bit_tag, level); } // EMV Book 3 -static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - if (!tlv || tlv->len < 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); +static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, int level) { + if (tlv == NULL || tlv->len < 1) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } - PRINT_INDENT(level); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC) fprintf(f, "\tAC1: AAC (Transaction declined)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC) fprintf(f, "\tAC1: TC (Transaction approved)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK) fprintf(f, "\tAC1: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC) + PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC) + PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC) + PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK) + PrintAndLogEx(NORMAL, " AC1: RFU"); if (tlv->value[0] & EMVCID_ADVICE) { - PRINT_INDENT(level); - fprintf(f, "\tAdvice required!\n"); + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Advice required!"); } if (tlv->value[0] & EMVCID_REASON_MASK) { - PRINT_INDENT(level); - fprintf(f, "\tReason/advice/referral code: "); + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Reason/advice/referral code: " NOLF); switch ((tlv->value[0] & EMVCID_REASON_MASK)) { case 0: - fprintf(f, "No information given\n"); + PrintAndLogEx(NORMAL, "No information given"); break; case 1: - fprintf(f, "Service not allowed\n"); + PrintAndLogEx(NORMAL, "Service not allowed"); break; case 2: - fprintf(f, "PIN Try Limit exceeded\n"); + PrintAndLogEx(NORMAL, "PIN Try Limit exceeded"); break; case 3: - fprintf(f, "Issuer authentication failed\n"); + PrintAndLogEx(NORMAL, "Issuer authentication failed"); break; default: - fprintf(f, "\tRFU: %2x\n", (tlv->value[0] & EMVCID_REASON_MASK)); + PrintAndLogEx(NORMAL, " RFU: %2x", (tlv->value[0] & EMVCID_REASON_MASK)); break; } } } -static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, int level) { uint32_t X, Y; int i; if (tlv->len < 10 || tlv->len % 2) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } X = emv_get_binary(tlv->value); Y = emv_get_binary(tlv->value + 4); - PRINT_INDENT(level); - fprintf(f, "\tX: %u\n", X); - PRINT_INDENT(level); - fprintf(f, "\tY: %u\n", Y); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " X: %u", X); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Y: %u", Y); for (i = 8; i < tlv->len; i += 2) { const char *method; @@ -746,73 +747,76 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t break; } - PRINT_INDENT(level); - fprintf(f, "\t%02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful\n", - tlv->value[i], tlv->value[i + 1], - method, condition, (tlv->value[i] & 0x40) ? "continue" : "fail"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " %02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful", + tlv->value[i], + tlv->value[i + 1], + method, + condition, + (tlv->value[i] & 0x40) ? "continue" : "fail" + ); } } -static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, int level) { if (tlv->len < 4 || tlv->len % 4) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } for (int i = 0; i < tlv->len / 4; i++) { - PRINT_INDENT(level); - fprintf(f, "SFI[%02x] start:%02x end:%02x offline:%02x\n", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, "SFI[%02x] start:%02x end:%02x offline:%02x", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]); } } -bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) { - if (!tlv) { - fprintf(f, "NULL\n"); +bool emv_tag_dump(const struct tlv *tlv, int level) { + if (tlv == NULL) { + PrintAndLogEx(FAILED, "NULL"); return false; } const struct emv_tag *tag = emv_get_tag(tlv); - PRINT_INDENT(level); - fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name); + PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name); switch (tag->type) { case EMV_TAG_GENERIC: - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); break; case EMV_TAG_BITMASK: - fprintf(f, "\n"); - emv_tag_dump_bitmask(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_bitmask(tlv, tag, level); break; case EMV_TAG_DOL: - fprintf(f, "\n"); - emv_tag_dump_dol(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_dol(tlv, tag, level); break; case EMV_TAG_CVM_LIST: - fprintf(f, "\n"); - emv_tag_dump_cvm_list(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cvm_list(tlv, tag, level); break; case EMV_TAG_AFL: - fprintf(f, "\n"); - emv_tag_dump_afl(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_afl(tlv, tag, level); break; case EMV_TAG_STRING: - emv_tag_dump_string(tlv, tag, f, level); + emv_tag_dump_string(tlv, tag, level); break; case EMV_TAG_NUMERIC: - emv_tag_dump_numeric(tlv, tag, f, level); + emv_tag_dump_numeric(tlv, tag, level); break; case EMV_TAG_YYMMDD: - emv_tag_dump_yymmdd(tlv, tag, f, level); + emv_tag_dump_yymmdd(tlv, tag, level); break; case EMV_TAG_CVR: - fprintf(f, "\n"); - emv_tag_dump_cvr(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cvr(tlv, tag, level); break; case EMV_TAG_CID: - fprintf(f, "\n"); - emv_tag_dump_cid(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cid(tlv, tag, level); break; }; diff --git a/client/src/emv/emv_tags.h b/client/src/emv/emv_tags.h index 235048b20..2da2cd2ef 100644 --- a/client/src/emv/emv_tags.h +++ b/client/src/emv/emv_tags.h @@ -17,7 +17,6 @@ #define TAGS_H #include "tlv.h" -#include // FILE // AC # define EMVAC_AC_MASK 0xC0 @@ -34,7 +33,7 @@ # define EMVCID_ADVICE 0x08 # define EMVCID_REASON_MASK 0x07 -bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level); +bool emv_tag_dump(const struct tlv *tlv, int level); const char *emv_get_tag_name(const struct tlv *tlv); #endif diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index ecbb7c4f9..38347b7e0 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -157,7 +157,7 @@ enum CardPSVendor GetCardPSVendor(uint8_t *AID, size_t AIDlen) { } static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { - emv_tag_dump(tlv, stdout, level); + emv_tag_dump(tlv, level); if (is_leaf) { print_buffer(tlv->value, tlv->len, level); }