coverity fix, textual, style

This commit is contained in:
iceman1001 2021-06-22 10:43:48 +02:00
commit 0d2cd089c0
2 changed files with 162 additions and 138 deletions

View file

@ -18,23 +18,30 @@
#include "cmdhf14a.h" #include "cmdhf14a.h"
#include "emv/emvcore.h" #include "emv/emvcore.h"
#include "emv/emvjson.h" #include "emv/emvjson.h"
#include "iso7816/apduinfo.h"
#include "ui.h" #include "ui.h"
#include "util.h" #include "util.h"
// context for secure channel // context for secure channel
CipurseContext cipurseContext; CipurseContext cipurseContext;
static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint16_t Le, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { static int CIPURSEExchangeEx(bool activate_field, bool leave_field_on, sAPDU apdu, bool include_le,
uint16_t le, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
uint8_t data[APDU_RES_LEN] = {0}; uint8_t data[APDU_RES_LEN] = {0};
uint8_t securedata[APDU_RES_LEN] = {0}; uint8_t securedata[APDU_RES_LEN] = {0};
sAPDU secapdu; sAPDU secapdu;
*ResultLen = 0; if (result_len) {
if (sw) *sw = 0; *result_len = 0;
}
if (sw) {
*sw = 0;
}
uint16_t isw = 0; uint16_t isw = 0;
int res = 0; int res = 0;
if (ActivateField) { if (activate_field) {
DropField(); DropField();
msleep(50); msleep(50);
} }
@ -45,11 +52,11 @@ static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu,
// COMPUTE APDU // COMPUTE APDU
int datalen = 0; int datalen = 0;
uint16_t xle = IncludeLe ? 0x100 : 0x00; uint16_t xle = include_le ? 0x100 : 0x00;
if (xle == 0x100 && Le != 0) if (xle == 0x100 && le != 0)
xle = Le; xle = le;
CipurseCAPDUReqEncode(&cipurseContext, &apdu, &secapdu, securedata, IncludeLe, Le); CipurseCAPDUReqEncode(&cipurseContext, &apdu, &secapdu, securedata, include_le, le);
if (APDUEncodeS(&secapdu, false, xle, data, &datalen)) { if (APDUEncodeS(&secapdu, false, xle, data, &datalen)) {
PrintAndLogEx(ERR, "APDU encoding error."); PrintAndLogEx(ERR, "APDU encoding error.");
@ -59,34 +66,36 @@ static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu,
if (GetAPDULogging()) if (GetAPDULogging())
PrintAndLogEx(SUCCESS, ">>>> %s", sprint_hex(data, datalen)); PrintAndLogEx(SUCCESS, ">>>> %s", sprint_hex(data, datalen));
res = ExchangeAPDU14a(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen); res = ExchangeAPDU14a(data, datalen, activate_field, leave_field_on, result, (int)max_result_len, (int *)result_len);
if (res) { if (res) {
return res; return res;
} }
if (GetAPDULogging()) if (GetAPDULogging())
PrintAndLogEx(SUCCESS, "<<<< %s", sprint_hex(Result, *ResultLen)); PrintAndLogEx(SUCCESS, "<<<< %s", sprint_hex(result, *result_len));
if (*ResultLen < 2) { if (*result_len < 2) {
return 200; return 200;
} }
size_t rlen = 0; size_t rlen = 0;
if (*ResultLen == 2) { if (*result_len == 2) {
if (cipurseContext.RequestSecurity == CPSMACed || cipurseContext.RequestSecurity == CPSEncrypted) if (cipurseContext.RequestSecurity == CPSMACed || cipurseContext.RequestSecurity == CPSEncrypted)
CipurseCClearContext(&cipurseContext); CipurseCClearContext(&cipurseContext);
isw = Result[0] * 0x0100 + Result[1]; isw = result[0] * 0x0100 + result[1];
} else { } else {
CipurseCAPDURespDecode(&cipurseContext, Result, *ResultLen, securedata, &rlen, &isw); CipurseCAPDURespDecode(&cipurseContext, result, *result_len, securedata, &rlen, &isw);
memcpy(Result, securedata, rlen); memcpy(result, securedata, rlen);
} }
if (ResultLen != NULL) if (result_len != NULL) {
*ResultLen = rlen; *result_len = rlen;
}
if (sw != NULL) if (sw != NULL) {
*sw = isw; *sw = isw;
}
if (isw != 0x9000) { if (isw != 0x9000) {
if (GetAPDULogging()) { if (GetAPDULogging()) {
@ -102,69 +111,69 @@ static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu,
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int CIPURSEExchange(sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { static int CIPURSEExchange(sAPDU apdu, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchangeEx(false, true, apdu, true, 0, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchangeEx(false, true, apdu, true, 0, result, max_result_len, result_len, sw);
} }
int CIPURSESelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSESelect(bool activate_field, bool leave_field_on, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
uint8_t data[] = {0x41, 0x44, 0x20, 0x46, 0x31}; uint8_t data[] = {0x41, 0x44, 0x20, 0x46, 0x31};
CipurseCClearContext(&cipurseContext); CipurseCClearContext(&cipurseContext);
return EMVSelect(CC_CONTACTLESS, ActivateField, LeaveFieldON, data, sizeof(data), Result, MaxResultLen, ResultLen, sw, NULL); return EMVSelect(CC_CONTACTLESS, activate_field, leave_field_on, data, sizeof(data), result, max_result_len, result_len, sw, NULL);
} }
int CIPURSEChallenge(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSEChallenge(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, true, 0x16, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0x84, 0x00, 0x00, 0x00, NULL}, true, 0x16, result, max_result_len, result_len, sw);
} }
int CIPURSEMutalAuthenticate(uint8_t keyIndex, uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSEMutalAuthenticate(uint8_t keyindex, uint8_t *params, uint8_t paramslen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0x82, 0x00, keyIndex, paramslen, params}, true, 0x10, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0x82, 0x00, keyindex, paramslen, params}, true, 0x10, result, max_result_len, result_len, sw);
} }
int CIPURSECreateFile(uint8_t *attr, uint16_t attrlen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSECreateFile(uint8_t *attr, uint16_t attrlen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0xe4, 0x00, 0x00, attrlen, attr}, false, 0, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0xe4, 0x00, 0x00, attrlen, attr}, false, 0, result, max_result_len, result_len, sw);
} }
int CIPURSEDeleteFile(uint16_t fileID, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSEDeleteFile(uint16_t fileid, uint8_t *Result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
uint8_t fileIdBin[] = {fileID >> 8, fileID & 0xff}; uint8_t fileIdBin[] = {fileid >> 8, fileid & 0xff};
return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0xe4, 0x00, 0x00, 02, fileIdBin}, false, 0, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchangeEx(false, true, (sAPDU) {0x00, 0xe4, 0x00, 0x00, 02, fileIdBin}, false, 0, Result, max_result_len, result_len, sw);
} }
int CIPURSESelectFile(uint16_t fileID, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSESelectFile(uint16_t fileid, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
uint8_t fileIdBin[] = {fileID >> 8, fileID & 0xff}; uint8_t fileIdBin[] = {fileid >> 8, fileid & 0xff};
return CIPURSEExchange((sAPDU) {0x00, 0xa4, 0x00, 0x00, 02, fileIdBin}, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchange((sAPDU) {0x00, 0xa4, 0x00, 0x00, 02, fileIdBin}, result, max_result_len, result_len, sw);
} }
int CIPURSESelectMFFile(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSESelectMFFile(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchange((sAPDU) {0x00, 0xa4, 0x00, 0x00, 0, NULL}, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchange((sAPDU) {0x00, 0xa4, 0x00, 0x00, 0, NULL}, result, max_result_len, result_len, sw);
} }
int CIPURSEReadFileAttributes(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSEReadFileAttributes(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchange((sAPDU) {0x80, 0xce, 0x00, 0x00, 0, NULL}, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchange((sAPDU) {0x80, 0xce, 0x00, 0x00, 0, NULL}, result, max_result_len, result_len, sw);
} }
int CIPURSEReadBinary(uint16_t offset, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSEReadBinary(uint16_t offset, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchange((sAPDU) {0x00, 0xb0, (offset >> 8) & 0x7f, offset & 0xff, 0, NULL}, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchange((sAPDU) {0x00, 0xb0, (offset >> 8) & 0x7f, offset & 0xff, 0, NULL}, result, max_result_len, result_len, sw);
} }
int CIPURSEUpdateBinary(uint16_t offset, uint8_t *data, uint16_t datalen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { int CIPURSEUpdateBinary(uint16_t offset, uint8_t *data, uint16_t datalen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) {
return CIPURSEExchange((sAPDU) {0x00, 0xd6, (offset >> 8) & 0x7f, offset & 0xff, datalen, data}, Result, MaxResultLen, ResultLen, sw); return CIPURSEExchange((sAPDU) {0x00, 0xd6, (offset >> 8) & 0x7f, offset & 0xff, datalen, data}, result, max_result_len, result_len, sw);
} }
bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose) { bool CIPURSEChannelAuthenticate(uint8_t keyindex, uint8_t *key, bool verbose) {
uint8_t buf[APDU_RES_LEN] = {0}; uint8_t buf[APDU_RES_LEN] = {0};
size_t len = 0; size_t len = 0;
uint16_t sw = 0; uint16_t sw = 0;
CipurseContext cpc = {0}; CipurseContext cpc = {0};
CipurseCSetKey(&cpc, keyIndex, key); CipurseCSetKey(&cpc, keyindex, key);
// get RP, rP // get RP, rP
int res = CIPURSEChallenge(buf, sizeof(buf), &len, &sw); int res = CIPURSEChallenge(buf, sizeof(buf), &len, &sw);
if (res != 0 || len != 0x16) { if (res != 0 || len != 0x16) {
if (verbose) if (verbose) {
PrintAndLogEx(ERR, "Cipurse get challenge " _RED_("error") ". Card returns 0x%04x.", sw); PrintAndLogEx(ERR, "Cipurse get challenge ( " _RED_("fail") " ). Card returns 0x%04x", sw);
}
return false; return false;
} }
CipurseCSetRandomFromPICC(&cpc, buf); CipurseCSetRandomFromPICC(&cpc, buf);
@ -174,17 +183,20 @@ bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose) {
CipurseCAuthenticateHost(&cpc, authparams); CipurseCAuthenticateHost(&cpc, authparams);
// authenticate // authenticate
res = CIPURSEMutalAuthenticate(keyIndex, authparams, sizeof(authparams), buf, sizeof(buf), &len, &sw); res = CIPURSEMutalAuthenticate(keyindex, authparams, sizeof(authparams), buf, sizeof(buf), &len, &sw);
if (res != 0 || sw != 0x9000 || len != 16) { if (res != 0 || sw != 0x9000 || len != 16) {
if (sw == 0x6988) { if (sw == 0x6988) {
if (verbose) if (verbose) {
PrintAndLogEx(ERR, "Cipurse authentication " _RED_("error") ". Wrong key."); PrintAndLogEx(WARNING, "Authentication ( " _RED_("fail") " ). Wrong key");
}
} else if (sw == 0x6A88) { } else if (sw == 0x6A88) {
if (verbose) if (verbose) {
PrintAndLogEx(ERR, "Cipurse authentication " _RED_("error") ". Wrong key number."); PrintAndLogEx(WARNING, "Authentication ( " _RED_("fail") " ). Wrong key number");
}
} else { } else {
if (verbose) if (verbose) {
PrintAndLogEx(ERR, "Cipurse authentication " _RED_("error") ". Card returns 0x%04x.", sw); PrintAndLogEx(WARNING, "Authentication ( " _RED_("fail") " ). Card returns 0x%04x", sw);
}
} }
CipurseCClearContext(&cipurseContext); CipurseCClearContext(&cipurseContext);
@ -192,15 +204,17 @@ bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose) {
} }
if (CipurseCCheckCT(&cpc, buf)) { if (CipurseCCheckCT(&cpc, buf)) {
if (verbose) if (verbose) {
PrintAndLogEx(INFO, "Authentication " _GREEN_("OK")); PrintAndLogEx(SUCCESS, "Authentication ( " _GREEN_("ok") " )");
}
CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed); CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed);
memcpy(&cipurseContext, &cpc, sizeof(CipurseContext)); memcpy(&cipurseContext, &cpc, sizeof(CipurseContext));
return true; return true;
} else { } else {
if (verbose) if (verbose) {
PrintAndLogEx(ERR, "Authentication " _RED_("ERROR") " card returned wrong CT"); PrintAndLogEx(WARNING, "Authentication ( " _RED_("fail") " ) card returned wrong CT");
}
CipurseCClearContext(&cipurseContext); CipurseCClearContext(&cipurseContext);
return false; return false;
@ -212,21 +226,20 @@ void CIPURSECSetActChannelSecurityLevels(CipurseChannelSecurityLevel req, Cipurs
} }
static void CIPURSEPrintPersoMode(uint8_t data) { static void CIPURSEPrintPersoMode(uint8_t data) {
if (data & 0x01) if ((data & 0x01) == 0x01)
PrintAndLogEx(INFO, "Perso: filesystem"); PrintAndLogEx(INFO, "Perso: filesystem");
if (data & 0x02) if ((data & 0x02) == 0x02)
PrintAndLogEx(INFO, "Perso: EMV"); PrintAndLogEx(INFO, "Perso: EMV");
if (data & 0x04) if ((data & 0x04) == 0x04)
PrintAndLogEx(INFO, "Perso: transaction supported"); PrintAndLogEx(INFO, "Perso: transaction supported");
} }
static void CIPURSEPrintProfileInfo(uint8_t data) { static void CIPURSEPrintProfileInfo(uint8_t data) {
if (data & 0x01) if ((data & 0x01) == 0x01)
PrintAndLogEx(INFO, "Profile: L"); PrintAndLogEx(INFO, "Profile: L");
if (data & 0x02) if ((data & 0x02) == 0x02)
PrintAndLogEx(INFO, "Profile: S"); PrintAndLogEx(INFO, "Profile: S");
if (data & 0x04) if ((data & 0x04) == 0x04)
PrintAndLogEx(INFO, "Profile: T"); PrintAndLogEx(INFO, "Profile: T");
} }
@ -239,12 +252,13 @@ static void CIPURSEPrintManufacturerInfo(uint8_t data) {
void CIPURSEPrintInfoFile(uint8_t *data, size_t len) { void CIPURSEPrintInfoFile(uint8_t *data, size_t len) {
if (len < 2) { if (len < 2) {
PrintAndLogEx(ERR, "Info file length " _RED_("ERROR")); PrintAndLogEx(FAILED, "Info file length too short");
return; return;
} }
PrintAndLogEx(INFO, "------------ INFO ------------"); PrintAndLogEx(INFO, "--- " _CYAN_("CIPURSE Information") "---------------------");
PrintAndLogEx(INFO, "CIPURSE version %d revision %d", data[0], data[1]); PrintAndLogEx(INFO, "version.... " _YELLOW_("%d"), data[0]);
PrintAndLogEx(INFO, "revision... " _YELLOW_("%d"), data[1]);
if (len >= 3) if (len >= 3)
CIPURSEPrintPersoMode(data[2]); CIPURSEPrintPersoMode(data[2]);
@ -278,101 +292,111 @@ static void CIPURSEPrintFileDescriptor(uint8_t desc) {
} }
static void CIPURSEPrintKeyAttrib(uint8_t *attr) { static void CIPURSEPrintKeyAttrib(uint8_t *attr) {
PrintAndLogEx(INFO, "-------- KEY ATTRIBUTES --------"); PrintAndLogEx(INFO, "--- " _CYAN_("Key Attributes") "---------------------");
PrintAndLogEx(INFO, "Additional info: 0x%02x", attr[0]); PrintAndLogEx(INFO, "Additional info... 0x%02x", attr[0]);
PrintAndLogEx(INFO, "Key length: %d", attr[1]); PrintAndLogEx(INFO, "Key length........ %d", attr[1]);
PrintAndLogEx(INFO, "Algorithm ID: 0x%02x", attr[2]); PrintAndLogEx(INFO, "Algorithm ID...... 0x%02x", attr[2]);
PrintAndLogEx(INFO, "Security attr: 0x%02x", attr[3]); PrintAndLogEx(INFO, "Security attr..... 0x%02x", attr[3]);
PrintAndLogEx(INFO, "KVV: 0x%02x%02x%02x", attr[4], attr[5], attr[6]); PrintAndLogEx(INFO, "KVV............... 0x%02x%02x%02x", attr[4], attr[5], attr[6]);
PrintAndLogEx(INFO, "-------------------------------"); PrintAndLogEx(NORMAL, "");
} }
void CIPURSEPrintFileAttr(uint8_t *fileAttr, size_t len) { void CIPURSEPrintFileAttr(uint8_t *attr, size_t len) {
if (len < 7) { if (len < 7) {
PrintAndLogEx(ERR, "Attributes length " _RED_("ERROR")); PrintAndLogEx(FAILED, "Attributes length too short");
return; return;
} }
PrintAndLogEx(INFO, "--------- FILE ATTRIBUTES ---------"); PrintAndLogEx(INFO, "--- " _CYAN_("File Attributes") "---------------------");
if (fileAttr[0] == 0x38) { if (attr[0] == 0x38) {
PrintAndLogEx(INFO, "Type: MF, ADF"); PrintAndLogEx(INFO, "Type... MF, ADF");
if (fileAttr[1] == 0x00) {
PrintAndLogEx(INFO, "Type: MF"); if (attr[1] == 0x00) {
PrintAndLogEx(INFO, "Type... MF");
} else { } else {
if ((fileAttr[1] & 0xe0) == 0x00) if ((attr[1] & 0xe0) == 0x00)
PrintAndLogEx(INFO, "Type: Unknown"); PrintAndLogEx(INFO, "Type... Unknown");
if ((fileAttr[1] & 0xe0) == 0x20)
PrintAndLogEx(INFO, "Type: CIPURSE L"); if ((attr[1] & 0xe0) == 0x20)
if ((fileAttr[1] & 0xe0) == 0x40) PrintAndLogEx(INFO, "Type... CIPURSE L");
PrintAndLogEx(INFO, "Type: CIPURSE S");
if ((fileAttr[1] & 0xe0) == 0x60) if ((attr[1] & 0xe0) == 0x40)
PrintAndLogEx(INFO, "Type: CIPURSE T"); PrintAndLogEx(INFO, "Type... CIPURSE S");
if ((fileAttr[1] & 0x02) == 0x00)
if ((attr[1] & 0xe0) == 0x60)
PrintAndLogEx(INFO, "Type... CIPURSE T");
if ((attr[1] & 0x02) == 0x00)
PrintAndLogEx(INFO, "Autoselect on PxSE select OFF"); PrintAndLogEx(INFO, "Autoselect on PxSE select OFF");
else else
PrintAndLogEx(INFO, "Autoselect on PxSE select ON"); PrintAndLogEx(INFO, "Autoselect on PxSE select ON");
if ((fileAttr[1] & 0x01) == 0x00)
if ((attr[1] & 0x01) == 0x00)
PrintAndLogEx(INFO, "PxSE select returns FCPTemplate OFF"); PrintAndLogEx(INFO, "PxSE select returns FCPTemplate OFF");
else else
PrintAndLogEx(INFO, "PxSE select returns FCPTemplate ON"); PrintAndLogEx(INFO, "PxSE select returns FCPTemplate ON");
} }
PrintAndLogEx(INFO, "File ID: 0x%02x%02x", fileAttr[2], fileAttr[3]); PrintAndLogEx(INFO, "File ID................... 0x%02x%02x", attr[2], attr[3]);
PrintAndLogEx(INFO, "Maximum # custom EFs...... %d", attr[4]);
PrintAndLogEx(INFO, "Maximum # EFs with SFID... %d", attr[5]);
PrintAndLogEx(INFO, "Maximum number of custom EFs: %d", fileAttr[4]); uint8_t keynum = attr[6];
PrintAndLogEx(INFO, "Maximum number of EFs with SFID: %d", fileAttr[5]); PrintAndLogEx(INFO, "Keys assigned... %d", keynum);
uint8_t keyNum = fileAttr[6];
PrintAndLogEx(INFO, "Keys assigned: %d", keyNum);
if (len >= 9) { if (len >= 9) {
PrintAndLogEx(INFO, "SMR entries: %02x%02x", fileAttr[7], fileAttr[8]); PrintAndLogEx(INFO, "SMR entries... %02x%02x", attr[7], attr[8]);
} }
if (len >= 10 + keyNum + 1) { if (len >= 10 + keynum + 1) {
PrintAndLogEx(INFO, "ART: %s", sprint_hex(&fileAttr[9], keyNum + 1)); PrintAndLogEx(INFO, "ART... %s", sprint_hex(&attr[9], keynum + 1));
} }
if (len >= 11 + keyNum + 1 + keyNum * 7) { if (len >= 11 + keynum + 1 + keynum * 7) {
for (int i = 0; i < keyNum; i++) { for (int i = 0; i < keynum; i++) {
PrintAndLogEx(INFO, "Key %d Attributes: %s", i, sprint_hex(&fileAttr[11 + keyNum + 1 + i * 7], 7)); PrintAndLogEx(INFO, "Key %d Attributes... %s", i, sprint_hex(&attr[11 + keynum + 1 + i * 7], 7));
CIPURSEPrintKeyAttrib(&fileAttr[11 + keyNum + 1 + i * 7]); CIPURSEPrintKeyAttrib(&attr[11 + keynum + 1 + i * 7]);
} }
} }
// MF // MF
if (fileAttr[1] == 0x00) { if (attr[1] == 0x00) {
PrintAndLogEx(INFO, "Total memory size: %d", (fileAttr[len - 6] << 16) + (fileAttr[len - 1] << 5) + fileAttr[len - 4]); PrintAndLogEx(INFO, "Total memory size... %d", (attr[len - 6] << 16) + (attr[len - 1] << 5) + attr[len - 4]);
PrintAndLogEx(INFO, "Free memory size: %d", (fileAttr[len - 3] << 16) + (fileAttr[len - 2] << 8) + fileAttr[len - 1]); PrintAndLogEx(INFO, "Free memory size.... %d", (attr[len - 3] << 16) + (attr[len - 2] << 8) + attr[len - 1]);
} else { } else {
int ptr = 11 + keyNum + 1 + keyNum * 7; int ptr = 11 + keynum + 1 + keynum * 7;
if (len > ptr) if (len > ptr) {
PrintAndLogEx(INFO, "TLV file control: %s", sprint_hex(&fileAttr[ptr], len - ptr)); PrintAndLogEx(INFO, "TLV file control... %s", sprint_hex(&attr[ptr], len - ptr));
}
} }
} else { } else {
PrintAndLogEx(INFO, "Type: EF"); PrintAndLogEx(INFO, "Type... EF");
CIPURSEPrintFileDescriptor(fileAttr[0]); CIPURSEPrintFileDescriptor(attr[0]);
if (fileAttr[1] == 0)
PrintAndLogEx(INFO, "SFI: not assigned"); if (attr[1] == 0)
PrintAndLogEx(INFO, "SFI.... not assigned");
else else
PrintAndLogEx(INFO, "SFI: 0x%02x", fileAttr[1]); PrintAndLogEx(INFO, "SFI.... 0x%02x", attr[1]);
PrintAndLogEx(INFO, "File ID: 0x%02x%02x", fileAttr[2], fileAttr[3]); PrintAndLogEx(INFO, "File ID... 0x%02x%02x", attr[2], attr[3]);
if (fileAttr[0] == 0x01 || fileAttr[0] == 0x11) if (attr[0] == 0x01 || attr[0] == 0x11)
PrintAndLogEx(INFO, "File size: %d", (fileAttr[4] << 8) + fileAttr[5]); PrintAndLogEx(INFO, "File size... %d", (attr[4] << 8) + attr[5]);
else else
PrintAndLogEx(INFO, "Record num: %d record size: %d", fileAttr[4], fileAttr[5]); PrintAndLogEx(INFO, "Record num " _YELLOW_("%d") " record size " _YELLOW_("%d"), attr[4], attr[5]);
PrintAndLogEx(INFO, "Keys assigned: %d", fileAttr[6]); PrintAndLogEx(INFO, "Keys assigned... %d", attr[6]);
if (len >= 9) { if (len >= 9) {
PrintAndLogEx(INFO, "SMR entries: %02x%02x", fileAttr[7], fileAttr[8]); PrintAndLogEx(INFO, "SMR entries... %02x%02x", attr[7], attr[8]);
} }
if (len >= 10) { if (len >= 10) {
PrintAndLogEx(INFO, "ART: %s", sprint_hex(&fileAttr[9], len - 9)); PrintAndLogEx(INFO, "ART... %s", sprint_hex(&attr[9], len - 9));
if (fileAttr[6] + 1 != len - 9)
if (attr[6] + 1 != len - 9) {
PrintAndLogEx(WARNING, "ART length is wrong"); PrintAndLogEx(WARNING, "ART length is wrong");
}
} }
} }

View file

@ -11,10 +11,10 @@
#ifndef __CIPURSECORE_H__ #ifndef __CIPURSECORE_H__
#define __CIPURSECORE_H__ #define __CIPURSECORE_H__
#include "common.h"
#include <jansson.h> #include <jansson.h>
#include "iso7816/apduinfo.h" // sAPDU #include <stdbool.h>
#include "common.h"
#include "iso7816/apduinfo.h" // sAPDU
#include "cipurse/cipursecrypto.h" #include "cipurse/cipursecrypto.h"
@ -22,23 +22,23 @@
void CIPURSEPrintInfoFile(uint8_t *data, size_t len); void CIPURSEPrintInfoFile(uint8_t *data, size_t len);
int CIPURSESelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSESelect(bool activate_field, bool leave_field_on, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSEChallenge(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSEChallenge(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSEMutalAuthenticate(uint8_t keyIndex, uint8_t *params, uint8_t paramslen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSEMutalAuthenticate(uint8_t keyIndex, uint8_t *params, uint8_t paramslen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSECreateFile(uint8_t *attr, uint16_t attrlen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSECreateFile(uint8_t *attr, uint16_t attrlen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSEDeleteFile(uint16_t fileID, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSEDeleteFile(uint16_t fileid, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSESelectMFFile(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) ; int CIPURSESelectMFFile(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw) ;
int CIPURSESelectFile(uint16_t fileID, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSESelectFile(uint16_t fileid, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSEReadFileAttributes(uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSEReadFileAttributes(uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSEReadBinary(uint16_t offset, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSEReadBinary(uint16_t offset, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
int CIPURSEUpdateBinary(uint16_t offset, uint8_t *data, uint16_t datalen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw); int CIPURSEUpdateBinary(uint16_t offset, uint8_t *data, uint16_t datalen, uint8_t *result, size_t max_result_len, size_t *result_len, uint16_t *sw);
bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose); bool CIPURSEChannelAuthenticate(uint8_t keyindex, uint8_t *key, bool verbose);
void CIPURSECSetActChannelSecurityLevels(CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp); void CIPURSECSetActChannelSecurityLevels(CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp);
void CIPURSEPrintFileAttr(uint8_t *fileAttr, size_t len); void CIPURSEPrintFileAttr(uint8_t *attr, size_t len);
#endif /* __CIPURSECORE_H__ */ #endif /* __CIPURSECORE_H__ */