From 90d001aab3d51014a92b53001552deafa71d74d0 Mon Sep 17 00:00:00 2001 From: Struan Clark Date: Thu, 9 Mar 2023 16:32:46 -0700 Subject: [PATCH] importing of mnemonics --- flipbip.c | 51 +++++++++++++++++++++++++++++++++---- flipbip.h | 17 +++++++++++-- scenes/flipbip_scene_menu.c | 16 ++++++++++++ views/flipbip_scene_1.c | 35 +++++++++++++++---------- 4 files changed, 99 insertions(+), 20 deletions(-) diff --git a/flipbip.c b/flipbip.c index 6649bfd7380..8f0ddda8248 100644 --- a/flipbip.c +++ b/flipbip.c @@ -1,5 +1,8 @@ #include "flipbip.h" #include "crypto/memzero.h" +#include "crypto/bip39.h" +#include "helpers/flipbip_file.h" +#include "helpers/flipbip_haptic.h" bool flipbip_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -23,6 +26,7 @@ bool flipbip_navigation_event_callback(void* context) { static void text_input_callback(void* context) { furi_assert(context); FlipBip* app = context; + bool handled = false; // check that there is text in the input if(strlen(app->input_text) > 0) { @@ -30,14 +34,46 @@ static void text_input_callback(void* context) { if(app->passphrase == FlipBipPassphraseOn) { strcpy(app->passphrase_text, app->input_text); } + // clear input text + memzero(app->input_text, TEXT_BUFFER_SIZE); + // reset input state + app->input_state = FlipBipTextInputDefault; + handled = true; view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdSettings); + } else if(app->input_state == FlipBipTextInputMnemonic) { + if(app->import_from_mnemonic == 1) { + strcpy(app->import_mnemonic_text, app->input_text); + + int status = FlipBipStatusSuccess; + // Check if the mnemonic is valid + if(mnemonic_check(app->import_mnemonic_text) == 0) status = FlipBipStatusMnemonicCheckError; // 13 = mnemonic check error + // Save the mnemonic to persistent storage + else if(!flipbip_save_settings_secure(app->import_mnemonic_text)) status = FlipBipStatusSaveError; // 12 = save error + + if (status == FlipBipStatusSuccess) { + flipbip_play_happy_bump(app); + } else { + flipbip_play_long_bump(app); + } + + memzero(app->import_mnemonic_text, TEXT_BUFFER_SIZE); + } + // clear input text + memzero(app->input_text, TEXT_BUFFER_SIZE); + // reset input state + app->input_state = FlipBipTextInputDefault; + handled = true; + view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu); } } - // clear input text - memzero(app->input_text, TEXT_BUFFER_SIZE); - // reset input state - app->input_state = FlipBipTextInputDefault; + if(!handled) { + // clear input text + memzero(app->input_text, TEXT_BUFFER_SIZE); + // reset input state + app->input_state = FlipBipTextInputDefault; + view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu); + } } FlipBip* flipbip_app_alloc() { @@ -64,10 +100,15 @@ FlipBip* flipbip_app_alloc() { // Settings app->haptic = FlipBipHapticOn; app->led = FlipBipLedOn; - app->passphrase = FlipBipPassphraseOff; app->bip39_strength = FlipBipStrength256; // 256 bits (24 words) + app->passphrase = FlipBipPassphraseOff; + + // Main menu app->bip44_coin = FlipBipCoinBTC0; // 0 (BTC) app->overwrite_saved_seed = 0; + app->import_from_mnemonic = 0; + + // Text input app->input_state = FlipBipTextInputDefault; view_dispatcher_add_view( diff --git a/flipbip.h b/flipbip.h index d5aafc91fe0..276bf599e8a 100644 --- a/flipbip.h +++ b/flipbip.h @@ -33,14 +33,19 @@ typedef struct { TextInput* text_input; FlipBipStartscreen* flipbip_startscreen; FlipBipScene1* flipbip_scene_1; + // Settings options int haptic; int led; - int passphrase; int bip39_strength; + int passphrase; + // Main menu options int bip44_coin; int overwrite_saved_seed; + int import_from_mnemonic; + // Text input int input_state; char passphrase_text[TEXT_BUFFER_SIZE]; + char import_mnemonic_text[TEXT_BUFFER_SIZE]; char input_text[TEXT_BUFFER_SIZE]; } FlipBip; @@ -83,4 +88,12 @@ typedef enum { FlipBipTextInputDefault, FlipBipTextInputPassphrase, FlipBipTextInputMnemonic -} FlipBipTextInputState; \ No newline at end of file +} FlipBipTextInputState; + +typedef enum { + FlipBipStatusSuccess = 0, + FlipBipStatusReturn = 10, + FlipBipStatusLoadError = 11, + FlipBipStatusSaveError = 12, + FlipBipStatusMnemonicCheckError = 13, +} FlipBipStatus; \ No newline at end of file diff --git a/scenes/flipbip_scene_menu.c b/scenes/flipbip_scene_menu.c index 7c457ec5c7b..e8fad579a77 100644 --- a/scenes/flipbip_scene_menu.c +++ b/scenes/flipbip_scene_menu.c @@ -6,6 +6,7 @@ enum SubmenuIndex { SubmenuIndexScene1ETH, SubmenuIndexScene1DOGE, SubmenuIndexScene1New, + SubmenuIndexScene1Import, SubmenuIndexSettings, }; @@ -50,6 +51,12 @@ void flipbip_scene_menu_on_enter(void* context) { flipbip_scene_menu_submenu_callback, app); } + submenu_add_item( + app->submenu, + "Import from mnemonic", + SubmenuIndexScene1Import, + flipbip_scene_menu_submenu_callback, + app); submenu_add_item( app->submenu, "Settings", SubmenuIndexSettings, flipbip_scene_menu_submenu_callback, app); @@ -71,6 +78,7 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) { } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexScene1BTC) { app->overwrite_saved_seed = 0; + app->import_from_mnemonic = 0; app->bip44_coin = FlipBipCoinBTC0; scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1BTC); @@ -78,6 +86,7 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) { return true; } else if(event.event == SubmenuIndexScene1ETH) { app->overwrite_saved_seed = 0; + app->import_from_mnemonic = 0; app->bip44_coin = FlipBipCoinETH60; scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1ETH); @@ -85,6 +94,7 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) { return true; } else if(event.event == SubmenuIndexScene1DOGE) { app->overwrite_saved_seed = 0; + app->import_from_mnemonic = 0; app->bip44_coin = FlipBipCoinDOGE3; scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1DOGE); @@ -92,10 +102,16 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) { return true; } else if(event.event == SubmenuIndexScene1New) { app->overwrite_saved_seed = 1; + app->import_from_mnemonic = 0; scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1New); scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1); return true; + } else if(event.event == SubmenuIndexScene1Import) { + app->import_from_mnemonic = 1; + app->input_state = FlipBipTextInputMnemonic; + view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdTextInput); + return true; } else if(event.event == SubmenuIndexSettings) { scene_manager_set_scene_state( app->scene_manager, FlipBipSceneMenu, SubmenuIndexSettings); diff --git a/views/flipbip_scene_1.c b/views/flipbip_scene_1.c index 159b99f2281..251ee95b5c7 100644 --- a/views/flipbip_scene_1.c +++ b/views/flipbip_scene_1.c @@ -314,22 +314,24 @@ static int flipbip_scene_1_model_init( if(overwrite || (!flipbip_has_settings(true) && !flipbip_has_settings(false))) { // Generate a random mnemonic using trezor-crypto const char* mnemonic_gen = mnemonic_generate(strength); + // Check if the mnemonic is valid + if(mnemonic_check(mnemonic_gen) == 0) return FlipBipStatusMnemonicCheckError; // 13 = mnemonic check error // Save the mnemonic to persistent storage - if(!flipbip_save_settings_secure(mnemonic_gen)) return 1; // 1 = save error + else if(!flipbip_save_settings_secure(mnemonic_gen)) return FlipBipStatusSaveError; // 12 = save error // Clear the generated mnemonic from memory mnemonic_clear(); model->mnemonic_only = true; } // Load the mnemonic from persistent storage - if(!flipbip_load_settings_secure(mnemonic)) return 2; // 2 = load error + if(!flipbip_load_settings_secure(mnemonic)) return FlipBipStatusLoadError; // 11 = load error model->mnemonic = mnemonic; // Check if the mnemonic is valid - if(mnemonic_check(model->mnemonic) == 0) return 3; // 3 = mnemonic check error + if(mnemonic_check(model->mnemonic) == 0) return FlipBipStatusMnemonicCheckError; // 13 = mnemonic check error // if we are only generating the mnemonic, return if(model->mnemonic_only) { - return -1; // -1 = mnemonic only, return from parent + return FlipBipStatusReturn; // 10 = mnemonic only, return from parent } // test mnemonic @@ -408,7 +410,7 @@ static int flipbip_scene_1_model_init( #endif // 0 = success - return 0; + return FlipBipStatusSuccess; } bool flipbip_scene_1_input(InputEvent* event, void* context) { @@ -524,7 +526,7 @@ void flipbip_scene_1_enter(void* context) { } // BIP44 Coin setting - uint32_t coin = app->bip44_coin; + const uint32_t coin = app->bip44_coin; // coin_name, derivation_path s_derivation_text = COIN_TEXT_ARRAY[coin][1]; @@ -543,31 +545,38 @@ void flipbip_scene_1_enter(void* context) { { // s_busy = true; - const int status = - flipbip_scene_1_model_init(model, strength, coin, overwrite, passphrase_text); + const int status = flipbip_scene_1_model_init( + model, + strength, + coin, + overwrite, + passphrase_text); // nonzero status, free the mnemonic - if(status != 0) { + if(status != FlipBipStatusSuccess) { memzero((void*)model->mnemonic, strlen(model->mnemonic)); free((void*)model->mnemonic); } // if error, set the error message - if(status == 1) { + if(status == FlipBipStatusSaveError) { model->mnemonic = "ERROR:,Save error"; model->page = 2; - } else if(status == 2) { + flipbip_play_long_bump(app); + } else if(status == FlipBipStatusLoadError) { model->mnemonic = "ERROR:,Load error"; model->page = 2; - } else if(status == 3) { + flipbip_play_long_bump(app); + } else if(status == FlipBipStatusMnemonicCheckError) { model->mnemonic = "ERROR:,Mnemonic check failed"; model->page = 2; + flipbip_play_long_bump(app); } // s_busy = false; // if overwrite is set and mnemonic generated, return from scene immediately - if(status == -1) { + if(status == FlipBipStatusReturn) { instance->callback(FlipBipCustomEventScene1Back, instance->context); } },