From fe2b5fa21e0e4184c58742c2f8b5ce3e743b66b5 Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Tue, 25 Oct 2022 10:05:59 +0200 Subject: [PATCH 01/12] MRTD recognize MRTDs properly --- lib/nfc/nfc_worker.c | 16 +++--- lib/nfc/protocols/mrtd.c | 109 ++++++++++++++++++++++++--------------- lib/nfc/protocols/mrtd.h | 6 +-- 3 files changed, 80 insertions(+), 51 deletions(-) diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index b6269ea7e..412d5229d 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -280,13 +280,17 @@ static bool nfc_worker_read_mrtd(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t // Read passport if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break; - //TODO: if(!mrtd_select_app(mrtd_app, AID.eMRTDApplication)) break; - - mrtd_test(mrtd_app, mrtd_data); // Some EFs are only available before Select App //TODO: try select eMRTDApp first, but when PACE, read CardAccess first! + if(!mrtd_select_app(mrtd_app, AID.eMRTDApplication)) break; // Passport app not selected - //TODO: read general informatie - //TODO: after auth scene, do auth (BAC / PACE) + // At least we're dealing with a passport. So return true. + read_success = true; + + if(!mrtd_authenticate(mrtd_app, mrtd_data)) break; // Authentication failed + //TODO: show auth failure screen + + mrtd_read_parse_file(mrtd_app, mrtd_data, EF.COM); + mrtd_read_parse_file(mrtd_app, mrtd_data, EF.DG1); read_success = true; } while(false); @@ -850,4 +854,4 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) { reader_analyzer_stop(nfc_worker->reader_analyzer); nfca_signal_free(nfca_signal); -} \ No newline at end of file +} diff --git a/lib/nfc/protocols/mrtd.c b/lib/nfc/protocols/mrtd.c index 2f10584ce..ce4fa9177 100644 --- a/lib/nfc/protocols/mrtd.c +++ b/lib/nfc/protocols/mrtd.c @@ -422,48 +422,6 @@ bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file return result; } -//TODO: remove testing function -void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data) { - FURI_LOG_D(TAG, "Mrtd Test"); - //mrtd_read_dump(app, EF.ATR); - //mrtd_read_dump(app, EF.COM); - //mrtd_read_dump(app, EF.DIR); - //mrtd_read_dump(app, EF.CardAccess); - //mrtd_read_dump(app, EF.CardSecurity); - - mrtd_select_app(app, AID.eMRTDApplication); - - MrtdAuthMethod method = mrtd_data->auth.method; - mrtd_data->auth_success = false; - FURI_LOG_D(TAG, "Auth method: %d", method); - switch(method) { - case MrtdAuthMethodAny: - //TODO: try PACE, then BAC - case MrtdAuthMethodBac: - mrtd_data->auth_success = mrtd_bac(app, &mrtd_data->auth); - break; - case MrtdAuthMethodPace: - FURI_LOG_E(TAG, "Auth method PACE not implemented"); - break; - case MrtdAuthMethodNone: - default: - break; - } - - if(!mrtd_data->auth_success) { - return; - } - - mrtd_read_parse_file(app, mrtd_data, EF.COM); - //mrtd_read_parse_file(app, mrtd_data, EF.DIR); - - mrtd_read_parse_file(app, mrtd_data, EF.DG1); - - //mrtd_read_dump(app, EF.DG2); - //mrtd_read_dump(app, EF.DG14); - //mrtd_read_dump(app, EF.DG15); -} - MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx) { MrtdApplication* app = malloc(sizeof(MrtdApplication)); @@ -570,3 +528,70 @@ bool mrtd_bac(MrtdApplication* app, MrtdAuthData* auth) { return true; } + +bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data) { + MrtdAuthMethod method = mrtd_data->auth.method; + mrtd_data->auth_success = false; + FURI_LOG_D(TAG, "Auth method: %d", method); + switch(method) { + case MrtdAuthMethodAny: + //TODO: try PACE, then BAC. For now, fall through to just BAC + case MrtdAuthMethodBac: + mrtd_data->auth_success = mrtd_bac(app, &mrtd_data->auth); + break; + case MrtdAuthMethodPace: + FURI_LOG_E(TAG, "Auth method PACE not implemented"); + break; + case MrtdAuthMethodNone: + default: + break; + } + + if(!mrtd_data->auth_success) { + return false; + } + + return true; +} + +//TODO: remove testing function +void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data) { + FURI_LOG_D(TAG, "Mrtd Test"); + //mrtd_read_dump(app, EF.ATR); + //mrtd_read_dump(app, EF.COM); + //mrtd_read_dump(app, EF.DIR); + //mrtd_read_dump(app, EF.CardAccess); + //mrtd_read_dump(app, EF.CardSecurity); + + mrtd_select_app(app, AID.eMRTDApplication); + + MrtdAuthMethod method = mrtd_data->auth.method; + mrtd_data->auth_success = false; + FURI_LOG_D(TAG, "Auth method: %d", method); + switch(method) { + case MrtdAuthMethodAny: + //TODO: try PACE, then BAC + case MrtdAuthMethodBac: + mrtd_data->auth_success = mrtd_bac(app, &mrtd_data->auth); + break; + case MrtdAuthMethodPace: + FURI_LOG_E(TAG, "Auth method PACE not implemented"); + break; + case MrtdAuthMethodNone: + default: + break; + } + + if(!mrtd_data->auth_success) { + return; + } + + mrtd_read_parse_file(app, mrtd_data, EF.COM); + //mrtd_read_parse_file(app, mrtd_data, EF.DIR); + + mrtd_read_parse_file(app, mrtd_data, EF.DG1); + + //mrtd_read_dump(app, EF.DG2); + //mrtd_read_dump(app, EF.DG14); + //mrtd_read_dump(app, EF.DG15); +} diff --git a/lib/nfc/protocols/mrtd.h b/lib/nfc/protocols/mrtd.h index c51f4f660..e4d032f88 100644 --- a/lib/nfc/protocols/mrtd.h +++ b/lib/nfc/protocols/mrtd.h @@ -27,7 +27,7 @@ typedef struct { //TODO: description MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx); +void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data); //TODO: remove bool mrtd_select_app(MrtdApplication* app, AIDValue aid); -bool mrtd_select_file(MrtdApplication* app, EFFile file); -void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data); -bool mrtd_bac(MrtdApplication* app, MrtdAuthData* auth); +bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data); +bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file); From c3d7417c2536f9d64e6ac98acf2d781268160848 Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Tue, 25 Oct 2022 10:33:36 +0200 Subject: [PATCH 02/12] MRTD show auth failure message --- .../main/nfc/scenes/nfc_scene_passport_read.c | 9 +++++++-- lib/nfc/nfc_worker.c | 16 +++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_passport_read.c b/applications/main/nfc/scenes/nfc_scene_passport_read.c index 3f5ce66f8..be8077682 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_read.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_read.c @@ -11,6 +11,7 @@ void nfc_scene_passport_read_widget_callback(GuiButtonType result, InputType typ void nfc_scene_passport_read_on_enter(void* context) { Nfc* nfc = context; FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data; + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; DOLPHIN_DEED(DolphinDeedNfcReadSuccess); @@ -40,7 +41,11 @@ void nfc_scene_passport_read_on_enter(void* context) { furi_string_cat_printf(temp_str, " %02X", data->uid[i]); } furi_string_cat_printf(temp_str, "\nATQA: %02X %02X ", data->atqa[1], data->atqa[0]); - furi_string_cat_printf(temp_str, " SAK: %02X", data->sak); + furi_string_cat_printf(temp_str, " SAK: %02X\n", data->sak); + + if(mrtd_data->auth.method != MrtdAuthMethodNone && !mrtd_data->auth_success) { + furi_string_cat_printf(temp_str, "Auth failed. Wrong params?"); + } widget_add_text_scroll_element(widget, 0, 0, 128, 52, furi_string_get_cstr(temp_str)); furi_string_free(temp_str); @@ -82,4 +87,4 @@ void nfc_scene_passport_read_on_exit(void* context) { // Clear view widget_reset(nfc->widget); -} \ No newline at end of file +} diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 412d5229d..a0728d928 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -283,11 +283,18 @@ static bool nfc_worker_read_mrtd(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t //TODO: try select eMRTDApp first, but when PACE, read CardAccess first! if(!mrtd_select_app(mrtd_app, AID.eMRTDApplication)) break; // Passport app not selected - // At least we're dealing with a passport. So return true. - read_success = true; + if(mrtd_data->auth.method == MrtdAuthMethodNone) { + // Selected the passport app, but auth. not selected + // Successfully read what we could + read_success = true; + break; + } - if(!mrtd_authenticate(mrtd_app, mrtd_data)) break; // Authentication failed - //TODO: show auth failure screen + if(!mrtd_authenticate(mrtd_app, mrtd_data)) { + // At least we're reading an MRTD and should the app switch to the NFC scenes + read_success = true; + break; // Authentication failed + } mrtd_read_parse_file(mrtd_app, mrtd_data, EF.COM); mrtd_read_parse_file(mrtd_app, mrtd_data, EF.DG1); @@ -337,7 +344,6 @@ static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t furi_hal_nfc_sleep(); // Needed between checks FURI_LOG_D(TAG, "Try reading MRTD"); - //TODO: support NFC-B? if(nfc_worker_read_mrtd(nfc_worker, tx_rx)) { nfc_worker->dev_data->protocol = NfcDeviceProtocolMRTD; break; From 46878d152670f6422b3904b4411c3caf40c1433c Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Wed, 26 Oct 2022 13:04:53 +0200 Subject: [PATCH 03/12] MRTD show auth method used --- .../main/nfc/scenes/nfc_scene_passport_auth.c | 12 ++--- .../nfc/scenes/nfc_scene_passport_read_auth.c | 2 +- lib/nfc/protocols/mrtd.c | 44 +------------------ lib/nfc/protocols/mrtd.h | 3 +- lib/nfc/protocols/mrtd_helpers.h | 15 +++++++ 5 files changed, 23 insertions(+), 53 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_auth.c index fe4bd056b..1af80cd62 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth.c @@ -3,13 +3,7 @@ #define TAG "PassportAuth" #define MRTD_AUTH_METHOD_COUNT 4 -// Indexes must match MrtdAuthMethod (lib/nfc/protocols/mrtd_helpers.h) -const char* const mrtd_auth_method_text[MRTD_AUTH_METHOD_COUNT] = { - "None", - "Any", - "BAC", - "PACE", -}; +// Must match MrtdAuthMethod size (lib/nfc/protocols/mrtd_helpers.h) typedef enum { NfcScenePassportAuthSelectDob, @@ -28,7 +22,7 @@ void nfc_scene_passport_auth_method_changed(VariableItem* item) { Nfc* nfc = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); nfc->dev->dev_data.mrtd_data.auth.method = index; - variable_item_set_current_value_text(item, mrtd_auth_method_text[index]); + variable_item_set_current_value_text(item, mrtd_auth_method_string(index)); } void nfc_scene_passport_auth_on_enter(void* context) { @@ -87,7 +81,7 @@ void nfc_scene_passport_auth_on_enter(void* context) { value_index = *auth_method; variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, mrtd_auth_method_text[value_index]); + variable_item_set_current_value_text(item, mrtd_auth_method_string(value_index)); variable_item_list_add(variable_item_list, "Authenticate and read", 1, NULL, NULL); diff --git a/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c index 0f0f82684..cc5c294d4 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c @@ -34,7 +34,7 @@ void nfc_scene_passport_read_auth_on_enter(void* context) { FuriString* temp_str; temp_str = furi_string_alloc(); furi_string_set(temp_str, "\e#Passport\n"); - furi_string_cat_printf(temp_str, "Authenticated: %d\n", mrtd_data->auth_success); + furi_string_cat_printf(temp_str, "Auth.method: %s\n", mrtd_auth_method_string(mrtd_data->auth_method_used)); // TODO: indicate BAC / PACE used uint16_t lds_version = mrtd_data->files.EF_COM.lds_version; diff --git a/lib/nfc/protocols/mrtd.c b/lib/nfc/protocols/mrtd.c index ce4fa9177..102dd4a12 100644 --- a/lib/nfc/protocols/mrtd.c +++ b/lib/nfc/protocols/mrtd.c @@ -532,12 +532,14 @@ bool mrtd_bac(MrtdApplication* app, MrtdAuthData* auth) { bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data) { MrtdAuthMethod method = mrtd_data->auth.method; mrtd_data->auth_success = false; + mrtd_data->auth_method_used = MrtdAuthMethodNone; FURI_LOG_D(TAG, "Auth method: %d", method); switch(method) { case MrtdAuthMethodAny: //TODO: try PACE, then BAC. For now, fall through to just BAC case MrtdAuthMethodBac: mrtd_data->auth_success = mrtd_bac(app, &mrtd_data->auth); + mrtd_data->auth_method_used = MrtdAuthMethodBac; break; case MrtdAuthMethodPace: FURI_LOG_E(TAG, "Auth method PACE not implemented"); @@ -553,45 +555,3 @@ bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data) { return true; } - -//TODO: remove testing function -void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data) { - FURI_LOG_D(TAG, "Mrtd Test"); - //mrtd_read_dump(app, EF.ATR); - //mrtd_read_dump(app, EF.COM); - //mrtd_read_dump(app, EF.DIR); - //mrtd_read_dump(app, EF.CardAccess); - //mrtd_read_dump(app, EF.CardSecurity); - - mrtd_select_app(app, AID.eMRTDApplication); - - MrtdAuthMethod method = mrtd_data->auth.method; - mrtd_data->auth_success = false; - FURI_LOG_D(TAG, "Auth method: %d", method); - switch(method) { - case MrtdAuthMethodAny: - //TODO: try PACE, then BAC - case MrtdAuthMethodBac: - mrtd_data->auth_success = mrtd_bac(app, &mrtd_data->auth); - break; - case MrtdAuthMethodPace: - FURI_LOG_E(TAG, "Auth method PACE not implemented"); - break; - case MrtdAuthMethodNone: - default: - break; - } - - if(!mrtd_data->auth_success) { - return; - } - - mrtd_read_parse_file(app, mrtd_data, EF.COM); - //mrtd_read_parse_file(app, mrtd_data, EF.DIR); - - mrtd_read_parse_file(app, mrtd_data, EF.DG1); - - //mrtd_read_dump(app, EF.DG2); - //mrtd_read_dump(app, EF.DG14); - //mrtd_read_dump(app, EF.DG15); -} diff --git a/lib/nfc/protocols/mrtd.h b/lib/nfc/protocols/mrtd.h index e4d032f88..57825994c 100644 --- a/lib/nfc/protocols/mrtd.h +++ b/lib/nfc/protocols/mrtd.h @@ -16,7 +16,8 @@ typedef struct { typedef struct { MrtdAuthData auth; - bool auth_success; //TODO: register (and display) method used BAC/PACE + bool auth_success; + MrtdAuthMethod auth_method_used; struct { EF_DIR_contents EF_DIR; diff --git a/lib/nfc/protocols/mrtd_helpers.h b/lib/nfc/protocols/mrtd_helpers.h index 83197d95e..d3310b0eb 100644 --- a/lib/nfc/protocols/mrtd_helpers.h +++ b/lib/nfc/protocols/mrtd_helpers.h @@ -25,6 +25,21 @@ typedef enum { MrtdAuthMethodPace, } MrtdAuthMethod; +inline const char* mrtd_auth_method_string(MrtdAuthMethod method) { + switch(method) { + case MrtdAuthMethodBac: + return "BAC"; + case MrtdAuthMethodPace: + return "PACE"; + case MrtdAuthMethodNone: + return "None"; + case MrtdAuthMethodAny: + return "Any"; + default: + return "Unknown"; + } +} + typedef enum { MrtdTypeUnknown, MrtdTypeTD1, From 496c059e39f206176a51f1a7d5de764efa908ce7 Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 18:39:46 +0200 Subject: [PATCH 04/12] MRTD save/load BAC params --- .../main/nfc/scenes/nfc_scene_config.h | 1 + .../main/nfc/scenes/nfc_scene_passport_auth.c | 58 +++++++ .../nfc_scene_passport_auth_save_name.c | 81 ++++++++++ .../main/nfc/scenes/nfc_scene_save_success.c | 3 + lib/nfc/protocols/mrtd.c | 144 ++++++++++++++++++ lib/nfc/protocols/mrtd.h | 8 + lib/nfc/protocols/mrtd_helpers.c | 36 +++++ lib/nfc/protocols/mrtd_helpers.h | 19 +-- 8 files changed, 335 insertions(+), 15 deletions(-) create mode 100644 applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c diff --git a/applications/main/nfc/scenes/nfc_scene_config.h b/applications/main/nfc/scenes/nfc_scene_config.h index cb28a07f9..20d8b19f3 100644 --- a/applications/main/nfc/scenes/nfc_scene_config.h +++ b/applications/main/nfc/scenes/nfc_scene_config.h @@ -42,6 +42,7 @@ ADD_SCENE(nfc, passport_read, PassportReadSuccess) ADD_SCENE(nfc, passport_read_auth, PassportReadAuthSuccess) ADD_SCENE(nfc, passport_menu, PassportMenu) ADD_SCENE(nfc, passport_auth, PassportAuth) +ADD_SCENE(nfc, passport_auth_save_name, PassportAuthSaveName) ADD_SCENE(nfc, passport_date, PassportDate) ADD_SCENE(nfc, passport_docnr, PassportDocNr) ADD_SCENE(nfc, passport_pace_todo, PassportPaceTodo) diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_auth.c index 1af80cd62..7376bdf39 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth.c @@ -11,6 +11,8 @@ typedef enum { NfcScenePassportAuthSelectDocNr, NfcScenePassportAuthSelectMethod, NfcScenePassportAuthSelectAuth, + NfcScenePassportAuthSelectSave, + NfcScenePassportAuthSelectLoad, } NfcScenePassportAuthSelect; void nfc_scene_passport_auth_var_list_enter_callback(void* context, uint32_t index) { @@ -25,6 +27,47 @@ void nfc_scene_passport_auth_method_changed(VariableItem* item) { variable_item_set_current_value_text(item, mrtd_auth_method_string(index)); } +void nfc_scene_passport_load_select_changed(VariableItem* item) { + Nfc* nfc = variable_item_get_context(item); + UNUSED(nfc); //TODO: remove either this or previous line + //TODO: iterate through params +} + +bool nfc_scene_passport_auth_load(Nfc* nfc) { + const DialogsFileBrowserOptions browser_options = { + .extension = MRTD_APP_EXTENSION, + .skip_assets = true, + .icon = &I_Nfc_10px, //TODO: custom icon? + .hide_ext = true, + .item_loader_callback = NULL, + .item_loader_context = NULL, + }; + + FuriString* mrtd_app_folder; + mrtd_app_folder = furi_string_alloc_set(MRTD_APP_FOLDER); + + FuriString* file_path; + file_path = furi_string_alloc(); + + bool res = dialog_file_browser_show(nfc->dev->dialogs, file_path, mrtd_app_folder, &browser_options); + + furi_string_free(mrtd_app_folder); + + if(res) { + mrtd_auth_params_load( + nfc->dev->storage, + nfc->dev->dialogs, + &nfc->dev->dev_data.mrtd_data.auth, + furi_string_get_cstr(file_path), + true); + + //TODO: make sure this call is ok: + nfc_scene_passport_auth_on_enter(nfc); + } + + return res; +} + void nfc_scene_passport_auth_on_enter(void* context) { Nfc* nfc = context; MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; @@ -36,12 +79,16 @@ void nfc_scene_passport_auth_on_enter(void* context) { } VariableItemList* variable_item_list = nfc->variable_item_list; + variable_item_list_reset(variable_item_list); VariableItem* item; uint8_t value_index; const size_t temp_str_size = 15; char temp_str[temp_str_size]; + + uint8_t num_params_saved = 0; + snprintf(temp_str, temp_str_size, "%02u%02u%02u", mrtd_data->auth.birth_date.year, mrtd_data->auth.birth_date.month, @@ -85,6 +132,9 @@ void nfc_scene_passport_auth_on_enter(void* context) { variable_item_list_add(variable_item_list, "Authenticate and read", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "Save parameters", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "Load parameters", num_params_saved, nfc_scene_passport_load_select_changed, nfc); + variable_item_list_set_enter_callback( variable_item_list, nfc_scene_passport_auth_var_list_enter_callback, nfc); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewVarItemList); @@ -97,6 +147,10 @@ bool nfc_scene_passport_auth_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { FURI_LOG_D(TAG, "event.event: %ld", event.event); switch(event.event) { + case NfcScenePassportAuthSelectLoad: + nfc_scene_passport_auth_load(nfc); + consumed = true; + break; case NfcScenePassportAuthSelectDob: scene_manager_set_scene_state(nfc->scene_manager, NfcScenePassportDate, 0); scene_manager_next_scene(nfc->scene_manager, NfcScenePassportDate); @@ -123,6 +177,10 @@ bool nfc_scene_passport_auth_on_event(void* context, SceneManagerEvent event) { } consumed = true; break; + case NfcScenePassportAuthSelectSave: + scene_manager_next_scene(nfc->scene_manager, NfcScenePassportAuthSaveName); + consumed = true; + break; } } else if(event.type == SceneManagerEventTypeBack) { consumed = scene_manager_previous_scene(nfc->scene_manager); diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c b/applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c new file mode 100644 index 000000000..5cfa7d9a3 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth_save_name.c @@ -0,0 +1,81 @@ +#include "../nfc_i.h" +#include +#include +#include + +void nfc_scene_passport_auth_save_name_text_input_callback(void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventTextInputDone); +} + +void nfc_scene_passport_auth_save_name_on_enter(void* context) { + Nfc* nfc = context; + + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; + + // Setup view + TextInput* text_input = nfc->text_input; + bool docnr_empty = false; + if(!strcmp(mrtd_data->auth.doc_number, "")) { + set_random_name(nfc->text_store, sizeof(nfc->text_store)); + docnr_empty = true; + } else { + nfc_text_store_set(nfc, mrtd_data->auth.doc_number); + } + text_input_set_header_text(text_input, "Name the parameters"); + text_input_set_result_callback( + text_input, + nfc_scene_passport_auth_save_name_text_input_callback, + nfc, + nfc->text_store, + NFC_DEV_NAME_MAX_LEN, + docnr_empty); + + FuriString* folder_path; + folder_path = furi_string_alloc(); + + if(furi_string_end_with(nfc->dev->load_path, NFC_APP_EXTENSION)) { + path_extract_dirname(furi_string_get_cstr(nfc->dev->load_path), folder_path); + } else { + furi_string_set(folder_path, NFC_APP_FOLDER); + } + + ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( + furi_string_get_cstr(folder_path), NFC_APP_EXTENSION, NULL); + text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); + + furi_string_free(folder_path); +} + +bool nfc_scene_passport_auth_save_name_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + MrtdData* mrtd_data = &nfc->dev->dev_data.mrtd_data; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventTextInputDone) { + if(mrtd_auth_params_save(nfc->dev->storage, nfc->dev->dialogs, &mrtd_data->auth, nfc->text_store)) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveSuccess); + consumed = true; + } else { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); + } + } + } + return consumed; +} + +void nfc_scene_passport_auth_save_name_on_exit(void* context) { + Nfc* nfc = context; + + // Clear view + void* validator_context = text_input_get_validator_callback_context(nfc->text_input); + text_input_set_validator(nfc->text_input, NULL, NULL); + validator_is_file_free(validator_context); + + text_input_reset(nfc->text_input); +} diff --git a/applications/main/nfc/scenes/nfc_scene_save_success.c b/applications/main/nfc/scenes/nfc_scene_save_success.c index dcd2519f1..99dacba8f 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_success.c +++ b/applications/main/nfc/scenes/nfc_scene_save_success.c @@ -33,6 +33,9 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) { consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneSavedMenu); + } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcScenePassportAuth)) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcScenePassportAuth); } else { consumed = scene_manager_search_and_switch_to_another_scene( nfc->scene_manager, NfcSceneFileSelect); diff --git a/lib/nfc/protocols/mrtd.c b/lib/nfc/protocols/mrtd.c index 102dd4a12..f06959ead 100644 --- a/lib/nfc/protocols/mrtd.c +++ b/lib/nfc/protocols/mrtd.c @@ -1,4 +1,7 @@ #include +#include +#include +#include #include "../helpers/iso7816.h" @@ -19,6 +22,9 @@ #define num_elements(A) (sizeof(A)/sizeof(A[0])) +static const char* mrtd_auth_file_header = "Flipper MRTD params"; +static const uint32_t mrtd_auth_file_version = 1; + static void hexdump(FuriLogLevel level, char* prefix, void* data, size_t length) { if(furi_log_get_level() >= level) { printf("%s ", prefix); @@ -555,3 +561,141 @@ bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data) { return true; } + +bool mrtd_auth_params_save(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_name) { + return mrtd_auth_params_save_file(storage, dialogs, auth_data, file_name, MRTD_APP_FOLDER, MRTD_APP_EXTENSION); +} + +void mrtd_date_prepare_format_string(MrtdDate date, FuriString* format_string) { + furi_string_printf( + format_string, "%02u%02u%02u", + date.year, + date.month, + date.day); +} + +bool mrtd_date_parse_format_string(MrtdDate* date, FuriString* format_string) { + int year; + int month; + int day; + + int ret = sscanf(furi_string_get_cstr(format_string), "%02d%02d%02d", &year, &month, &day); + if(ret != 3) { + return false; + } + + date->year = year; + date->month = month; + date->day = day; + return true; +} + +bool mrtd_auth_params_save_file(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_name, const char* folder, const char* extension) { + furi_assert(auth_data); + + bool saved = false; + FlipperFormat* file = flipper_format_file_alloc(storage); + FuriString* temp_str; + temp_str = furi_string_alloc(); + + do { + // Create mrtd directory if necessary + if(!storage_simply_mkdir(storage, MRTD_APP_FOLDER)) break; + + furi_string_printf(temp_str, "%s/%s%s", folder, file_name, extension); + + // Open file + if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; + // Write header + if(!flipper_format_write_header_cstr(file, mrtd_auth_file_header, mrtd_auth_file_version)) break; + + // Write auth method + furi_string_set(temp_str, mrtd_auth_method_string(auth_data->method)); + if(!flipper_format_write_string(file, "Method", temp_str)) break; + + // Write birth date + mrtd_date_prepare_format_string(auth_data->birth_date, temp_str); + if(!flipper_format_write_string(file, "BirthDate", temp_str)) break; + + // Write expiry date + mrtd_date_prepare_format_string(auth_data->expiry_date, temp_str); + if(!flipper_format_write_string(file, "ExpiryDate", temp_str)) break; + + // Write docnr + furi_string_set(temp_str, auth_data->doc_number); + if(!flipper_format_write_string(file, "DocNr", temp_str)) break; + + saved = true; + } while(false); + + if(!saved) { + dialog_message_show_storage_error(dialogs, "Can not save\nparams file"); + } + furi_string_free(temp_str); + flipper_format_free(file); + return saved; +} + +bool mrtd_auth_params_load(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_path, bool show_dialog) { + furi_assert(storage); + furi_assert(dialogs); + furi_assert(auth_data); + furi_assert(file_path); + + bool parsed = false; + FlipperFormat* file = flipper_format_file_alloc(storage); + bool deprecated_version = false; + + FuriString* temp_str; + temp_str = furi_string_alloc(); + + MrtdAuthData copy; + + FURI_LOG_D(TAG, "Load auth params"); + + do { + if(!flipper_format_file_open_existing(file, file_path)) break; + + uint32_t version = 0; + if(!flipper_format_read_header(file, temp_str, &version)) break; + FURI_LOG_D(TAG, "Version: %s", furi_string_get_cstr(temp_str)); + if(furi_string_cmp_str(temp_str, mrtd_auth_file_header) || (version != mrtd_auth_file_version)) { + deprecated_version = true; + break; + } + + if(!flipper_format_read_string(file, "Method", temp_str)) break; + FURI_LOG_D(TAG, "Method: %s", furi_string_get_cstr(temp_str)); + if(!mrtd_auth_method_parse_string(©.method, furi_string_get_cstr(temp_str))) break; + + if(!flipper_format_read_string(file, "BirthDate", temp_str)) break; + FURI_LOG_D(TAG, "BirthDate: %s", furi_string_get_cstr(temp_str)); + if(!mrtd_date_parse_format_string(©.birth_date, temp_str)) break; + + if(!flipper_format_read_string(file, "ExpiryDate", temp_str)) break; + FURI_LOG_D(TAG, "ExpiryDate: %s", furi_string_get_cstr(temp_str)); + if(!mrtd_date_parse_format_string(©.expiry_date, temp_str)) break; + + if(!flipper_format_read_string(file, "DocNr", temp_str)) break; + FURI_LOG_D(TAG, "DocNr: %s", furi_string_get_cstr(temp_str)); + strlcpy(copy.doc_number, furi_string_get_cstr(temp_str), MRTD_DOCNR_MAX_LENGTH); + + // Everything went fine. Save copy to pointed auth data + *auth_data = copy; + parsed = true; + } while(false); + + FURI_LOG_D(TAG, "Load done, success: %d", parsed); + + if(!parsed && show_dialog) { + if(deprecated_version) { + dialog_message_show_storage_error(dialogs, "File format deprecated"); + } else { + dialog_message_show_storage_error(dialogs, "Can not parse\nfile"); + } + } + + furi_string_free(temp_str); + flipper_format_free(file); + return parsed; +} diff --git a/lib/nfc/protocols/mrtd.h b/lib/nfc/protocols/mrtd.h index 57825994c..0a9e64801 100644 --- a/lib/nfc/protocols/mrtd.h +++ b/lib/nfc/protocols/mrtd.h @@ -4,6 +4,9 @@ #include "mrtd_helpers.h" +#define MRTD_APP_FOLDER NFC_APP_FOLDER "/mrtd" +#define MRTD_APP_EXTENSION ".mrtd" + typedef struct { FuriHalNfcTxRxContext* tx_rx; uint16_t file_offset; @@ -32,3 +35,8 @@ void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data); //TODO: remove bool mrtd_select_app(MrtdApplication* app, AIDValue aid); bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data); bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file); + +bool mrtd_auth_params_save(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_name); +bool mrtd_auth_params_save_file(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_name, const char* folder, const char* extension); + +bool mrtd_auth_params_load(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_path, bool show_dialog); diff --git a/lib/nfc/protocols/mrtd_helpers.c b/lib/nfc/protocols/mrtd_helpers.c index 7456830d1..70d740309 100644 --- a/lib/nfc/protocols/mrtd_helpers.c +++ b/lib/nfc/protocols/mrtd_helpers.c @@ -9,6 +9,42 @@ static inline unsigned char *ucstr(const char *str) { return (unsigned char *)str; } +const char* mrtd_auth_method_string(MrtdAuthMethod method) { + switch(method) { + case MrtdAuthMethodBac: + return "BAC"; + case MrtdAuthMethodPace: + return "PACE"; + case MrtdAuthMethodNone: + return "None"; + case MrtdAuthMethodAny: + return "Any"; + default: + return "Unknown"; + } +} + +bool mrtd_auth_method_parse_string(MrtdAuthMethod* method, const char* str) { + if(!strcmp(str, "BAC")) { + *method = MrtdAuthMethodBac; + return true; + } + if(!strcmp(str, "PACE")) { + *method = MrtdAuthMethodPace; + return true; + } + if(!strcmp(str, "None")) { + *method = MrtdAuthMethodNone; + return true; + } + if(!strcmp(str, "Any")) { + *method = MrtdAuthMethodAny; + return true; + } + return false; +} + + uint8_t mrtd_bac_check_digit(const char* input, const uint8_t length) { const uint8_t num_weights = 3; uint8_t weights[] = {7, 3, 1}; diff --git a/lib/nfc/protocols/mrtd_helpers.h b/lib/nfc/protocols/mrtd_helpers.h index d3310b0eb..d538a7079 100644 --- a/lib/nfc/protocols/mrtd_helpers.h +++ b/lib/nfc/protocols/mrtd_helpers.h @@ -25,21 +25,6 @@ typedef enum { MrtdAuthMethodPace, } MrtdAuthMethod; -inline const char* mrtd_auth_method_string(MrtdAuthMethod method) { - switch(method) { - case MrtdAuthMethodBac: - return "BAC"; - case MrtdAuthMethodPace: - return "PACE"; - case MrtdAuthMethodNone: - return "None"; - case MrtdAuthMethodAny: - return "Any"; - default: - return "Unknown"; - } -} - typedef enum { MrtdTypeUnknown, MrtdTypeTD1, @@ -144,6 +129,10 @@ typedef struct { MrtdDate expiry_date; } EF_DG1_contents; +const char* mrtd_auth_method_string(MrtdAuthMethod method); + +bool mrtd_auth_method_parse_string(MrtdAuthMethod* method, const char* str); + uint8_t mrtd_bac_check_digit(const char* input, const uint8_t length); //TODO: swap order, all other functions have output last From 5119eaf2f771ebdeede92b806084c06e019d6b62 Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 18:47:19 +0200 Subject: [PATCH 05/12] MRTD remove auth failed TODO --- applications/main/nfc/scenes/nfc_scene_read.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_read.c b/applications/main/nfc/scenes/nfc_scene_read.c index 6dd06e8f3..434fdadd6 100644 --- a/applications/main/nfc/scenes/nfc_scene_read.c +++ b/applications/main/nfc/scenes/nfc_scene_read.c @@ -87,8 +87,6 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) { notification_message(nfc->notifications, &sequence_success); if(nfc->dev->dev_data.mrtd_data.auth_success) { scene_manager_next_scene(nfc->scene_manager, NfcScenePassportReadAuthSuccess); - //TODO: } else if(nfc->dev->dev_data.mrtd_data.auth.method != MrtdAuthMethodNone) { - //scene_manager_next_scene(nfc->scene_manager, NfcScenePassportReadAuthFailed); } else { scene_manager_next_scene(nfc->scene_manager, NfcScenePassportReadSuccess); } From 7778904a392dfeb76fd9ee6ab1b6a40ff280ad21 Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 18:49:06 +0200 Subject: [PATCH 06/12] MRTD move mrtd_helpers to nfc/helpers/ --- lib/nfc/{protocols => helpers}/mrtd_helpers.c | 0 lib/nfc/{protocols => helpers}/mrtd_helpers.h | 0 lib/nfc/protocols/mrtd.h | 3 +-- 3 files changed, 1 insertion(+), 2 deletions(-) rename lib/nfc/{protocols => helpers}/mrtd_helpers.c (100%) rename lib/nfc/{protocols => helpers}/mrtd_helpers.h (100%) diff --git a/lib/nfc/protocols/mrtd_helpers.c b/lib/nfc/helpers/mrtd_helpers.c similarity index 100% rename from lib/nfc/protocols/mrtd_helpers.c rename to lib/nfc/helpers/mrtd_helpers.c diff --git a/lib/nfc/protocols/mrtd_helpers.h b/lib/nfc/helpers/mrtd_helpers.h similarity index 100% rename from lib/nfc/protocols/mrtd_helpers.h rename to lib/nfc/helpers/mrtd_helpers.h diff --git a/lib/nfc/protocols/mrtd.h b/lib/nfc/protocols/mrtd.h index 0a9e64801..6ac4a93ae 100644 --- a/lib/nfc/protocols/mrtd.h +++ b/lib/nfc/protocols/mrtd.h @@ -1,8 +1,7 @@ #pragma once #include - -#include "mrtd_helpers.h" +#include #define MRTD_APP_FOLDER NFC_APP_FOLDER "/mrtd" #define MRTD_APP_EXTENSION ".mrtd" From 16ed3cb7c601f25c598b59c773b238cc60ae264a Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 18:53:33 +0200 Subject: [PATCH 07/12] MRTD reset auth on retry --- applications/main/nfc/scenes/nfc_scene_passport_read_auth.c | 2 ++ applications/main/nfc/scenes/nfc_scene_read.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c index cc5c294d4..7dddc7fa1 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_read_auth.c @@ -97,6 +97,8 @@ bool nfc_scene_passport_read_auth_on_event(void* context, SceneManagerEvent even if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { + nfc->dev->dev_data.mrtd_data.auth_success = false; + nfc->dev->dev_data.mrtd_data.auth.method = MrtdAuthMethodNone; scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm); consumed = true; } else if(event.event == GuiButtonTypeCenter) { diff --git a/applications/main/nfc/scenes/nfc_scene_read.c b/applications/main/nfc/scenes/nfc_scene_read.c index 434fdadd6..09e3d79be 100644 --- a/applications/main/nfc/scenes/nfc_scene_read.c +++ b/applications/main/nfc/scenes/nfc_scene_read.c @@ -85,6 +85,9 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) { consumed = true; } else if(event.event == NfcWorkerEventReadPassport) { notification_message(nfc->notifications, &sequence_success); + FURI_LOG_D("NFC", "Read passport, auth: %d, success: %d", + nfc->dev->dev_data.mrtd_data.auth.method, + nfc->dev->dev_data.mrtd_data.auth_success); if(nfc->dev->dev_data.mrtd_data.auth_success) { scene_manager_next_scene(nfc->scene_manager, NfcScenePassportReadAuthSuccess); } else { From fc31ddc4474c5f810c3dfafe3828467653f136ee Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 18:53:59 +0200 Subject: [PATCH 08/12] MRTD Load params as menu option --- applications/main/nfc/scenes/nfc_scene_passport_auth.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_auth.c index 7376bdf39..c064bb1a2 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth.c @@ -27,12 +27,6 @@ void nfc_scene_passport_auth_method_changed(VariableItem* item) { variable_item_set_current_value_text(item, mrtd_auth_method_string(index)); } -void nfc_scene_passport_load_select_changed(VariableItem* item) { - Nfc* nfc = variable_item_get_context(item); - UNUSED(nfc); //TODO: remove either this or previous line - //TODO: iterate through params -} - bool nfc_scene_passport_auth_load(Nfc* nfc) { const DialogsFileBrowserOptions browser_options = { .extension = MRTD_APP_EXTENSION, @@ -87,8 +81,6 @@ void nfc_scene_passport_auth_on_enter(void* context) { const size_t temp_str_size = 15; char temp_str[temp_str_size]; - uint8_t num_params_saved = 0; - snprintf(temp_str, temp_str_size, "%02u%02u%02u", mrtd_data->auth.birth_date.year, mrtd_data->auth.birth_date.month, @@ -133,7 +125,7 @@ void nfc_scene_passport_auth_on_enter(void* context) { variable_item_list_add(variable_item_list, "Authenticate and read", 1, NULL, NULL); variable_item_list_add(variable_item_list, "Save parameters", 1, NULL, NULL); - variable_item_list_add(variable_item_list, "Load parameters", num_params_saved, nfc_scene_passport_load_select_changed, nfc); + variable_item_list_add(variable_item_list, "Load parameters", 1, NULL, NULL); variable_item_list_set_enter_callback( variable_item_list, nfc_scene_passport_auth_var_list_enter_callback, nfc); From 131578ab427583867e15ecc8d0253410b22cc832 Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 19:44:05 +0200 Subject: [PATCH 09/12] MRTD Use u2f icon in load params --- applications/main/nfc/scenes/nfc_scene_passport_auth.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_auth.c index c064bb1a2..b9dd6365f 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth.c @@ -31,7 +31,7 @@ bool nfc_scene_passport_auth_load(Nfc* nfc) { const DialogsFileBrowserOptions browser_options = { .extension = MRTD_APP_EXTENSION, .skip_assets = true, - .icon = &I_Nfc_10px, //TODO: custom icon? + .icon = &I_u2f_10px, .hide_ext = true, .item_loader_callback = NULL, .item_loader_context = NULL, @@ -55,7 +55,6 @@ bool nfc_scene_passport_auth_load(Nfc* nfc) { furi_string_get_cstr(file_path), true); - //TODO: make sure this call is ok: nfc_scene_passport_auth_on_enter(nfc); } From 0a044d6416050a0598663e8d0248fd521a17688f Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 19:45:32 +0200 Subject: [PATCH 10/12] MRTD Select auth&read after load --- applications/main/nfc/scenes/nfc_scene_passport_auth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/main/nfc/scenes/nfc_scene_passport_auth.c b/applications/main/nfc/scenes/nfc_scene_passport_auth.c index b9dd6365f..55b0bd296 100644 --- a/applications/main/nfc/scenes/nfc_scene_passport_auth.c +++ b/applications/main/nfc/scenes/nfc_scene_passport_auth.c @@ -56,6 +56,7 @@ bool nfc_scene_passport_auth_load(Nfc* nfc) { true); nfc_scene_passport_auth_on_enter(nfc); + variable_item_list_set_selected_item(nfc->variable_item_list, NfcScenePassportAuthSelectAuth); } return res; From bd5b0da3619ed5bd14768285d07b803648f749ab Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 19:47:29 +0200 Subject: [PATCH 11/12] MRTD Move MrtdData to helper .h --- lib/nfc/helpers/mrtd_helpers.h | 12 ++++++++++++ lib/nfc/protocols/mrtd.h | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/nfc/helpers/mrtd_helpers.h b/lib/nfc/helpers/mrtd_helpers.h index d538a7079..5d4f05a50 100644 --- a/lib/nfc/helpers/mrtd_helpers.h +++ b/lib/nfc/helpers/mrtd_helpers.h @@ -129,6 +129,18 @@ typedef struct { MrtdDate expiry_date; } EF_DG1_contents; +typedef struct { + MrtdAuthData auth; + bool auth_success; + MrtdAuthMethod auth_method_used; + + struct { + EF_DIR_contents EF_DIR; + EF_COM_contents EF_COM; + EF_DG1_contents DG1; + } files; +} MrtdData; + const char* mrtd_auth_method_string(MrtdAuthMethod method); bool mrtd_auth_method_parse_string(MrtdAuthMethod* method, const char* str); diff --git a/lib/nfc/protocols/mrtd.h b/lib/nfc/protocols/mrtd.h index 6ac4a93ae..b3377641a 100644 --- a/lib/nfc/protocols/mrtd.h +++ b/lib/nfc/protocols/mrtd.h @@ -16,18 +16,6 @@ typedef struct { bool secure_messaging; } MrtdApplication; -typedef struct { - MrtdAuthData auth; - bool auth_success; - MrtdAuthMethod auth_method_used; - - struct { - EF_DIR_contents EF_DIR; - EF_COM_contents EF_COM; - EF_DG1_contents DG1; - } files; -} MrtdData; - //TODO: description MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx); void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data); //TODO: remove From a629a3901775e685b0036cf09ef65e4f38a1c0fd Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Thu, 27 Oct 2022 19:56:45 +0200 Subject: [PATCH 12/12] MRTD Reference MrtdData from MrtdApplication --- lib/nfc/nfc_worker.c | 8 ++++---- lib/nfc/protocols/mrtd.c | 25 +++++++++++++------------ lib/nfc/protocols/mrtd.h | 8 ++++---- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index eb43d7ee4..5d61677f8 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -288,8 +288,8 @@ static bool nfc_worker_read_bank_card(NfcWorker* nfc_worker, FuriHalNfcTxRxConte static bool nfc_worker_read_mrtd(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { bool read_success = false; - MrtdApplication* mrtd_app = mrtd_alloc_init(tx_rx); MrtdData* mrtd_data = &nfc_worker->dev_data->mrtd_data; + MrtdApplication* mrtd_app = mrtd_alloc_init(tx_rx, mrtd_data); if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false); @@ -310,14 +310,14 @@ static bool nfc_worker_read_mrtd(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t break; } - if(!mrtd_authenticate(mrtd_app, mrtd_data)) { + if(!mrtd_authenticate(mrtd_app)) { // At least we're reading an MRTD and should the app switch to the NFC scenes read_success = true; break; // Authentication failed } - mrtd_read_parse_file(mrtd_app, mrtd_data, EF.COM); - mrtd_read_parse_file(mrtd_app, mrtd_data, EF.DG1); + mrtd_read_parse_file(mrtd_app, EF.COM); + mrtd_read_parse_file(mrtd_app, EF.DG1); read_success = true; } while(false); diff --git a/lib/nfc/protocols/mrtd.c b/lib/nfc/protocols/mrtd.c index f06959ead..2de966754 100644 --- a/lib/nfc/protocols/mrtd.c +++ b/lib/nfc/protocols/mrtd.c @@ -389,7 +389,7 @@ bool parse_ef_dg1(EF_DG1_contents* DG1, const uint8_t* data, size_t length) { return true; } -bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file) { +bool mrtd_read_parse_file(MrtdApplication* app, EFFile file) { uint8_t buffer[100]; size_t buf_len; @@ -414,13 +414,13 @@ bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file bool result = false; if(file.file_id == EF.COM.file_id) { - result = parse_ef_com(&mrtd_data->files.EF_COM, buffer, buf_len); + result = parse_ef_com(&app->mrtd_data->files.EF_COM, buffer, buf_len); FURI_LOG_D(TAG, "Parsed EF.COM"); } else if(file.file_id == EF.DIR.file_id) { - result = parse_ef_dir(&mrtd_data->files.EF_DIR, buffer, buf_len); + result = parse_ef_dir(&app->mrtd_data->files.EF_DIR, buffer, buf_len); FURI_LOG_D(TAG, "Parsed EF.DIR"); } else if(file.file_id == EF.DG1.file_id) { - result = parse_ef_dg1(&mrtd_data->files.DG1, buffer, buf_len); + result = parse_ef_dg1(&app->mrtd_data->files.DG1, buffer, buf_len); } else { FURI_LOG_W(TAG, "Don't know how to parse file with id 0x%04X", file.file_id); } @@ -428,10 +428,11 @@ bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file return result; } -MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx) { +MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx, MrtdData* mrtd_data) { MrtdApplication* app = malloc(sizeof(MrtdApplication)); app->tx_rx = tx_rx; + app->mrtd_data = mrtd_data; return app; } @@ -535,17 +536,17 @@ bool mrtd_bac(MrtdApplication* app, MrtdAuthData* auth) { return true; } -bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data) { - MrtdAuthMethod method = mrtd_data->auth.method; - mrtd_data->auth_success = false; - mrtd_data->auth_method_used = MrtdAuthMethodNone; +bool mrtd_authenticate(MrtdApplication* app) { + MrtdAuthMethod method = app->mrtd_data->auth.method; + app->mrtd_data->auth_success = false; + app->mrtd_data->auth_method_used = MrtdAuthMethodNone; FURI_LOG_D(TAG, "Auth method: %d", method); switch(method) { case MrtdAuthMethodAny: //TODO: try PACE, then BAC. For now, fall through to just BAC case MrtdAuthMethodBac: - mrtd_data->auth_success = mrtd_bac(app, &mrtd_data->auth); - mrtd_data->auth_method_used = MrtdAuthMethodBac; + app->mrtd_data->auth_success = mrtd_bac(app, &app->mrtd_data->auth); + app->mrtd_data->auth_method_used = MrtdAuthMethodBac; break; case MrtdAuthMethodPace: FURI_LOG_E(TAG, "Auth method PACE not implemented"); @@ -555,7 +556,7 @@ bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data) { break; } - if(!mrtd_data->auth_success) { + if(!app->mrtd_data->auth_success) { return false; } diff --git a/lib/nfc/protocols/mrtd.h b/lib/nfc/protocols/mrtd.h index b3377641a..180186f6e 100644 --- a/lib/nfc/protocols/mrtd.h +++ b/lib/nfc/protocols/mrtd.h @@ -8,6 +8,7 @@ typedef struct { FuriHalNfcTxRxContext* tx_rx; + MrtdData* mrtd_data; uint16_t file_offset; uint8_t ksenc[16]; uint8_t ksmac[16]; @@ -17,11 +18,10 @@ typedef struct { } MrtdApplication; //TODO: description -MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx); -void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data); //TODO: remove +MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx, MrtdData* mrtd_data); bool mrtd_select_app(MrtdApplication* app, AIDValue aid); -bool mrtd_authenticate(MrtdApplication* app, MrtdData* mrtd_data); -bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file); +bool mrtd_authenticate(MrtdApplication* app); +bool mrtd_read_parse_file(MrtdApplication* app, EFFile file); bool mrtd_auth_params_save(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_name); bool mrtd_auth_params_save_file(Storage* storage, DialogsApp* dialogs, MrtdAuthData* auth_data, const char* file_name, const char* folder, const char* extension);