mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
[EMV] Add Effective date and Preferred Name
This commit is contained in:
@@ -88,11 +88,32 @@ void nfc_render_emv_application(const EmvApplication* apl, FuriString* str) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
furi_string_cat_printf(str, "AID: ");
|
furi_string_cat_printf(str, "Application:\n");
|
||||||
|
|
||||||
|
if(strlen(apl->label)) {
|
||||||
|
furi_string_cat_printf(str, " Label: %s", apl->label);
|
||||||
|
furi_string_cat_printf(str, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strlen(apl->name)) {
|
||||||
|
furi_string_cat_printf(str, " Name: %s", apl->name);
|
||||||
|
furi_string_cat_printf(str, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_string_cat_printf(str, " AID:");
|
||||||
for(uint8_t i = 0; i < len; i++) furi_string_cat_printf(str, "%02X", apl->aid[i]);
|
for(uint8_t i = 0; i < len; i++) furi_string_cat_printf(str, "%02X", apl->aid[i]);
|
||||||
|
|
||||||
furi_string_cat_printf(str, "\n");
|
furi_string_cat_printf(str, "\n");
|
||||||
|
|
||||||
|
if(apl->eff_month) {
|
||||||
|
furi_string_cat_printf(
|
||||||
|
str, " Effective: 20%02X/%02X/%02X", apl->eff_year, apl->eff_month, apl->eff_day);
|
||||||
|
furi_string_cat_printf(str, "\n");
|
||||||
|
}
|
||||||
|
if(apl->exp_month) {
|
||||||
|
furi_string_cat_printf(
|
||||||
|
str, " Expire: 20%02X/%02X/%02X", apl->exp_year, apl->exp_month, apl->exp_day);
|
||||||
|
furi_string_cat_printf(str, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfc_render_emv_pin_try_counter(uint8_t counter, FuriString* str) {
|
static void nfc_render_emv_pin_try_counter(uint8_t counter, FuriString* str) {
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ static bool emv_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||||||
const EmvApplication app = data->emv_application;
|
const EmvApplication app = data->emv_application;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(app.name_found)
|
if(strlen(app.label))
|
||||||
furi_string_cat_printf(parsed_data, "\e#%s\n", app.name);
|
furi_string_cat_printf(parsed_data, "\e#%s\n", app.label);
|
||||||
else
|
else
|
||||||
furi_string_cat_printf(parsed_data, "\e#%s\n", "EMV");
|
furi_string_cat_printf(parsed_data, "\e#%s\n", "EMV");
|
||||||
|
|
||||||
|
|||||||
@@ -76,10 +76,12 @@ bool emv_load(EmvData* data, FlipperFormat* ff, uint32_t version) {
|
|||||||
|
|
||||||
EmvApplication* app = &data->emv_application;
|
EmvApplication* app = &data->emv_application;
|
||||||
|
|
||||||
//Read name
|
|
||||||
if(!flipper_format_read_string(ff, "Name", temp_str)) break;
|
if(!flipper_format_read_string(ff, "Name", temp_str)) break;
|
||||||
strcpy(app->name, furi_string_get_cstr(temp_str));
|
strcpy(app->name, furi_string_get_cstr(temp_str));
|
||||||
if(app->name[0] != '\0') app->name_found = true;
|
|
||||||
|
//Read label
|
||||||
|
if(!flipper_format_read_string(ff, "Label", temp_str)) break;
|
||||||
|
strcpy(app->label, furi_string_get_cstr(temp_str));
|
||||||
|
|
||||||
uint32_t pan_len;
|
uint32_t pan_len;
|
||||||
if(!flipper_format_read_uint32(ff, "PAN length", &pan_len, 1)) break;
|
if(!flipper_format_read_uint32(ff, "PAN length", &pan_len, 1)) break;
|
||||||
@@ -99,6 +101,11 @@ bool emv_load(EmvData* data, FlipperFormat* ff, uint32_t version) {
|
|||||||
|
|
||||||
if(!flipper_format_read_hex(ff, "Expiration year", &app->exp_year, 1)) break;
|
if(!flipper_format_read_hex(ff, "Expiration year", &app->exp_year, 1)) break;
|
||||||
if(!flipper_format_read_hex(ff, "Expiration month", &app->exp_month, 1)) break;
|
if(!flipper_format_read_hex(ff, "Expiration month", &app->exp_month, 1)) break;
|
||||||
|
if(!flipper_format_read_hex(ff, "Expiration day", &app->exp_day, 1)) break;
|
||||||
|
|
||||||
|
if(!flipper_format_read_hex(ff, "Effective year", &app->eff_year, 1)) break;
|
||||||
|
if(!flipper_format_read_hex(ff, "Effective month", &app->eff_month, 1)) break;
|
||||||
|
if(!flipper_format_read_hex(ff, "Effective day", &app->eff_day, 1)) break;
|
||||||
|
|
||||||
uint32_t pin_try_counter;
|
uint32_t pin_try_counter;
|
||||||
if(!flipper_format_read_uint32(ff, "PIN counter", &pin_try_counter, 1)) break;
|
if(!flipper_format_read_uint32(ff, "PIN counter", &pin_try_counter, 1)) break;
|
||||||
@@ -126,6 +133,8 @@ bool emv_save(const EmvData* data, FlipperFormat* ff) {
|
|||||||
|
|
||||||
if(!flipper_format_write_string_cstr(ff, "Name", app.name)) break;
|
if(!flipper_format_write_string_cstr(ff, "Name", app.name)) break;
|
||||||
|
|
||||||
|
if(!flipper_format_write_string_cstr(ff, "Label", app.label)) break;
|
||||||
|
|
||||||
uint32_t pan_len = app.pan_len;
|
uint32_t pan_len = app.pan_len;
|
||||||
if(!flipper_format_write_uint32(ff, "PAN length", &pan_len, 1)) break;
|
if(!flipper_format_write_uint32(ff, "PAN length", &pan_len, 1)) break;
|
||||||
|
|
||||||
@@ -141,8 +150,12 @@ bool emv_save(const EmvData* data, FlipperFormat* ff) {
|
|||||||
if(!flipper_format_write_hex(ff, "Currency code", (uint8_t*)&app.currency_code, 2)) break;
|
if(!flipper_format_write_hex(ff, "Currency code", (uint8_t*)&app.currency_code, 2)) break;
|
||||||
|
|
||||||
if(!flipper_format_write_hex(ff, "Expiration year", (uint8_t*)&app.exp_year, 1)) break;
|
if(!flipper_format_write_hex(ff, "Expiration year", (uint8_t*)&app.exp_year, 1)) break;
|
||||||
|
|
||||||
if(!flipper_format_write_hex(ff, "Expiration month", (uint8_t*)&app.exp_month, 1)) break;
|
if(!flipper_format_write_hex(ff, "Expiration month", (uint8_t*)&app.exp_month, 1)) break;
|
||||||
|
if(!flipper_format_write_hex(ff, "Expiration day", (uint8_t*)&app.exp_day, 1)) break;
|
||||||
|
|
||||||
|
if(!flipper_format_write_hex(ff, "Effective year", (uint8_t*)&app.eff_year, 1)) break;
|
||||||
|
if(!flipper_format_write_hex(ff, "Effective month", (uint8_t*)&app.eff_month, 1)) break;
|
||||||
|
if(!flipper_format_write_hex(ff, "Effective day", (uint8_t*)&app.eff_day, 1)) break;
|
||||||
|
|
||||||
if(!flipper_format_write_uint32(ff, "PIN counter", (uint32_t*)&app.pin_try_counter, 1))
|
if(!flipper_format_write_uint32(ff, "PIN counter", (uint32_t*)&app.pin_try_counter, 1))
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ extern "C" {
|
|||||||
|
|
||||||
#define EMV_REQ_GET_DATA 0x80CA
|
#define EMV_REQ_GET_DATA 0x80CA
|
||||||
|
|
||||||
#define EMV_TAG_APP_TEMPLATE 0x61
|
|
||||||
#define EMV_TAG_AID 0x4F
|
#define EMV_TAG_AID 0x4F
|
||||||
#define EMV_TAG_PRIORITY 0x87
|
#define EMV_TAG_PRIORITY 0x87
|
||||||
#define EMV_TAG_PDOL 0x9F38
|
#define EMV_TAG_PDOL 0x9F38
|
||||||
#define EMV_TAG_CARD_NAME 0x50
|
#define EMV_TAG_APPL_LABEL 0x50
|
||||||
#define EMV_TAG_FCI 0xBF0C
|
#define EMV_TAG_APPL_NAME 0x9F12
|
||||||
|
#define EMV_TAG_APPL_EFFECTIVE 0x5F25
|
||||||
#define EMV_TAG_PIN_TRY_COUNTER 0x9F17
|
#define EMV_TAG_PIN_TRY_COUNTER 0x9F17
|
||||||
#define EMV_TAG_LOG_ENTRY 0x9F4D
|
#define EMV_TAG_LOG_ENTRY 0x9F4D
|
||||||
#define EMV_TAG_LOG_FMT 0x9F4F
|
#define EMV_TAG_LOG_FMT 0x9F4F
|
||||||
@@ -42,6 +42,12 @@ extern "C" {
|
|||||||
#define EMV_TAG_RESP_BUF_SIZE 0x6C
|
#define EMV_TAG_RESP_BUF_SIZE 0x6C
|
||||||
#define EMV_TAG_RESP_BYTES_AVAILABLE 0x61
|
#define EMV_TAG_RESP_BYTES_AVAILABLE 0x61
|
||||||
|
|
||||||
|
// Not used tags
|
||||||
|
#define EMV_TAG_FORM_FACTOR 0x9F6E
|
||||||
|
#define EMV_TAG_APP_TEMPLATE 0x61
|
||||||
|
#define EMV_TAG_FCI 0xBF0C
|
||||||
|
#define EMV_TAG_DEPOSIT_LOG_ENTRY 0xDF4D
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t tag;
|
uint16_t tag;
|
||||||
uint8_t data[];
|
uint8_t data[];
|
||||||
@@ -72,12 +78,16 @@ typedef struct {
|
|||||||
uint8_t priority;
|
uint8_t priority;
|
||||||
uint8_t aid[16];
|
uint8_t aid[16];
|
||||||
uint8_t aid_len;
|
uint8_t aid_len;
|
||||||
char name[32];
|
char name[16 + 1];
|
||||||
bool name_found;
|
char label[16 + 1];
|
||||||
uint8_t pan[10]; // card_number
|
uint8_t pan[10]; // card_number
|
||||||
uint8_t pan_len;
|
uint8_t pan_len;
|
||||||
|
uint8_t exp_day;
|
||||||
uint8_t exp_month;
|
uint8_t exp_month;
|
||||||
uint8_t exp_year;
|
uint8_t exp_year;
|
||||||
|
uint8_t eff_day;
|
||||||
|
uint8_t eff_month;
|
||||||
|
uint8_t eff_year;
|
||||||
uint16_t country_code;
|
uint16_t country_code;
|
||||||
uint16_t currency_code;
|
uint16_t currency_code;
|
||||||
uint8_t pin_try_counter;
|
uint8_t pin_try_counter;
|
||||||
|
|||||||
@@ -114,12 +114,25 @@ static bool
|
|||||||
success = true;
|
success = true;
|
||||||
FURI_LOG_T(TAG, "found EMV_TAG_APP_PRIORITY %X: %d", tag, app->priority);
|
FURI_LOG_T(TAG, "found EMV_TAG_APP_PRIORITY %X: %d", tag, app->priority);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_CARD_NAME:
|
case EMV_TAG_APPL_LABEL:
|
||||||
|
memcpy(app->label, &buff[i], tlen);
|
||||||
|
app->label[tlen] = '\0';
|
||||||
|
success = true;
|
||||||
|
FURI_LOG_T(TAG, "found EMV_TAG_APPL_LABEL %x: %s", tag, app->label);
|
||||||
|
break;
|
||||||
|
case EMV_TAG_APPL_NAME:
|
||||||
|
furi_check(tlen < sizeof(app->name));
|
||||||
memcpy(app->name, &buff[i], tlen);
|
memcpy(app->name, &buff[i], tlen);
|
||||||
app->name[tlen] = '\0';
|
app->name[tlen] = '\0';
|
||||||
app->name_found = true;
|
|
||||||
success = true;
|
success = true;
|
||||||
FURI_LOG_T(TAG, "found EMV_TAG_CARD_NAME %x : %s", tag, app->name);
|
FURI_LOG_T(TAG, "found EMV_TAG_APPL_NAME %x: %s", tag, app->name);
|
||||||
|
break;
|
||||||
|
case EMV_TAG_APPL_EFFECTIVE:
|
||||||
|
app->eff_year = buff[i];
|
||||||
|
app->eff_month = buff[i + 1];
|
||||||
|
app->eff_day = buff[i + 2];
|
||||||
|
success = true;
|
||||||
|
FURI_LOG_T(TAG, "found EMV_TAG_APPL_EFFECTIVE %x:", tag);
|
||||||
break;
|
break;
|
||||||
case EMV_TAG_PDOL:
|
case EMV_TAG_PDOL:
|
||||||
memcpy(app->pdol.data, &buff[i], tlen);
|
memcpy(app->pdol.data, &buff[i], tlen);
|
||||||
@@ -192,6 +205,7 @@ static bool
|
|||||||
case EMV_TAG_EXP_DATE:
|
case EMV_TAG_EXP_DATE:
|
||||||
app->exp_year = buff[i];
|
app->exp_year = buff[i];
|
||||||
app->exp_month = buff[i + 1];
|
app->exp_month = buff[i + 1];
|
||||||
|
app->exp_day = buff[i + 2];
|
||||||
success = true;
|
success = true;
|
||||||
FURI_LOG_T(TAG, "found EMV_TAG_EXP_DATE %x", tag);
|
FURI_LOG_T(TAG, "found EMV_TAG_EXP_DATE %x", tag);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user