diff --git a/client/src/cipurse/cipursecore.c b/client/src/cipurse/cipursecore.c index c11707d3d..6da5f7849 100644 --- a/client/src/cipurse/cipursecore.c +++ b/client/src/cipurse/cipursecore.c @@ -352,6 +352,23 @@ void CIPURSEPrintFileDescriptor(uint8_t desc) { PrintAndLogEx(INFO, "Unknown file 0x%02x", desc); } +void CIPURSEPrintDGIArray(uint8_t *dgi, size_t dgilen) { + if (dgilen < 3) { + PrintAndLogEx(WARNING, "DGI too small. Length: %zu", dgilen); + return; + } + + uint8_t *dgiptr = dgi; + size_t reslen = 0; + while (dgilen > reslen + 2) { + uint8_t len = dgiptr[2]; + CIPURSEPrintDGI(dgiptr, len + 3); + + dgiptr += len + 3; + reslen += len + 3; + } +} + void CIPURSEPrintDGI(uint8_t *dgi, size_t dgilen) { if (dgilen < 3) { PrintAndLogEx(WARNING, "DGI too small. Length: %zu", dgilen); @@ -367,12 +384,11 @@ void CIPURSEPrintDGI(uint8_t *dgi, size_t dgilen) { // check DGI if (dgi[0] == 0x92 && dgi[1] == 0x00) { PrintAndLogEx(INFO, "DGI 9200 - ADF file attributes"); + CIPURSEPrintFileAttrEx(&dgi[3], len, true); } else if (dgi[0] == 0x92 && dgi[1] == 0x01) { PrintAndLogEx(INFO, "DGI 9201 - EF file attributes"); - PrintAndLogEx(INFO, "File type:"); - CIPURSEPrintEFFileAttr(&dgi[3], len); - PrintAndLogEx(NORMAL, ""); + CIPURSEPrintFileAttrEx(&dgi[3], len, true); } else if (dgi[0] == 0xa0 && dgi[1] == 0x0f) { PrintAndLogEx(INFO, "DGI a00f - All key values"); @@ -398,10 +414,10 @@ void CIPURSEPrintDGI(uint8_t *dgi, size_t dgilen) { } static void CIPURSEPrintKeySecurityAttributes(uint8_t attr) { - PrintAndLogEx(INFO, "Update right: %s", (attr & 0x01) ? "self" : "any"); - PrintAndLogEx(INFO, "Change key and rights: %s", (attr & 0x02) ? "ok" : "frozen"); - PrintAndLogEx(INFO, "Use as key encryption key: %s", (attr & 0x04) ? "blocked" : "ok"); - PrintAndLogEx(INFO, "Key validity: %s", (attr & 0x80) ? "invalid" : "valid"); + PrintAndLogEx(INFO, " Update right: %s", (attr & 0x01) ? "self" : "any"); + PrintAndLogEx(INFO, " Change key and rights: %s", (attr & 0x02) ? "ok" : "frozen"); + PrintAndLogEx(INFO, " Use as key encryption key: %s", (attr & 0x04) ? "blocked" : "ok"); + PrintAndLogEx(INFO, " Key validity: %s", (attr & 0x80) ? "invalid" : "valid"); } static void CIPURSEPrintKeyAttrib(uint8_t *attr) { @@ -415,6 +431,15 @@ static void CIPURSEPrintKeyAttrib(uint8_t *attr) { PrintAndLogEx(NORMAL, ""); } +static void CIPURSEPrintKeyAttribDGI(uint8_t *attr) { + PrintAndLogEx(INFO, "--- " _CYAN_("DGI Key Attributes") "---------------------"); + PrintAndLogEx(INFO, "Security attr..... 0x%02x", attr[0]); + CIPURSEPrintKeySecurityAttributes(attr[0]); + PrintAndLogEx(INFO, "Key length........ %d", attr[1]); + PrintAndLogEx(INFO, "Algorithm ID...... 0x%02x (%s)", attr[2], (attr[2] == 0x09) ? "AES" : "unknown"); + PrintAndLogEx(NORMAL, ""); +} + const char *CIPURSEGetSMR(uint8_t smr) { switch (smr) { case 0x00: return "plain"; @@ -483,7 +508,7 @@ void CIPURSEPrintEFFileAttr(uint8_t *attr, size_t len) { } } -void CIPURSEPrintFileAttr(uint8_t *attr, size_t len) { +void CIPURSEPrintFileAttrEx(uint8_t *attr, size_t len, bool isDGI) { if (len < 7) { PrintAndLogEx(FAILED, "Attributes length too short"); return; @@ -544,13 +569,17 @@ void CIPURSEPrintFileAttr(uint8_t *attr, size_t len) { } idx += keynum + 1; - if (len >= idx + keynum * 7) { + size_t reclen = (isDGI) ? 3 : 7; + if (len >= idx + keynum * reclen) { for (int i = 0; i < keynum; i++) { - PrintAndLogEx(INFO, "Key %d Attributes... %s", i + 1, sprint_hex(&attr[idx + i * 7], 7)); - CIPURSEPrintKeyAttrib(&attr[idx + i * 7]); + PrintAndLogEx(INFO, "Key %d Attributes... %s", i + 1, sprint_hex(&attr[idx + i * reclen], reclen)); + if (isDGI) + CIPURSEPrintKeyAttribDGI(&attr[idx + i * reclen]); + else + CIPURSEPrintKeyAttrib(&attr[idx + i * reclen]); } } - idx += keynum * 7; + idx += keynum * reclen; } // FCP if (len >= idx + 1) { @@ -573,9 +602,11 @@ void CIPURSEPrintFileAttr(uint8_t *attr, size_t len) { } else { PrintAndLogEx(INFO, "Type... EF"); CIPURSEPrintEFFileAttr(attr, len); + PrintAndLogEx(NORMAL, ""); } - } - +void CIPURSEPrintFileAttr(uint8_t *attr, size_t len) { + return CIPURSEPrintFileAttrEx(attr, len, false); +} diff --git a/client/src/cipurse/cipursecore.h b/client/src/cipurse/cipursecore.h index 4c9a018de..3a880326a 100644 --- a/client/src/cipurse/cipursecore.h +++ b/client/src/cipurse/cipursecore.h @@ -64,8 +64,10 @@ const char *CIPURSEGetSMR(uint8_t smr); void CIPURSEPrintSMR(uint8_t *smrrec); void CIPURSEPrintART(uint8_t *artrec, size_t artlen); void CIPURSEPrintEFFileAttr(uint8_t *attr, size_t len); +void CIPURSEPrintFileAttrEx(uint8_t *attr, size_t len, bool isDGI); void CIPURSEPrintFileAttr(uint8_t *attr, size_t len); void CIPURSEPrintFileDescriptor(uint8_t desc); +void CIPURSEPrintDGIArray(uint8_t *dgi, size_t dgilen); void CIPURSEPrintDGI(uint8_t *dgi, size_t dgilen); #endif /* __CIPURSECORE_H__ */ diff --git a/client/src/cmdhfcipurse.c b/client/src/cmdhfcipurse.c index af5ff0345..4d11d0ef9 100644 --- a/client/src/cmdhfcipurse.c +++ b/client/src/cmdhfcipurse.c @@ -1043,7 +1043,7 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) { SetAPDULogging(APDULogging); if (verbose && hdatalen > 3) - CIPURSEPrintDGI(hdata, hdatalen); + CIPURSEPrintDGIArray(hdata, hdatalen); uint8_t buf[APDU_RES_LEN] = {0}; size_t len = 0;