Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgornekich <n.gorbadey@gmail.com>2021-08-04 21:58:11 +0300
committerGitHub <noreply@github.com>2021-08-04 21:58:11 +0300
commit5741ed2bd5ef9b8c9cdb07459df034625c624d33 (patch)
tree46479fcac62edd8fe75b02d2b431946567f09295 /applications/nfc
parent841804026e5cfe2692d199ffff31763347c8dc58 (diff)
[FL-1595] Add EMV tags (#625)
* nfc: add expiration date tag to emv parser * nfc: add expiration date save and display * nfc: add long apdu test command
Diffstat (limited to 'applications/nfc')
-rwxr-xr-xapplications/nfc/nfc_device.c12
-rw-r--r--applications/nfc/nfc_device.h2
-rwxr-xr-xapplications/nfc/nfc_worker.c70
-rwxr-xr-xapplications/nfc/nfc_worker.h2
-rwxr-xr-xapplications/nfc/nfc_worker_i.h2
-rw-r--r--applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c2
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_read_emv_data_success.c6
-rwxr-xr-xapplications/nfc/views/bank_card.c4
-rw-r--r--applications/nfc/views/bank_card.h2
9 files changed, 89 insertions, 13 deletions
diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c
index d0575e1b..bfe0e877 100755
--- a/applications/nfc/nfc_device.c
+++ b/applications/nfc/nfc_device.c
@@ -203,6 +203,10 @@ uint16_t nfc_device_prepare_bank_card_string(NfcDevice* dev, string_t bank_card_
for(uint8_t i = 0; i < sizeof(data->number); i++) {
string_cat_printf(bank_card_string, " %02X", data->number[i]);
}
+ if(data->exp_mon) {
+ string_cat_printf(
+ bank_card_string, "\nExp date: %02X/%02X", data->exp_mon, data->exp_year);
+ }
return string_size(bank_card_string);
}
@@ -236,6 +240,14 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string
break;
}
parsed = true;
+ // Check expiration date presence
+ ws = string_search_str(bank_card_string, "Exp date: ");
+ if(ws != STRING_FAILURE) {
+ // strlen("Exp date: ") = 10
+ string_right(bank_card_string, 10);
+ nfc_device_read_hex(bank_card_string, &data->exp_mon, 1);
+ nfc_device_read_hex(bank_card_string, &data->exp_year, 1);
+ }
} while(0);
return parsed;
diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h
index ab644615..c2de3120 100644
--- a/applications/nfc/nfc_device.h
+++ b/applications/nfc/nfc_device.h
@@ -42,7 +42,7 @@ typedef struct {
uint16_t aid_len;
uint8_t number[8];
uint8_t exp_mon;
- uint16_t exp_year;
+ uint8_t exp_year;
char cardholder[32];
} NfcEmvData;
diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c
index c5c9ed76..30aecbfd 100755
--- a/applications/nfc/nfc_worker.c
+++ b/applications/nfc/nfc_worker.c
@@ -81,8 +81,8 @@ void nfc_worker_task(void* context) {
nfc_worker_read_emv_app(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateReadEMV) {
nfc_worker_read_emv(nfc_worker);
- } else if(nfc_worker->state == NfcWorkerStateEmulateEMV) {
- nfc_worker_emulate_emv(nfc_worker);
+ } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) {
+ nfc_worker_emulate_apdu(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateReadMifareUl) {
nfc_worker_read_mifare_ul(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
@@ -324,6 +324,10 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) {
result->emv_data.number,
emv_app.card_number,
sizeof(emv_app.card_number));
+ if(emv_app.exp_month) {
+ result->emv_data.exp_mon = emv_app.exp_month;
+ result->emv_data.exp_year = emv_app.exp_year;
+ }
// Notify caller and exit
if(nfc_worker->callback) {
nfc_worker->callback(nfc_worker->context);
@@ -348,7 +352,7 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) {
}
}
-void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
+void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) {
ReturnCode err;
uint8_t tx_buff[255] = {};
uint16_t tx_len = 0;
@@ -362,8 +366,46 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
.device = NfcDeviceNfca,
.protocol = NfcDeviceProtocolEMV,
};
-
- while(nfc_worker->state == NfcWorkerStateEmulateEMV) {
+ // Test RX data
+ const uint8_t debug_rx[] = {
+ 0xba, 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca,
+ 0xca, 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba,
+ 0x0b, 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca,
+ 0xfe, 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b,
+ 0xba, 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe,
+ 0xfa, 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
+ 0xbb, 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba,
+ 0xba, 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa,
+ 0xce, 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
+ 0xcc, 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba,
+ 0x20, 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce,
+ 0x14, 0x88, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
+ 0xdd, 0xee, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xba, 0x0b, 0xba, 0xba, 0x20,
+ 0x00, 0x02, 0x28, 0xde, 0xad, 0xbe, 0xef, 0x00, 0xca, 0xca, 0xca, 0xfe, 0xfa, 0xce, 0x14,
+ 0x88, 0x00};
+ // Test TX data
+ const uint8_t debug_tx[] = {
+ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
+ 0x10, 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad,
+ 0xbe, 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12,
+ 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+ 0x14, 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe,
+ 0xef, 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34,
+ 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14,
+ 0x88, 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef,
+ 0xce, 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56,
+ 0x78, 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88,
+ 0x02, 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce,
+ 0xee, 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78,
+ 0x9a, 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02,
+ 0x28, 0x00, 0x00, 0xca, 0xca, 0x00, 0xc0, 0xc0, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xce, 0xee,
+ 0xec, 0xca, 0xfe, 0xba, 0xba, 0xb0, 0xb0, 0xac, 0xdc, 0x11, 0x12, 0x34, 0x56, 0x78, 0x9a,
+ 0xbc, 0xde, 0xff, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x14, 0x88, 0x02, 0x28,
+ 0x00, 0x00};
+
+ while(nfc_worker->state == NfcWorkerStateEmulateApdu) {
if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 300)) {
FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected");
// Read data from POS terminal
@@ -401,7 +443,23 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) {
tx_len = emv_get_proc_opt_ans(tx_buff);
err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
if(err == ERR_NONE) {
- FURI_LOG_I(NFC_WORKER_TAG, "Received PDOL");
+ FURI_LOG_I(NFC_WORKER_TAG, "Transive PDOL ANS");
+ } else {
+ FURI_LOG_E(NFC_WORKER_TAG, "Error in 4rd data exchange: Transive PDOL ANS");
+ api_hal_nfc_deactivate();
+ continue;
+ }
+
+ if(*rx_len != sizeof(debug_rx) || memcmp(rx_buff, debug_rx, sizeof(debug_rx))) {
+ FURI_LOG_E(NFC_WORKER_TAG, "Failed long message test");
+ } else {
+ FURI_LOG_I(NFC_WORKER_TAG, "Correct debug message received");
+ tx_len = sizeof(debug_tx);
+ err = api_hal_nfc_data_exchange(
+ (uint8_t*)debug_tx, tx_len, &rx_buff, &rx_len, false);
+ if(err == ERR_NONE) {
+ FURI_LOG_I(NFC_WORKER_TAG, "Transive Debug message");
+ }
}
api_hal_nfc_deactivate();
} else {
diff --git a/applications/nfc/nfc_worker.h b/applications/nfc/nfc_worker.h
index 4719cb21..519ec7a2 100755
--- a/applications/nfc/nfc_worker.h
+++ b/applications/nfc/nfc_worker.h
@@ -14,7 +14,7 @@ typedef enum {
NfcWorkerStateEmulate,
NfcWorkerStateReadEMVApp,
NfcWorkerStateReadEMV,
- NfcWorkerStateEmulateEMV,
+ NfcWorkerStateEmulateApdu,
NfcWorkerStateField,
NfcWorkerStateReadMifareUl,
NfcWorkerStateEmulateMifareUl,
diff --git a/applications/nfc/nfc_worker_i.h b/applications/nfc/nfc_worker_i.h
index 9df5707d..79c64225 100755
--- a/applications/nfc/nfc_worker_i.h
+++ b/applications/nfc/nfc_worker_i.h
@@ -36,7 +36,7 @@ void nfc_worker_read_emv_app(NfcWorker* nfc_worker);
void nfc_worker_read_emv(NfcWorker* nfc_worker);
-void nfc_worker_emulate_emv(NfcWorker* nfc_worker);
+void nfc_worker_emulate_apdu(NfcWorker* nfc_worker);
void nfc_worker_detect(NfcWorker* nfc_worker);
diff --git a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c
index 2f5018c8..70288054 100644
--- a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c
+++ b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c
@@ -11,7 +11,7 @@ const void nfc_scene_emulate_apdu_sequence_on_enter(void* context) {
// Setup and start worker
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
- nfc_worker_start(nfc->worker, NfcWorkerStateEmulateEMV, &nfc->dev.dev_data, NULL, nfc);
+ nfc_worker_start(nfc->worker, NfcWorkerStateEmulateApdu, &nfc->dev.dev_data, NULL, nfc);
}
const bool nfc_scene_emulate_apdu_sequence_on_event(void* context, SceneManagerEvent event) {
diff --git a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c
index 74f15a22..c6a9280c 100755
--- a/applications/nfc/scenes/nfc_scene_read_emv_data_success.c
+++ b/applications/nfc/scenes/nfc_scene_read_emv_data_success.c
@@ -59,6 +59,12 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) {
char sak_str[16];
snprintf(sak_str, sizeof(sak_str), "SAK: %02X", nfc_data->sak);
widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, sak_str);
+ if(emv_data->exp_mon) {
+ char exp_str[16];
+ snprintf(
+ exp_str, sizeof(exp_str), "Exp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year);
+ widget_add_string_element(nfc->widget, 7, 32, AlignLeft, AlignTop, FontSecondary, exp_str);
+ }
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
diff --git a/applications/nfc/views/bank_card.c b/applications/nfc/views/bank_card.c
index a483fcff..f4354792 100755
--- a/applications/nfc/views/bank_card.c
+++ b/applications/nfc/views/bank_card.c
@@ -49,10 +49,10 @@ void bank_card_set_number(BankCard* bank_card, uint8_t* number) {
string_clear(num_str);
}
-void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint16_t year) {
+void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year) {
furi_assert(bank_card);
char exp_date_str[16];
- snprintf(exp_date_str, sizeof(exp_date_str), "Exp: %02d/%02d", mon, year % 100);
+ snprintf(exp_date_str, sizeof(exp_date_str), "Exp: %02X/%02X", mon, year);
widget_add_string_element(
bank_card->widget, 122, 54, AlignRight, AlignBottom, FontSecondary, exp_date_str);
}
diff --git a/applications/nfc/views/bank_card.h b/applications/nfc/views/bank_card.h
index 40472c87..f7252a80 100644
--- a/applications/nfc/views/bank_card.h
+++ b/applications/nfc/views/bank_card.h
@@ -18,6 +18,6 @@ void bank_card_set_name(BankCard* bank_card, char* name);
void bank_card_set_number(BankCard* bank_card, uint8_t* number);
-void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint16_t year);
+void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year);
void bank_card_set_cardholder_name(BankCard* bank_card, char* name);