From 5dffe7b022fd48104f4658c319db660e8931d264 Mon Sep 17 00:00:00 2001 From: merlokk Date: Tue, 9 Oct 2018 19:27:43 +0300 Subject: [PATCH] added finalization logic to `emv scan` and option to remove hash checking in key recovery --- client/emv/cmdemv.c | 20 ++++++++++++++++++-- client/emv/emv_pki.c | 14 +++++++++++--- client/emv/emv_pki.h | 2 ++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index b6a7e310..d886834d 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -12,6 +12,7 @@ #include "mifare.h" #include "cmdemv.h" #include "emvjson.h" +#include "emv_pki.h" #include "test/cryptotest.h" #include "cliparser/cliparser.h" #include @@ -1148,7 +1149,7 @@ int CmdHFEMVScan(const char *cmd) { root = json_object(); } - // drop field + // drop field at start DropField(); // iso 14443 select @@ -1202,6 +1203,7 @@ int CmdHFEMVScan(const char *cmd) { if (EMVSearch(false, true, decodeTLV, tlvSelect)) { PrintAndLog("E->Can't found any of EMV AID. Exit..."); tlvdb_free(tlvSelect); + DropField(); return 3; } @@ -1217,6 +1219,7 @@ int CmdHFEMVScan(const char *cmd) { if (!AIDlen) { PrintAndLog("Can't select AID. EMV AID not found. Exit..."); + DropField(); return 4; } @@ -1234,6 +1237,8 @@ int CmdHFEMVScan(const char *cmd) { if (res) { PrintAndLog("E->Can't select AID (%d). Exit...", res); + tlvdb_free(tlvRoot); + DropField(); return 5; } @@ -1260,6 +1265,8 @@ int CmdHFEMVScan(const char *cmd) { struct tlv *pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83); if (!pdol_data_tlv){ PrintAndLog("E->Can't create PDOL TLV."); + tlvdb_free(tlvRoot); + DropField(); return 6; } @@ -1267,6 +1274,8 @@ int CmdHFEMVScan(const char *cmd) { unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len); if (!pdol_data_tlv_data) { PrintAndLog("E->Can't create PDOL data."); + tlvdb_free(tlvRoot); + DropField(); return 6; } PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len)); @@ -1279,6 +1288,8 @@ int CmdHFEMVScan(const char *cmd) { if (res) { PrintAndLog("GPO error(%d): %4x. Exit...", res, sw); + tlvdb_free(tlvRoot); + DropField(); return 7; } ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV); @@ -1362,9 +1373,14 @@ int CmdHFEMVScan(const char *cmd) { // getting certificates if (tlvdb_get(tlvRoot, 0x90, NULL)) { PrintAndLog("-->Recovering certificates."); + PKISetStrictExecution(false); RecoveryCertificates(tlvRoot, root); + PKISetStrictExecution(true); } + // free tlv object + tlvdb_free(tlvRoot); + // DropField DropField(); @@ -1375,7 +1391,7 @@ int CmdHFEMVScan(const char *cmd) { } PrintAndLog("File `%s` saved.", fname); - // free json + // free json object json_decref(root); return 0; diff --git a/client/emv/emv_pki.c b/client/emv/emv_pki.c index f79e3045..da102291 100644 --- a/client/emv/emv_pki.c +++ b/client/emv/emv_pki.c @@ -27,6 +27,11 @@ #include #include +static bool strictExecution = true; +void PKISetStrictExecution(bool se) { + strictExecution = se; +} + static const unsigned char empty_tlv_value[] = {}; static const struct tlv empty_tlv = {.tag = 0x0, .len = 0, .value = empty_tlv_value}; @@ -108,9 +113,12 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, printf("ERROR: Calculated wrong hash\n"); printf("decoded: %s\n",sprint_hex(data + data_len - 1 - hash_len, hash_len)); printf("calculated: %s\n",sprint_hex(crypto_hash_read(ch), hash_len)); - crypto_hash_close(ch); - free(data); - return NULL; + + if (strictExecution) { + crypto_hash_close(ch); + free(data); + return NULL; + } } crypto_hash_close(ch); diff --git a/client/emv/emv_pki.h b/client/emv/emv_pki.h index e37e3c7d..6fa7b12e 100644 --- a/client/emv/emv_pki.h +++ b/client/emv/emv_pki.h @@ -21,6 +21,8 @@ #include +extern void PKISetStrictExecution(bool se); + struct emv_pk *emv_pki_recover_issuer_cert(const struct emv_pk *pk, struct tlvdb *db); struct emv_pk *emv_pki_recover_icc_cert(const struct emv_pk *pk, struct tlvdb *db, const struct tlv *sda_tlv); struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb *db);