Merge branch 'master' into experimental_varlen

* master: (27 commits)
  textual
  style redundant assignment
  timeout fix
  small fix
  add termcap
  add readline and small fix
  rdp
  textual
  null term?
  fix: https://github.com/RfidResearchGroup/proxmark3/issues/166
  add dlls to release
  style
  style
  test fix
  test fixes
  another fix
  fix memleak
  fix
  textual
  use printandlogex
  ...
This commit is contained in:
Philippe Teuwen
2019-04-17 22:06:39 +02:00
20 changed files with 519 additions and 534 deletions

View File

@@ -46,7 +46,7 @@ static void ParamLoadDefaults(struct tlvdb *tlvRoot) {
static void PrintChannel(EMVCommandChannel channel) {
switch (channel) {
case ECC_CONTACTLESS:
PrintAndLogEx(INFO, "Channel: CONTACTLESS");
PrintAndLogEx(INFO, "Channel: CONTACTLESS (T=CL)");
break;
case ECC_CONTACT:
PrintAndLogEx(INFO, "Channel: CONTACT");
@@ -203,7 +203,6 @@ static int CmdEMVPPSE(const char *Cmd) {
if (res)
return res;
if (decodeTLV)
TLVPrintFromBuffer(buf, len);
@@ -288,6 +287,7 @@ static int CmdEMVGPO(const char *Cmd) {
PrintAndLogEx(ERR, "Can't create PDOL data.");
tlvdb_free(tmp_ext);
tlvdb_free(tlvRoot);
if (pdol_data_tlv != &data_tlv);
free(pdol_data_tlv);
return 4;
}
@@ -410,7 +410,7 @@ static int CmdEMVAC(const char *Cmd) {
termDecision = EMVAC_ARQC;
if (termDecision == 0xff) {
PrintAndLog("ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval[0]);
PrintAndLogEx(ERR, "ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval[0]);
return 1;
}
} else {
@@ -647,7 +647,7 @@ static void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON,
ParamLoadDefaults(tlvRoot);
if (paramLoadJSON) {
PrintAndLog("* * Transaction parameters loading from JSON...");
PrintAndLogEx(INFO, "* * Transaction parameters loading from JSON...");
ParamLoadFromJson(tlvRoot);
}
@@ -678,12 +678,12 @@ static void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON,
static void ProcessGPOResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, bool decodeTLV) {
if (buf[0] == 0x80) {
if (decodeTLV) {
PrintAndLog("GPO response format1:");
PrintAndLogEx(SUCCESS, "GPO response format1:");
TLVPrintFromBuffer(buf, len);
}
if (len < 4 || (len - 4) % 4) {
PrintAndLogEx(ERR, "GPO response format1 parsing error. length=%d", len);
PrintAndLogEx(ERR, "GPO response format 1 parsing error. length = %d", len);
} else {
// AIP
struct tlvdb *f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
@@ -708,7 +708,7 @@ static void ProcessGPOResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_
static void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, bool decodeTLV) {
if (buf[0] == 0x80) {
if (decodeTLV) {
PrintAndLog("GPO response format1:");
PrintAndLogEx(SUCCESS, "GPO response format 1:");
TLVPrintFromBuffer(buf, len);
}
@@ -719,7 +719,7 @@ static void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t
} else {
struct tlvdb *tlvElm = NULL;
if (decodeTLV)
PrintAndLog("\n------------ Format1 decoded ------------");
PrintAndLogEx(NORMAL, "\n------------ Format1 decoded ------------");
// CID (Cryptogram Information Data)
tlvdb_change_or_add_node_ex(tlvRoot, 0x9f27, 1, &buf[2], &tlvElm);
@@ -873,23 +873,23 @@ static int CmdEMVExec(const char *Cmd) {
if (decodeTLV)
TLVPrintFromBuffer(buf, len);
PrintAndLog("* Selected.");
PrintAndLogEx(NORMAL, "* Selected.");
PrintAndLog("\n* Init transaction parameters.");
PrintAndLogEx(NORMAL, "\n* Init transaction parameters.");
InitTransactionParameters(tlvRoot, paramLoadJSON, TrType, GenACGPO);
TLVPrintFromTLV(tlvRoot); // TODO delete!!!
PrintAndLogEx(NORMAL, "\n* Calc PDOL.");
pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
if (!pdol_data_tlv) {
PrintAndLogEx(WARNING, "Error: can't create PDOL TLV.");
PrintAndLogEx(ERR, "Error: can't create PDOL TLV.");
dreturn(4);
}
size_t pdol_data_tlv_data_len;
unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
if (!pdol_data_tlv_data) {
PrintAndLogEx(WARNING, "Error: can't create PDOL data.");
PrintAndLogEx(ERR, "Error: can't create PDOL data.");
dreturn(4);
}
PrintAndLogEx(NORMAL, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
@@ -901,7 +901,7 @@ static int CmdEMVExec(const char *Cmd) {
//free(pdol_data_tlv); --- free on exit.
if (res) {
PrintAndLogEx(NORMAL, "GPO error(%d): %4x. Exit...", res, sw);
PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw);
dreturn(5);
}
@@ -919,7 +919,7 @@ static int CmdEMVExec(const char *Cmd) {
const struct tlv *pantlv = tlvdb_get(tlvRoot, 0x5a, NULL);
PrintAndLogEx(NORMAL, "\n* * Extracted PAN from track2: %s", sprint_hex(pantlv->value, pantlv->len));
} else {
PrintAndLogEx(NORMAL, "\n* * WARNING: Can't extract PAN from track2.");
PrintAndLogEx(WARNING, "\n* * WARNING: Can't extract PAN from track2.");
}
}
}
@@ -928,7 +928,7 @@ static int CmdEMVExec(const char *Cmd) {
const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
if (!AFL || !AFL->len)
PrintAndLogEx(NORMAL, "WARNING: AFL not found.");
PrintAndLogEx(WARNING, "WARNING: AFL not found.");
while (AFL && AFL->len) {
if (AFL->len % 4) {
@@ -1066,11 +1066,11 @@ static int CmdEMVExec(const char *Cmd) {
PrintAndLogEx(NORMAL, "* * Generate challenge");
res = EMVGenerateChallenge(channel, true, buf, sizeof(buf), &len, &sw, tlvRoot);
if (res) {
PrintAndLogEx(WARNING, "Error GetChallenge. APDU error %4x", sw);
PrintAndLogEx(ERR, "Error GetChallenge. APDU error %4x", sw);
dreturn(6);
}
if (len < 4) {
PrintAndLogEx(WARNING, "Error GetChallenge. Wrong challenge length %d", len);
PrintAndLogEx(ERR, "Error GetChallenge. Wrong challenge length %d", len);
dreturn(6);
}
@@ -1085,7 +1085,7 @@ static int CmdEMVExec(const char *Cmd) {
PrintAndLogEx(NORMAL, "* * Calc CDOL1");
struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
if (!cdol_data_tlv) {
PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV.");
PrintAndLogEx(ERR, "Error: can't create CDOL1 TLV.");
dreturn(6);
}
@@ -1096,7 +1096,7 @@ static int CmdEMVExec(const char *Cmd) {
res = EMVAC(channel, true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
if (res) {
PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw);
PrintAndLogEx(ERR, "AC1 error(%d): %4x. Exit...", res, sw);
dreturn(7);
}
@@ -1175,7 +1175,7 @@ static int CmdEMVExec(const char *Cmd) {
struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag
if (!udol_data_tlv) {
PrintAndLogEx(WARNING, "Error: can't create UDOL TLV.");
PrintAndLogEx(ERR, "Error: can't create UDOL TLV.");
dreturn(8);
}
@@ -1185,7 +1185,7 @@ static int CmdEMVExec(const char *Cmd) {
res = MSCComputeCryptoChecksum(channel, true, (uint8_t *)udol_data_tlv->value, udol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
if (res) {
PrintAndLogEx(WARNING, "Error Compute Crypto Checksum. APDU error %4x", sw);
PrintAndLogEx(ERR, "Error Compute Crypto Checksum. APDU error %4x", sw);
free(udol_data_tlv);
dreturn(9);
}
@@ -1198,7 +1198,7 @@ static int CmdEMVExec(const char *Cmd) {
}
} else {
PrintAndLogEx(WARNING, "Error MSD: Track2 data not found.");
PrintAndLogEx(ERR, "Error MSD: Track2 data not found.");
}
}
@@ -1209,7 +1209,7 @@ static int CmdEMVExec(const char *Cmd) {
PrintAndLogEx(NORMAL, "* * Calc CDOL1");
struct tlv *cdol1_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
if (!cdol1_data_tlv) {
PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV.");
PrintAndLogEx(ERR, "Error: can't create CDOL1 TLV.");
dreturn(6);
}
@@ -1220,7 +1220,7 @@ static int CmdEMVExec(const char *Cmd) {
res = EMVAC(channel, true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol1_data_tlv->value, cdol1_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
if (res) {
PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw);
PrintAndLogEx(ERR, "AC1 error(%d): %4x. Exit...", res, sw);
free(cdol1_data_tlv);
dreturn(7);
}
@@ -1232,7 +1232,7 @@ static int CmdEMVExec(const char *Cmd) {
tlvdb_get_uint8(tlvRoot, 0x9f27, &CID);
// AC1 print result
PrintAndLog("");
PrintAndLogEx(NORMAL, "");
if ((CID & EMVAC_AC_MASK) == EMVAC_AAC) PrintAndLogEx(INFO, "AC1 result: AAC (Transaction declined)");
if ((CID & EMVAC_AC_MASK) == EMVAC_TC) PrintAndLogEx(INFO, "AC1 result: TC (Transaction approved)");
if ((CID & EMVAC_AC_MASK) == EMVAC_ARQC) PrintAndLogEx(INFO, "AC1 result: ARQC (Online authorisation requested)");
@@ -1264,13 +1264,13 @@ static int CmdEMVExec(const char *Cmd) {
PrintAndLogEx(NORMAL, "CVR length: %d", CVRlen);
PrintAndLogEx(NORMAL, "CVR: %s", sprint_hex(&IAD->value[4], CVRlen));
} else {
PrintAndLogEx(NORMAL, "Wrong CVR length! CVR: %s", sprint_hex(&IAD->value[3], VDDlen - 2));
PrintAndLogEx(WARNING, "Wrong CVR length! CVR: %s", sprint_hex(&IAD->value[3], VDDlen - 2));
}
}
if (IDDlen)
PrintAndLogEx(NORMAL, "IDD: %s", sprint_hex(&IAD->value[VDDlen + 1], IDDlen));
} else {
PrintAndLogEx(NORMAL, "Issuer Application Data (IAD) not found.");
PrintAndLogEx(WARNING, "Issuer Application Data (IAD) not found.");
}
PrintAndLogEx(NORMAL, "\n* * Processing online request");
@@ -1278,7 +1278,9 @@ static int CmdEMVExec(const char *Cmd) {
// authorization response code from acquirer
const char HostResponse[] = "00"; // 0x3030
size_t HostResponseLen = sizeof(HostResponse) - 1;
PrintAndLogEx(NORMAL, "Host Response: `%s`", HostResponse);
tlvdb_change_or_add_node(tlvRoot, 0x8a, HostResponseLen, (const unsigned char *)HostResponse);
if (CryptoVersion == 10) {
@@ -1300,30 +1302,23 @@ static int CmdEMVExec(const char *Cmd) {
PrintAndLogEx(NORMAL, "ARPC: n/a");
} else {
PrintAndLogEx(NORMAL, "Application Cryptogram (AC) not found.");
PrintAndLogEx(WARNING, "Application Cryptogram (AC) not found.");
}
// here must be external authenticate, but we dont know ARPC
}
// needs to send AC2 command (res == ARQC)
if ((CID & EMVAC_AC_MASK) == EMVAC_ARQC) {
PrintAndLogEx(NORMAL, "\n* * Calc CDOL2");
struct tlv *cdol2_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8d, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
if (!cdol2_data_tlv) {
PrintAndLogEx(WARNING, "Error: can't create CDOL2 TLV.");
PrintAndLogEx(ERR, "Error: can't create CDOL2 TLV.");
dreturn(6);
}
PrintAndLogEx(NORMAL, "CDOL2 data[%d]: %s", cdol2_data_tlv->len, sprint_hex(cdol2_data_tlv->value, cdol2_data_tlv->len));
//PrintAndLogEx(NORMAL, "* * AC2");
// here must be AC2, but we dont make external authenticate (
/* // AC2
PRINT_INDENT(level);
if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n");
@@ -1332,7 +1327,6 @@ static int CmdEMVExec(const char *Cmd) {
if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n");
*/
}
}
DropFieldEx(channel);
@@ -1409,7 +1403,7 @@ static int CmdEMVScan(const char *Cmd) {
#ifndef WITH_SMARTCARD
// not compiled with smartcard functionality, we need to exit
if (channel == ECC_CONTACT) {
PrintAndLogEx(WARNING, "PM3 Client is not compiled with support for SMARTCARD. Exiting.");
PrintAndLogEx(ERR, "PM3 Client is not compiled with support for SMARTCARD. Exiting.");
return 0;
}
#endif
@@ -1652,7 +1646,7 @@ static int CmdEMVScan(const char *Cmd) {
if (decodeTLV) {
TLVPrintFromBuffer(buf, len);
PrintAndLog("");
PrintAndLogEx(NORMAL, "");
}
json_t *jsonelm = json_object();
@@ -1692,7 +1686,7 @@ static int CmdEMVScan(const char *Cmd) {
PrintAndLogEx(ERR, "Can't save the file: %s", fname);
return 200;
}
PrintAndLogEx(SUCCESS, "File `%s` saved.", fname);
PrintAndLogEx(SUCCESS, "File " _YELLOW_("`%s`") " saved.", fname);
// free json object
json_decref(root);
@@ -1807,7 +1801,7 @@ static int CmdEMVRoca(const char *Cmd) {
return 5;
}
PrintAndLog("\n* Init transaction parameters.");
PrintAndLogEx(NORMAL, "\n* Init transaction parameters.");
InitTransactionParameters(tlvRoot, true, TT_QVSDCMCHIP, false);
PrintAndLogEx(NORMAL, "-->Calc PDOL.");

View File

@@ -253,20 +253,29 @@ static size_t crypto_pk_polarssl_get_nbits(const struct crypto_pk *_cp) {
static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_cp, unsigned param, size_t *plen) {
struct crypto_pk_polarssl *cp = (struct crypto_pk_polarssl *)_cp;
unsigned char *result = NULL;
int res;
switch (param) {
// mod
case 0:
*plen = mbedtls_mpi_size(&cp->ctx.N);
result = malloc(*plen);
memset(result, 0x00, *plen);
mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen);
res = mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen);
if (res < 0) {
printf("Error write_binary.");
result = 0;
}
break;
// exp
case 1:
*plen = mbedtls_mpi_size(&cp->ctx.E);
result = malloc(*plen);
memset(result, 0x00, *plen);
mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen);
res = mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen);
if (res < 0) {
printf("Error write_binary.");
result = 0;
}
break;
default:
printf("Error get parameter. Param = %u", param);

View File

@@ -152,10 +152,10 @@ int roca_self_test(void) {
if (emv_rocacheck(keyp, 64, false)) {
PrintAndLogEx(SUCCESS, "Weak modulus [ %s]", _GREEN_("PASS"));
PrintAndLogEx(SUCCESS, "Weak modulus [ %s]", _GREEN_("PASS"));
} else {
ret++;
PrintAndLogEx(FAILED, "Weak modulus [ %s]", _RED_("Fail"));
PrintAndLogEx(FAILED, "Weak modulus [ %s]", _RED_("Fail"));
}
// negative

View File

@@ -75,7 +75,7 @@ int JsonSaveJsonObject(json_t *root, const char *path, json_t *value) {
if (path[0] == '$') {
if (json_path_set(root, path, value, 0, &error)) {
PrintAndLog("ERROR: can't set json path: ", error.text);
PrintAndLogEx(ERR, "ERROR: can't set json path: ", error.text);
return 2;
} else {
return 0;
@@ -151,12 +151,12 @@ int JsonSaveTLVElm(json_t *elm, const char *path, struct tlv *tlvelm, bool saveN
if (json_is_array(elm)) {
if (json_array_append_new(elm, obj)) {
PrintAndLog("ERROR: can't append array: %s", path);
PrintAndLogEx(ERR, "ERROR: can't append array: %s", path);
return 2;
}
} else {
if (json_path_set(elm, path, obj, 0, &error)) {
PrintAndLog("ERROR: can't set json path: ", error.text);
PrintAndLogEx(ERR, "ERROR: can't set json path: ", error.text);
return 2;
}
}
@@ -225,7 +225,7 @@ int JsonSaveTLVTree(json_t *root, json_t *elm, const char *path, struct tlvdb *t
// check
if (!json_is_array(chjson)) {
PrintAndLog("E->Internal logic error. `$.Childs` is not an array.");
PrintAndLogEx(ERR, "E->Internal logic error. `$.Childs` is not an array.");
break;
}
@@ -243,18 +243,18 @@ static bool HexToBuffer(const char *errormsg, const char *hexvalue, uint8_t *buf
switch (param_gethex_to_eol(hexvalue, 0, buffer, maxbufferlen, &buflen)) {
case 1:
PrintAndLog("%s Invalid HEX value.", errormsg);
PrintAndLogEx(ERR, "%s Invalid HEX value.", errormsg);
return false;
case 2:
PrintAndLog("%s Hex value too large.", errormsg);
PrintAndLogEx(ERR, "%s Hex value too large.", errormsg);
return false;
case 3:
PrintAndLog("%s Hex value must have even number of digits.", errormsg);
PrintAndLogEx(ERR, "%s Hex value must have even number of digits.", errormsg);
return false;
}
if (buflen > maxbufferlen) {
PrintAndLog("%s HEX length (%d) more than %d", errormsg, (bufferlen) ? *bufferlen : -1, maxbufferlen);
PrintAndLogEx(ERR, "%s HEX length (%d) more than %d", errormsg, (bufferlen) ? *bufferlen : -1, maxbufferlen);
return false;
}
@@ -300,7 +300,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
json_error_t error;
if (!tlv) {
PrintAndLog("ERROR load params: tlv tree is NULL.");
PrintAndLogEx(ERR, "ERROR load params: tlv tree is NULL.");
return false;
}
@@ -312,30 +312,30 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
root = json_load_file(fname, 0, &error);
if (!root) {
PrintAndLog("Load params: json error on line %d: %s", error.line, error.text);
PrintAndLogEx(ERR, "Load params: json error on line " _YELLOW_("%d") ": %s", error.line, error.text);
return false;
}
if (!json_is_array(root)) {
PrintAndLog("Load params: Invalid json format. root must be array.");
PrintAndLogEx(ERR, "Load params: Invalid json format. root must be array.");
return false;
}
PrintAndLog("Load params: json(%d) OK", json_array_size(root));
PrintAndLogEx(SUCCESS, "Load params: json(%d) " _GREEN_("OK"), json_array_size(root));
for (int i = 0; i < json_array_size(root); i++) {
json_t *data, *jtag, *jlength, *jvalue;
data = json_array_get(root, i);
if (!json_is_object(data)) {
PrintAndLog("Load params: data [%d] is not an object", i + 1);
PrintAndLogEx(ERR, "Load params: data [%d] is not an object", i + 1);
json_decref(root);
return false;
}
jtag = json_object_get(data, "tag");
if (!json_is_string(jtag)) {
PrintAndLog("Load params: data [%d] tag is not a string", i + 1);
PrintAndLogEx(ERR, "Load params: data [%d] tag is not a string", i + 1);
json_decref(root);
return false;
}
@@ -343,7 +343,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
jvalue = json_object_get(data, "value");
if (!json_is_string(jvalue)) {
PrintAndLog("Load params: data [%d] value is not a string", i + 1);
PrintAndLogEx(ERR, "Load params: data [%d] value is not a string", i + 1);
json_decref(root);
return false;
}
@@ -351,19 +351,19 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
jlength = json_object_get(data, "length");
if (!json_is_number(jlength)) {
PrintAndLog("Load params: data [%d] length is not a number", i + 1);
PrintAndLogEx(ERR, "Load params: data [%d] length is not a number", i + 1);
json_decref(root);
return false;
}
int tlvLength = json_integer_value(jlength);
if (tlvLength > 250) {
PrintAndLog("Load params: data [%d] length more than 250", i + 1);
PrintAndLogEx(ERR, "Load params: data [%d] length more than 250", i + 1);
json_decref(root);
return false;
}
PrintAndLog("TLV param: %s[%d]=%s", tlvTag, tlvLength, tlvValue);
PrintAndLogEx(SUCCESS, "TLV param: %s[%d]=%s", tlvTag, tlvLength, tlvValue);
uint8_t buf[251] = {0};
size_t buflen = 0;
@@ -382,7 +382,7 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
}
if (buflen != tlvLength) {
PrintAndLog("Load params: data [%d] length of HEX must(%d) be identical to length in TLV param(%d)", i + 1, buflen, tlvLength);
PrintAndLogEx(ERR, "Load params: data [%d] length of HEX must(%d) be identical to length in TLV param(%d)", i + 1, buflen, tlvLength);
json_decref(root);
return false;
}