diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 8e377687f..f77258401 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -6313,21 +6313,39 @@ static int CmdHF14ADesChFileSettings(const char *Cmd) { } } + uint8_t buf[APDU_RES_LEN] = {0}; + size_t buflen = 0; + + // check current file settings + DesfireCommunicationMode commMode = dctx.commMode; + DesfireSetCommMode(&dctx, DCMPlain); + res = DesfireGetFileSettings(&dctx, fileid, buf, &buflen); + if (res == PM3_SUCCESS && buflen > 5) { + uint8_t chright = buf[2] & 0x0f; + if (verbose) + PrintAndLogEx(INFO, "Current access right for change file settings: %s", GetDesfireAccessRightStr(chright)); + + if (chright == 0x0f) + PrintAndLogEx(WARNING, "Change file settings disabled"); + + if (chright == 0x0e && (!(commMode == DCMPlain || commMode == DCMMACed || noauth))) + PrintAndLogEx(WARNING, "File settings have free access for change. Change command must be sent via plain communications mode or without authentication (--no-auth option)"); + + if (chright < 0x0e && dctx.keyNum != chright) + PrintAndLogEx(WARNING, "File settings must be changed with auth key=0x%02x but current auth with key 0x%02x", chright, dctx.keyNum); + + if (chright < 0x0e && commMode != DCMEncrypted) + PrintAndLogEx(WARNING, "File settings must be changed via encryted (full) communication mode"); + } + DesfireSetCommMode(&dctx, commMode); + + // print the new file settings if (verbose) PrintAndLogEx(INFO, "app %06x file %02x settings[%d]: %s", appid, fileid, settingslen, sprint_hex(settings, settingslen)); DesfirePrintSetFileSettings(settings, settingslen); - /* uint8_t buf[APDU_RES_LEN] = {0}; - size_t buflen = 0; - - res = DesfireGetFileSettings(&dctx, fileid, buf, &buflen); - if (res == PM3_SUCCESS && buflen > 5) { - uint8_t chright = buf[2] & 0x0f; - }*/ - - - + // set file settings data[0] = fileid; res = DesfireChangeFileSettings(&dctx, data, settingslen + 1); if (res != PM3_SUCCESS) { diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index c1e4d3c12..413ef3b96 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1192,7 +1192,7 @@ static const char *GetDesfireKeyType(uint8_t keytype) { return DesfireUnknownStr; } -static const char *GetAccessRightStr(uint8_t right) { +const char *GetDesfireAccessRightStr(uint8_t right) { static char int_access_str[200]; memset(int_access_str, 0, sizeof(int_access_str)); @@ -1213,10 +1213,10 @@ static const char *GetAccessRightStr(uint8_t right) { } void DesfirePrintAccessRight(uint8_t *data) { - PrintAndLogEx(SUCCESS, "read : %s", GetAccessRightStr((data[1] >> 4) & 0x0f)); // hi 2b - PrintAndLogEx(SUCCESS, "write : %s", GetAccessRightStr(data[1] & 0x0f)); - PrintAndLogEx(SUCCESS, "readwrite: %s", GetAccessRightStr((data[0] >> 4) & 0x0f)); // low 2b - PrintAndLogEx(SUCCESS, "change : %s", GetAccessRightStr(data[0] & 0x0f)); + PrintAndLogEx(SUCCESS, "read : %s", GetDesfireAccessRightStr((data[1] >> 4) & 0x0f)); // hi 2b + PrintAndLogEx(SUCCESS, "write : %s", GetDesfireAccessRightStr(data[1] & 0x0f)); + PrintAndLogEx(SUCCESS, "readwrite: %s", GetDesfireAccessRightStr((data[0] >> 4) & 0x0f)); // low 2b + PrintAndLogEx(SUCCESS, "change : %s", GetDesfireAccessRightStr(data[0] & 0x0f)); } void DesfirePrintFileSettings(uint8_t *data, size_t len) { diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 5c077738a..a7eb29120 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -66,6 +66,7 @@ int DesfireGetFileIDList(DesfireContext *dctx, uint8_t *resp, size_t *resplen); int DesfireGetFileISOIDList(DesfireContext *dctx, uint8_t *resp, size_t *resplen); int DesfireGetFileSettings(DesfireContext *dctx, uint8_t fileid, uint8_t *resp, size_t *resplen); int DesfireChangeFileSettings(DesfireContext *dctx, uint8_t *data, size_t datalen); +const char *GetDesfireAccessRightStr(uint8_t right); void DesfirePrintAccessRight(uint8_t *data); void DesfirePrintFileSettings(uint8_t *data, size_t len); void DesfirePrintSetFileSettings(uint8_t *data, size_t len);