Merge branch 'RfidResearchGroup:master' into master

This commit is contained in:
Davi Mikael 2023-05-15 13:59:04 -03:00 committed by GitHub
commit 6d1b5b8e13
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 175 additions and 66 deletions

View file

@ -18,7 +18,6 @@
#include "cmdhfmf.h" #include "cmdhfmf.h"
#include <ctype.h> #include <ctype.h>
#include "cmdparser.h" // command_t #include "cmdparser.h" // command_t
#include "commonutil.h" // ARRAYLEN #include "commonutil.h" // ARRAYLEN
#include "comms.h" // clearCommandBuffer #include "comms.h" // clearCommandBuffer
@ -38,23 +37,6 @@
#include "wiegand_formats.h" #include "wiegand_formats.h"
#include "wiegand_formatutils.h" #include "wiegand_formatutils.h"
#define MIFARE_4K_MAXBLOCK 256
#define MIFARE_2K_MAXBLOCK 128
#define MIFARE_1K_MAXBLOCK 64
#define MIFARE_MINI_MAXBLOCK 20
#define MIFARE_4K_MAXSECTOR 40
#define MIFARE_2K_MAXSECTOR 32
#define MIFARE_1K_MAXSECTOR 16
#define MIFARE_MINI_MAXSECTOR 5
#define MIFARE_4K_MAX_BYTES 4096
#define MIFARE_2K_MAX_BYTES 2048
#define MIFARE_1K_MAX_BYTES 1024
#define MIFARE_MINI_MAX_BYTES 320
#define MIFARE_KEY_SIZE 6
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
/* /*
@ -152,12 +134,12 @@ static char *GenerateFilename(const char *prefix, const char *suffix) {
return fptr; return fptr;
} }
static int32_t initSectorTable(sector_t **src, int32_t items) { static int initSectorTable(sector_t **src, size_t items) {
(*src) = calloc(items, sizeof(sector_t)); (*src) = calloc(items, sizeof(sector_t));
if (*src == NULL) if (*src == NULL)
return -1; return PM3_EMALLOC;
// empty e_sector // empty e_sector
for (int i = 0; i < items; ++i) { for (int i = 0; i < items; ++i) {
@ -166,7 +148,7 @@ static int32_t initSectorTable(sector_t **src, int32_t items) {
(*src)[i].foundKey[j] = false; (*src)[i].foundKey[j] = false;
} }
} }
return items; return PM3_SUCCESS;
} }
static void decode_print_st(uint16_t blockno, uint8_t *data) { static void decode_print_st(uint16_t blockno, uint8_t *data) {
@ -2373,7 +2355,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
// Attack key storage variables // Attack key storage variables
uint8_t *keyBlock = NULL; uint8_t *keyBlock = NULL;
uint32_t key_cnt = 0; uint32_t key_cnt = 0;
sector_t *e_sector;
uint8_t tmp_key[6] = {0}; uint8_t tmp_key[6] = {0};
// Nested and Hardnested returned status // Nested and Hardnested returned status
@ -2408,7 +2389,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
iso14a_card_select_t card; iso14a_card_select_t card;
memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
// detect MFC EV1 Signature // detect MFC EV1 Signature
bool is_ev1 = detect_mfc_ev1_signature(); bool is_ev1 = detect_mfc_ev1_signature();
if (is_ev1) { if (is_ev1) {
@ -2417,10 +2397,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
} }
// create/initialize key storage structure // create/initialize key storage structure
uint32_t e_sector_size = sector_cnt > sectorno ? sector_cnt : sectorno + 1; sector_t *e_sector = NULL;
res = initSectorTable(&e_sector, e_sector_size); uint32_t e_sector_cnt = (sector_cnt > sectorno) ? sector_cnt : sectorno + 1;
if (res != e_sector_size) { if (initSectorTable(&e_sector, e_sector_cnt) != PM3_SUCCESS) {
free(e_sector);
return PM3_EMALLOC; return PM3_EMALLOC;
} }
@ -2859,7 +2838,7 @@ tryNested:
} }
break; break;
} }
case PM3_ESTATIC_NONCE: case PM3_ESTATIC_NONCE: {
PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n");
e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff;; e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff;;
@ -2872,6 +2851,7 @@ tryNested:
free(e_sector); free(e_sector);
free(fptr); free(fptr);
return isOK; return isOK;
}
case PM3_SUCCESS: { case PM3_SUCCESS: {
calibrate = false; calibrate = false;
e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmp_key, 6); e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmp_key, 6);
@ -2896,6 +2876,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
slow ? "Yes" : "No"); slow ? "Yes" : "No");
} }
foundkey = 0;
isOK = mfnestedhard(mfFirstBlockOfSector(sectorno), keytype, key, mfFirstBlockOfSector(current_sector_i), current_key_type_i, NULL, false, false, slow, 0, &foundkey, NULL); isOK = mfnestedhard(mfFirstBlockOfSector(sectorno), keytype, key, mfFirstBlockOfSector(current_sector_i), current_key_type_i, NULL, false, false, slow, 0, &foundkey, NULL);
DropField(); DropField();
if (isOK) { if (isOK) {
@ -3211,8 +3192,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
// create/initialize key storage structure // create/initialize key storage structure
sector_t *e_sector = NULL; sector_t *e_sector = NULL;
int32_t res = initSectorTable(&e_sector, sectorsCnt); if (initSectorTable(&e_sector, sectorsCnt) != PM3_SUCCESS) {
if (res != sectorsCnt) {
free(keyBlock); free(keyBlock);
return PM3_EMALLOC; return PM3_EMALLOC;
} }
@ -3247,7 +3227,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
if (size == keycnt - i) if (size == keycnt - i)
lastChunk = true; lastChunk = true;
res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false); int res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * 6), e_sector, false);
if (firstChunk) if (firstChunk)
firstChunk = false; firstChunk = false;
@ -3454,8 +3434,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
// create/initialize key storage structure // create/initialize key storage structure
sector_t *e_sector = NULL; sector_t *e_sector = NULL;
int32_t res = initSectorTable(&e_sector, SectorsCnt); if (initSectorTable(&e_sector, SectorsCnt) != PM3_SUCCESS) {
if (res != SectorsCnt) {
free(keyBlock); free(keyBlock);
return PM3_EMALLOC; return PM3_EMALLOC;
} }
@ -3613,28 +3592,24 @@ out:
return PM3_SUCCESS; return PM3_SUCCESS;
} }
void showSectorTable(sector_t *k_sector, uint8_t k_sectorsCount) { void showSectorTable(sector_t *k_sector, uint8_t k_sectors_cnt) {
if (k_sector != NULL) { if (k_sector != NULL) {
printKeyTable(k_sectorsCount, k_sector); printKeyTable(k_sectors_cnt, k_sector);
free(k_sector); free(k_sector);
} }
} }
void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, bool setEmulatorMem, bool verbose) { void readerAttack(sector_t *k_sector, uint8_t k_sectors_cnt, nonces_t data, bool setEmulatorMem, bool verbose) {
uint64_t key = 0;
bool success = false;
// init if needed
if (k_sector == NULL) { if (k_sector == NULL) {
int32_t res = initSectorTable(&k_sector, k_sectorsCount); if (initSectorTable(&k_sector, k_sectors_cnt) != PM3_SUCCESS) {
if (res != k_sectorsCount) {
free(k_sector);
return; return;
} }
} }
success = mfkey32_moebius(&data, &key); uint64_t key = 0;
if (success) { if (mfkey32_moebius(&data, &key)) {
uint8_t sector = data.sector; uint8_t sector = data.sector;
uint8_t keytype = data.keytype; uint8_t keytype = data.keytype;
@ -3649,7 +3624,7 @@ void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, boo
//set emulator memory for keys //set emulator memory for keys
if (setEmulatorMem) { if (setEmulatorMem) {
uint8_t memBlock[16] = {0, 0, 0, 0, 0, 0, 0xff, 0x0F, 0x80, 0x69, 0, 0, 0, 0, 0, 0}; uint8_t memBlock[16] = {0, 0, 0, 0, 0, 0, 0xFF, 0x07, 0x80, 0x69, 0, 0, 0, 0, 0, 0};
num_to_bytes(k_sector[sector].Key[0], 6, memBlock); num_to_bytes(k_sector[sector].Key[0], 6, memBlock);
num_to_bytes(k_sector[sector].Key[1], 6, memBlock + 10); num_to_bytes(k_sector[sector].Key[1], 6, memBlock + 10);
//iceman, guessing this will not work so well for 4K tags. //iceman, guessing this will not work so well for 4K tags.
@ -3907,6 +3882,8 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto
PrintAndLogEx(SUCCESS, " Sec | Blk | key A |res| key B |res"); PrintAndLogEx(SUCCESS, " Sec | Blk | key A |res| key B |res");
PrintAndLogEx(SUCCESS, "-----+-----+--------------+---+--------------+----"); PrintAndLogEx(SUCCESS, "-----+-----+--------------+---+--------------+----");
uint64_t ndef_key = 0xD3F7D3F7D3F7;
bool has_ndef_key = false;
bool extended_legend = false; bool extended_legend = false;
for (uint8_t i = 0; i < sectorscnt; i++) { for (uint8_t i = 0; i < sectorscnt; i++) {
@ -3914,20 +3891,32 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto
extended_legend = true; extended_legend = true;
} }
if (e_sector[i].Key[0] == ndef_key || e_sector[i].Key[1] == ndef_key) {
has_ndef_key = true;
}
if (e_sector[i].foundKey[0]) { if (e_sector[i].foundKey[0]) {
snprintf(strA, sizeof(strA), _GREEN_("%012" PRIX64), e_sector[i].Key[0]); snprintf(strA, sizeof(strA), _GREEN_("%012" PRIX64), e_sector[i].Key[0]);
snprintf(resA, sizeof(resA), _BRIGHT_GREEN_("%c"), e_sector[i].foundKey[0]); if (extended_legend) {
snprintf(resA, sizeof(resA), _BRIGHT_GREEN_("%c"), e_sector[i].foundKey[0]);
} else {
snprintf(resA, sizeof(resA), _BRIGHT_GREEN_("%d"), e_sector[i].foundKey[0]);
}
} else { } else {
snprintf(strA, sizeof(strA), _RED_("%s"), "------------"); snprintf(strA, sizeof(strA), _RED_("%s"), "------------");
snprintf(resA, sizeof(resA), _RED_("%d"), 0); snprintf(resA, sizeof(resA), _RED_("0"));
} }
if (e_sector[i].foundKey[1]) { if (e_sector[i].foundKey[1]) {
snprintf(strB, sizeof(strB), _GREEN_("%012" PRIX64), e_sector[i].Key[1]); snprintf(strB, sizeof(strB), _GREEN_("%012" PRIX64), e_sector[i].Key[1]);
snprintf(resB, sizeof(resB), _BRIGHT_GREEN_("%c"), e_sector[i].foundKey[1]); if (extended_legend) {
snprintf(resB, sizeof(resB), _BRIGHT_GREEN_("%c"), e_sector[i].foundKey[1]);
} else {
snprintf(resB, sizeof(resB), _BRIGHT_GREEN_("%d"), e_sector[i].foundKey[1]);
}
} else { } else {
snprintf(strB, sizeof(strB), _RED_("%s"), "------------"); snprintf(strB, sizeof(strB), _RED_("%s"), "------------");
snprintf(resB, sizeof(resB), _RED_("%d"), 0); snprintf(resB, sizeof(resB), _RED_("0"));
} }
// keep track if we use start_sector or i // keep track if we use start_sector or i
@ -3964,9 +3953,13 @@ void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_secto
} }
// MAD detection // MAD detection
if (e_sector[MF_MAD1_SECTOR].foundKey[0] && e_sector[MF_MAD1_SECTOR].Key[MF_KEY_A] == 0xA0A1A2A3A4A5) { if (e_sector[MF_MAD1_SECTOR].foundKey[0] && e_sector[MF_MAD1_SECTOR].Key[0] == 0xA0A1A2A3A4A5) {
PrintAndLogEx(HINT, "MAD key detected. Try " _YELLOW_("`hf mf mad`") " for more details"); PrintAndLogEx(HINT, "MAD key detected. Try " _YELLOW_("`hf mf mad`") " for more details");
} }
// NDEF detection
if (has_ndef_key) {
PrintAndLogEx(HINT, "NDEF key detected. Try " _YELLOW_("`hf mf ndefread`") " for more details");
}
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
} }
@ -4585,12 +4578,9 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
sector_t *e_sector = NULL;
// create/initialize key storage structure // create/initialize key storage structure
int32_t res = initSectorTable(&e_sector, sectors_cnt); sector_t *e_sector = NULL;
if (res != sectors_cnt) { if (initSectorTable(&e_sector, sectors_cnt) != PM3_SUCCESS) {
free(e_sector);
return PM3_EMALLOC; return PM3_EMALLOC;
} }

View file

@ -30,8 +30,8 @@ int CmdHFMFNDEFRead(const char *Cmd); // used by "nfc mf cread"
int CmdHFMFNDEFFormat(const char *Cmd); // used by "nfc mf cformat" int CmdHFMFNDEFFormat(const char *Cmd); // used by "nfc mf cformat"
int CmdHFMFNDEFWrite(const char *Cmd); // used by "nfc mf cwrite" int CmdHFMFNDEFWrite(const char *Cmd); // used by "nfc mf cwrite"
void showSectorTable(sector_t *k_sector, uint8_t k_sectorsCount); void showSectorTable(sector_t *k_sector, uint8_t k_sectors_cnt);
void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, bool setEmulatorMem, bool verbose); void readerAttack(sector_t *k_sector, uint8_t k_sectors_cnt, nonces_t data, bool setEmulatorMem, bool verbose);
void printKeyTable(uint8_t sectorscnt, sector_t *e_sector); void printKeyTable(uint8_t sectorscnt, sector_t *e_sector);
void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector); void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector);
void printKeyTable_fast(uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo); void printKeyTable_fast(uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo);

View file

@ -118,8 +118,13 @@ static int CmdNfcDecode(const char *Cmd) {
PrintAndLogEx(SUCCESS, "MFC dump file detected. Converting..."); PrintAndLogEx(SUCCESS, "MFC dump file detected. Converting...");
uint8_t ndef[4096] = {0}; uint8_t ndef[4096] = {0};
uint16_t ndeflen = 0; uint16_t ndeflen = 0;
uint8_t skip = (4 * MFBLOCK_SIZE);
convert_mfc_2_arr(dump + skip, bytes_read - skip, ndef, &ndeflen); if (convert_mad_to_arr(dump, bytes_read, ndef, &ndeflen) != PM3_SUCCESS) {
PrintAndLogEx(FAILED, "Failed converting, aborting...");
free(dump);
return PM3_ESOFT;
}
memcpy(dump, ndef, ndeflen); memcpy(dump, ndef, ndeflen);
bytes_read = ndeflen; bytes_read = ndeflen;
} }

View file

@ -421,3 +421,51 @@ int DetectHID(uint8_t *d, uint16_t manufacture) {
return -1; return -1;
} }
int convert_mad_to_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) {
if (in == NULL || out == NULL || ilen == 0 ) {
return PM3_EINVARG;
}
// MAD detection
if (HasMADKey(in) == false) {
PrintAndLogEx(FAILED, "No MAD key was detected in the dump file");
return PM3_ESOFT;
}
uint8_t sector0[MFBLOCK_SIZE * 4] = {0};
uint8_t sector10[MFBLOCK_SIZE * 4] = {0};
memcpy(sector0, in, sizeof(sector0));
if (ilen == MIFARE_4K_MAX_BYTES) {
memcpy(sector10, in + (MF_MAD2_SECTOR * 4 * MFBLOCK_SIZE), sizeof(sector10));
}
uint16_t mad[7 + 8 + 8 + 8 + 8] = {0};
size_t madlen = 0;
if (MADDecode(sector0, sector10, mad, &madlen, false)) {
PrintAndLogEx(ERR, "can't decode MAD");
return PM3_ESOFT;
}
uint16_t ndef_aid = 0xE103;
for (int i = 0; i < madlen; i++) {
if (ndef_aid == mad[i]) {
uint8_t tmp[MFBLOCK_SIZE * 4] = {0};
memset(tmp, 0x00, sizeof(tmp));
// sector i dump (skip first sector +1)
memcpy(tmp, in + (i + 1) * sizeof(tmp), sizeof(tmp));
// debug print
// print_hex_noascii_break(tmp, sizeof(tmp) - MFBLOCK_SIZE, MFBLOCK_SIZE);
// copy to out (skip ST)
memcpy(out, tmp, sizeof(tmp) - MFBLOCK_SIZE);
out += sizeof(tmp) - MFBLOCK_SIZE;
*olen += sizeof(tmp) -MFBLOCK_SIZE;
}
}
return PM3_SUCCESS;
}

View file

@ -30,4 +30,5 @@ int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose);
void MADPrintHeader(void); void MADPrintHeader(void);
bool HasMADKey(uint8_t *d); bool HasMADKey(uint8_t *d);
int DetectHID(uint8_t *d, uint16_t manufacture); int DetectHID(uint8_t *d, uint16_t manufacture);
int convert_mad_to_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen);
#endif // _MAD_H_ #endif // _MAD_H_

View file

@ -21,8 +21,25 @@
#include "common.h" #include "common.h"
#define MFKEY_SIZE 6 #define MFKEY_SIZE 6
#define MFBLOCK_SIZE 16 #define MFBLOCK_SIZE 16
#define MIFARE_4K_MAXBLOCK 256
#define MIFARE_2K_MAXBLOCK 128
#define MIFARE_1K_MAXBLOCK 64
#define MIFARE_MINI_MAXBLOCK 20
#define MIFARE_4K_MAXSECTOR 40
#define MIFARE_2K_MAXSECTOR 32
#define MIFARE_1K_MAXSECTOR 16
#define MIFARE_MINI_MAXSECTOR 5
#define MIFARE_4K_MAX_BYTES 4096
#define MIFARE_2K_MAX_BYTES 2048
#define MIFARE_1K_MAX_BYTES 1024
#define MIFARE_MINI_MAX_BYTES 320
#define MIFARE_KEY_SIZE 6
static const uint64_t g_mifare_default_keys[] = { static const uint64_t g_mifare_default_keys[] = {
0xffffffffffff, // Default key (first key used by program if no user defined key) 0xffffffffffff, // Default key (first key used by program if no user defined key)

View file

@ -499,6 +499,51 @@ static int ndefDecodePayloadDeviceInfo(uint8_t *payload, size_t len) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int ndefDecodePayloadHandoverRequest(uint8_t *payload, size_t len) {
if (payload == NULL)
return PM3_EINVARG;
if (len < 1)
return PM3_EINVARG;
PrintAndLogEx(INFO, _CYAN_("Handover Request"));
uint8_t *p = payload;
uint8_t major = (*(p) >> 4) & 0x0F;
uint8_t minor = *(p) & 0x0F;
p++;
PrintAndLogEx(INFO, "Version....... " _YELLOW_("%u.%u"), major, minor);
if (major != 1 && minor != 2) {
PrintAndLogEx(FAILED, "Wrong version numbers");
}
uint16_t collision = MemBeToUint2byte(p);
p += 2;
PrintAndLogEx(INFO, "Collision Resolution... " _YELLOW_("%u"), collision);
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int ndefDecodePayloadHandoverSelect(uint8_t *payload, size_t len) {
if (payload == NULL)
return PM3_EINVARG;
if (len < 1)
return PM3_EINVARG;
PrintAndLogEx(INFO, _CYAN_("Handover select"));
uint8_t *p = payload;
uint8_t major = (*(p) >> 4) & 0x0F;
uint8_t minor = *(p) & 0x0F;
p++;
PrintAndLogEx(INFO, "Version....... " _YELLOW_("%u.%u"), major, minor);
if (major != 1 && minor != 2) {
PrintAndLogEx(FAILED, "Wrong version numbers");
}
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int ndefDecodePayloadSmartPoster(uint8_t *ndef, size_t ndeflen, bool print, bool verbose) { static int ndefDecodePayloadSmartPoster(uint8_t *ndef, size_t ndeflen, bool print, bool verbose) {
if (print) { if (print) {
PrintAndLogEx(INFO, _YELLOW_("Well Known Record - Smartposter {")); PrintAndLogEx(INFO, _YELLOW_("Well Known Record - Smartposter {"));
@ -817,7 +862,11 @@ static int ndefDecodeMime_bt(NDEFHeader_t *ndef) {
PrintAndLogEx(INFO, "Type............ " _YELLOW_("%.*s"), (int)ndef->TypeLen, ndef->Type); PrintAndLogEx(INFO, "Type............ " _YELLOW_("%.*s"), (int)ndef->TypeLen, ndef->Type);
uint16_t ooblen = MemBeToUint2byte(ndef->Payload); uint16_t ooblen = MemBeToUint2byte(ndef->Payload);
PrintAndLogEx(INFO, "OOB data len.... %u", ooblen); PrintAndLogEx(INFO, "OOB data len.... %u", ooblen);
PrintAndLogEx(INFO, "BT MAC.......... " _YELLOW_("%s"), sprint_hex(ndef->Payload + 2, 6));
uint8_t rev[6] = {0};
reverse_array_copy(ndef->Payload + 2, 6, rev);
PrintAndLogEx(INFO, "BT MAC.......... " _YELLOW_("%s"), sprint_hex(rev, sizeof(rev)));
// Let's check payload[8]. Tells us a bit about the UUID's. If 0x07 then it tells us a service UUID is 128bit // Let's check payload[8]. Tells us a bit about the UUID's. If 0x07 then it tells us a service UUID is 128bit
switch (ndef->Payload[8]) { switch (ndef->Payload[8]) {
case 0x02: case 0x02:
@ -942,13 +991,11 @@ static int ndefDecodePayload(NDEFHeader_t *ndef, bool verbose) {
} }
if (!strncmp((char *)ndef->Type, "Hr", ndef->TypeLen)) { if (!strncmp((char *)ndef->Type, "Hr", ndef->TypeLen)) {
PrintAndLogEx(INFO, _CYAN_("Handover request")); ndefDecodePayloadHandoverRequest(ndef->Payload, ndef->PayloadLen);
PrintAndLogEx(INFO, "- decoder to be impl -");
} }
if (!strncmp((char *)ndef->Type, "Hs", ndef->TypeLen)) { if (!strncmp((char *)ndef->Type, "Hs", ndef->TypeLen)) {
PrintAndLogEx(INFO, _CYAN_("Handover select")); ndefDecodePayloadHandoverSelect(ndef->Payload, ndef->PayloadLen);
PrintAndLogEx(INFO, "- decoder to be impl -");
} }
if (!strncmp((char *)ndef->Type, "ac", ndef->TypeLen)) { if (!strncmp((char *)ndef->Type, "ac", ndef->TypeLen)) {

View file

@ -388,6 +388,7 @@ while true; do
if ! CheckExecute "nfc decode test - device info" "$CLIENTBIN -c 'nfc decode -d d1025744690004536f6e79010752432d533338300220426c61636b204e46432052656164657220636f6e6e656374656420746f2050430310123e4567e89b12d3a45642665544000004124e464320506f72742d3130302076312e3032'" "NFC Port-100 v1.02"; then break; fi if ! CheckExecute "nfc decode test - device info" "$CLIENTBIN -c 'nfc decode -d d1025744690004536f6e79010752432d533338300220426c61636b204e46432052656164657220636f6e6e656374656420746f2050430310123e4567e89b12d3a45642665544000004124e464320506f72742d3130302076312e3032'" "NFC Port-100 v1.02"; then break; fi
if ! CheckExecute "nfc decode test - vcard" "$CLIENTBIN -c 'nfc decode -d d20ca3746578742f782d7643617264424547494e3a56434152440a56455253494f4e3a332e300a4e3a43687269733b4963656d616e3b3b3b0a464e3a476f7468656e627572670a5245563a323032312d30362d32345432303a31353a30385a0a6974656d322e582d4142444154453b747970653d707265663a323032302d30362d32340a4954454d322e582d41424c4142454c3a5f24213c416e6e69766572736172793e21245f0a454e443a56434152440a'" "END:VCARD"; then break; fi if ! CheckExecute "nfc decode test - vcard" "$CLIENTBIN -c 'nfc decode -d d20ca3746578742f782d7643617264424547494e3a56434152440a56455253494f4e3a332e300a4e3a43687269733b4963656d616e3b3b3b0a464e3a476f7468656e627572670a5245563a323032312d30362d32345432303a31353a30385a0a6974656d322e582d4142444154453b747970653d707265663a323032302d30362d32340a4954454d322e582d41424c4142454c3a5f24213c416e6e69766572736172793e21245f0a454e443a56434152440a'" "END:VCARD"; then break; fi
if ! CheckExecute "nfc decode test - apple wallet" "$CLIENTBIN -c 'nfc decode -d 031AD10116550077616C6C65743A2F2F61637469766174652F6E6663FE'" "activate/nfc"; then break; fi if ! CheckExecute "nfc decode test - apple wallet" "$CLIENTBIN -c 'nfc decode -d 031AD10116550077616C6C65743A2F2F61637469766174652F6E6663FE'" "activate/nfc"; then break; fi
if ! CheckExecute "nfc decode test - signature" "$CLIENTBIN -c 'nfc decode -d 03FF010194113870696C65742E65653A656B616172743A3266195F26063132303832325904202020205F28033233335F2701316E1B5A13333038363439303039303030323636343030355304EBF2CE704103000000AC536967010200803A2448FCA7D354A654A81BD021150D1A152D1DF4D7A55D2B771F12F094EAB6E5E10F2617A2F8DAD4FD38AFF8EA39B71C19BD42618CDA86EE7E144636C8E0E7CFC4096E19C3680E09C78A0CDBC05DA2D698E551D5D709717655E56FE3676880B897D2C70DF5F06ECE07C71435255144F8EE41AF110E7B180DA0E6C22FB8FDEF61800025687474703A2F2F70696C65742E65652F6372742F33303836343930302D303030312E637274FE'" "30864900-0001.crt"; then break; fi
echo -e "\n${C_BLUE}Testing LF:${C_NC}" echo -e "\n${C_BLUE}Testing LF:${C_NC}"
if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi if ! CheckExecute "lf AWID test" "$CLIENTBIN -c 'data load -f traces/lf_AWID-15-259.pm3;lf search -1'" "AWID ID found"; then break; fi