diff --git a/applications/plugins/totp/lib/config/config.c b/applications/plugins/totp/lib/config/config.c index c9c10aebc..5c20ed576 100644 --- a/applications/plugins/totp/lib/config/config.c +++ b/applications/plugins/totp/lib/config/config.c @@ -3,7 +3,8 @@ #include "../../types/common.h" #include "../../types/token_info.h" -#define CONFIG_FILE_PATH "/ext/apps/Misc/totp.conf" +#define CONFIG_FILE_DIRECTORY_PATH "/ext/apps/Misc" +#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf" #define CONFIG_FILE_HEADER "Flipper TOTP plugin config file" #define CONFIG_FILE_VERSION 1 @@ -19,12 +20,22 @@ FlipperFormat* totp_open_config_file(Storage* storage) { FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); if (storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK) { + FURI_LOG_D(LOGGING_TAG, "Config file %s found", CONFIG_FILE_PATH); if(!flipper_format_file_open_existing(fff_data_file, CONFIG_FILE_PATH)) { FURI_LOG_E(LOGGING_TAG, "Error opening existing file %s", CONFIG_FILE_PATH); totp_close_config_file(fff_data_file); return NULL; } } else { + FURI_LOG_D(LOGGING_TAG, "Config file %s is not found. Will create new.", CONFIG_FILE_PATH); + if (storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) { + FURI_LOG_D(LOGGING_TAG, "Directory %s doesn't exist. Will create new.", CONFIG_FILE_DIRECTORY_PATH); + if (!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) { + FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH); + return NULL; + } + } + if (!flipper_format_file_open_new(fff_data_file, CONFIG_FILE_PATH)) { totp_close_config_file(fff_data_file); FURI_LOG_E(LOGGING_TAG, "Error creating new file %s", CONFIG_FILE_PATH); @@ -50,7 +61,7 @@ void totp_full_save_config_file(PluginState* const plugin_state) { flipper_format_file_open_always(fff_data_file, CONFIG_FILE_PATH); flipper_format_write_header_cstr(fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_VERSION); - flipper_format_write_hex(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], 16); + flipper_format_write_hex(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE); flipper_format_write_hex(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, plugin_state->crypto_verify_data, plugin_state->crypto_verify_data_length); flipper_format_write_float(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1); ListNode* node = plugin_state->tokens_list; @@ -80,7 +91,7 @@ void totp_config_file_load_base(PluginState* const plugin_state) { return; } - if (!flipper_format_read_hex(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], 16)) { + if (!flipper_format_read_hex(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) { FURI_LOG_D(LOGGING_TAG, "Missing base IV"); } diff --git a/applications/plugins/totp/lib/ui/constants.h b/applications/plugins/totp/lib/ui/constants.h index 658686c8d..0946a763d 100644 --- a/applications/plugins/totp/lib/ui/constants.h +++ b/applications/plugins/totp/lib/ui/constants.h @@ -3,7 +3,7 @@ #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 -#define SCREEN_WIDTH_CENTER 64 -#define SCREEN_HEIGHT_CENTER 32 +#define SCREEN_WIDTH_CENTER (SCREEN_WIDTH >> 1) +#define SCREEN_HEIGHT_CENTER (SCREEN_HEIGHT >> 1) #endif diff --git a/applications/plugins/totp/lib/ui/icons.h b/applications/plugins/totp/lib/ui/icons.h index 8f60bafa0..ea4b6812e 100644 --- a/applications/plugins/totp/lib/ui/icons.h +++ b/applications/plugins/totp/lib/ui/icons.h @@ -3,28 +3,12 @@ #include -static const uint8_t ICON_ARROW_LEFT_8x9[] = { - 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, -}; +#define ICON_ARROW_LEFT_8x9_WIDTH 8 +#define ICON_ARROW_LEFT_8x9_HEIGHT 9 +static const uint8_t ICON_ARROW_LEFT_8x9[] = { 0x80,0xe0,0xf8,0xfe,0xff,0xfe,0xf8,0xe0,0x80 }; -static const uint8_t ICON_ARROW_RIGHT_8x9[] = { - 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, -}; +#define ICON_ARROW_RIGHT_8x9_WIDTH 8 +#define ICON_ARROW_RIGHT_8x9_HEIGHT 9 +static const uint8_t ICON_ARROW_RIGHT_8x9[] = { 0x01,0x07,0x1f,0x7f,0xff,0x7f,0x1f,0x07,0x01 }; #endif diff --git a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c index ee930cdfe..068d118af 100644 --- a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c +++ b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c @@ -1,16 +1,15 @@ #include "totp_scene_authenticate.h" +#include #include "../../types/common.h" #include "../../lib/ui/icons.h" -#include "../../lib/ui/canvas_extensions.h" #include "../../lib/ui/constants.h" #include "../../lib/config/config.h" #include "../scene_director.h" #include "../totp_scenes_enum.h" -#define MAX_CODE_LENGTH 16 +#define MAX_CODE_LENGTH TOTP_IV_SIZE #define CRYPTO_VERIFY_KEY "FFF_Crypto_pass" #define CRYPTO_VERIFY_KEY_LENGTH 16 -#define BASE_IV_LENGTH 16 typedef struct { uint8_t code_input[MAX_CODE_LENGTH]; @@ -18,23 +17,29 @@ typedef struct { } SceneState; void totp_scene_authenticate_init(PluginState* plugin_state) { - for (uint8_t i = 0; i < MAX_CODE_LENGTH; i++) plugin_state->iv[i] = 0; + memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE); } void totp_scene_authenticate_activate(PluginState* plugin_state) { SceneState* scene_state = malloc(sizeof(SceneState)); scene_state->code_length = 0; - for (uint8_t i = 0; i < MAX_CODE_LENGTH; i++) scene_state->code_input[i] = 0; + memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH); plugin_state->current_scene_state = scene_state; } void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state) { SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; + + int v_shift = 0; + if (scene_state->code_length > 0) { + v_shift = -10; + } + if (plugin_state->crypto_verify_data == NULL) { - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER - 20, AlignCenter, AlignCenter, "Use arrow keys"); - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER - 5, AlignCenter, AlignCenter, "to setup new PIN"); + canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER - 10 + v_shift, AlignCenter, AlignCenter, "Use arrow keys"); + canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER + 5 + v_shift, AlignCenter, AlignCenter, "to setup new PIN"); } else { - canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER - 10, AlignCenter, AlignCenter, "Use arrow keys to enter PIN"); + canvas_draw_str_aligned(canvas, SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER + v_shift, AlignCenter, AlignCenter, "Use arrow keys to enter PIN"); } const uint8_t PIN_ASTERISK_RADIUS = 3; const uint8_t PIN_ASTERISK_STEP = (PIN_ASTERISK_RADIUS << 1) + 2; @@ -56,7 +61,7 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* return false; } else if(event->input.type == InputTypePress) { SceneState* scene_state = (SceneState *)plugin_state->current_scene_state; - + const uint8_t ARROW_UP_CODE = 2; const uint8_t ARROW_RIGHT_CODE = 8; const uint8_t ARROW_DOWN_CODE = 11; @@ -90,10 +95,10 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* case InputKeyOk: if (plugin_state->crypto_verify_data == NULL) { FURI_LOG_D(LOGGING_TAG, "Generating new IV"); - furi_hal_random_fill_buf(&plugin_state->base_iv[0], BASE_IV_LENGTH); + furi_hal_random_fill_buf(&plugin_state->base_iv[0], TOTP_IV_SIZE); } - memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], BASE_IV_LENGTH); + memcpy(&plugin_state->iv[0], &plugin_state->base_iv[0], TOTP_IV_SIZE); for (uint8_t i = 0; i < scene_state->code_length; i++) { plugin_state->iv[i] = plugin_state->iv[i] ^ (uint8_t)(scene_state->code_input[i] * (i + 1)); } @@ -107,7 +112,7 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* furi_hal_crypto_store_load_key(CRYPTO_KEY_SLOT, &plugin_state->iv[0]); furi_hal_crypto_encrypt((uint8_t* )CRYPTO_VERIFY_KEY, plugin_state->crypto_verify_data, CRYPTO_VERIFY_KEY_LENGTH); furi_hal_crypto_store_unload_key(CRYPTO_KEY_SLOT); - flipper_format_insert_or_update_hex(config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, BASE_IV_LENGTH); + flipper_format_insert_or_update_hex(config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE); flipper_format_insert_or_update_hex(config_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, plugin_state->crypto_verify_data, CRYPTO_VERIFY_KEY_LENGTH); totp_close_config_file(config_file); totp_close_storage(); @@ -128,11 +133,16 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); } else { FURI_LOG_D(LOGGING_TAG, "PIN is NOT valid"); - for (uint8_t i = 0; i < MAX_CODE_LENGTH; i++) { - scene_state->code_input[i] = 0; - plugin_state->iv[i] = 0; - } + memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH); + memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE); scene_state->code_length = 0; + + DialogMessage* message = dialog_message_alloc(); + dialog_message_set_buttons(message, "Try again", NULL, NULL); + dialog_message_set_header(message, "You entered\ninvalid PIN", SCREEN_WIDTH_CENTER - 25, SCREEN_HEIGHT_CENTER - 5, AlignCenter, AlignCenter); + dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17); + dialog_message_show(plugin_state->dialogs, message); + dialog_message_free(message); } break; case InputKeyBack: diff --git a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c index 0bfe65d5f..0d75972cb 100644 --- a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c +++ b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c @@ -5,7 +5,6 @@ #include "../../types/token_info.h" #include "../../types/common.h" #include "../../lib/ui/icons.h" -#include "../../lib/ui/canvas_extensions.h" #include "../../lib/ui/constants.h" #include "../../lib/totp/totp.h" #include "../../lib/config/config.h" @@ -152,8 +151,8 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ BAR_HEIGHT); if (plugin_state->tokens_count > 1) { - canvas_draw_dots(canvas, 0, SCREEN_HEIGHT_CENTER - 24, 8, 9, ICON_ARROW_LEFT_8x9); - canvas_draw_dots(canvas, SCREEN_WIDTH - 9, SCREEN_HEIGHT_CENTER - 24, 8, 9, ICON_ARROW_RIGHT_8x9); + canvas_draw_xbm(canvas, 0, SCREEN_HEIGHT_CENTER - 24, ICON_ARROW_LEFT_8x9_WIDTH, ICON_ARROW_LEFT_8x9_HEIGHT, &ICON_ARROW_LEFT_8x9[0]); + canvas_draw_xbm(canvas, SCREEN_WIDTH - 9, SCREEN_HEIGHT_CENTER - 24, ICON_ARROW_RIGHT_8x9_WIDTH, ICON_ARROW_RIGHT_8x9_HEIGHT, &ICON_ARROW_RIGHT_8x9[0]); } } diff --git a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c index 8f35dfcf7..122f8cc17 100644 --- a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c +++ b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c @@ -63,14 +63,12 @@ bool totp_scene_token_menu_handle_event(PluginEvent* const event, PluginState* p break; } case DeleteToken: { - DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogMessage* message = dialog_message_alloc(); dialog_message_set_buttons(message, "No", NULL, "Yes"); dialog_message_set_header(message, "Confirmation", 0, 0, AlignLeft, AlignTop); dialog_message_set_text(message, "Are you sure want to delete?", SCREEN_WIDTH_CENTER, SCREEN_HEIGHT_CENTER, AlignCenter, AlignCenter); - DialogMessageButton dialog_result = dialog_message_show(dialogs, message); + DialogMessageButton dialog_result = dialog_message_show(plugin_state->dialogs, message); dialog_message_free(message); - furi_record_close(RECORD_DIALOGS); if (dialog_result == DialogMessageButtonRight) { uint8_t i = 0; diff --git a/applications/plugins/totp/totp_app.c b/applications/plugins/totp/totp_app.c index b55acefeb..a420e1ed5 100644 --- a/applications/plugins/totp/totp_app.c +++ b/applications/plugins/totp/totp_app.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queu static void totp_state_init(PluginState* const plugin_state) { plugin_state->gui = furi_record_open(RECORD_GUI); plugin_state->notification = furi_record_open(RECORD_NOTIFICATION); + plugin_state->dialogs = furi_record_open(RECORD_DIALOGS); totp_config_file_load_base(plugin_state); totp_scene_director_init_scenes(plugin_state); @@ -50,6 +52,7 @@ static void dispose_plugin_state(PluginState* plugin_state) { furi_record_close(RECORD_GUI); furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_DIALOGS); ListNode* node = plugin_state->tokens_list; ListNode* tmp; diff --git a/applications/plugins/totp/types/plugin_state.h b/applications/plugins/totp/types/plugin_state.h index 52e757fa0..e026d4d78 100644 --- a/applications/plugins/totp/types/plugin_state.h +++ b/applications/plugins/totp/types/plugin_state.h @@ -3,14 +3,18 @@ #include #include +#include #include "../lib/list/list.h" #include "../scenes/totp_scenes_enum.h" +#define TOTP_IV_SIZE 16 + typedef struct { Scene current_scene; void* current_scene_state; bool changing_scene; NotificationApp* notification; + DialogsApp* dialogs; Gui* gui; float timezone_offset; @@ -20,8 +24,8 @@ typedef struct { uint8_t* crypto_verify_data; uint8_t crypto_verify_data_length; - uint8_t iv[16]; - uint8_t base_iv[16]; + uint8_t iv[TOTP_IV_SIZE]; + uint8_t base_iv[TOTP_IV_SIZE]; } PluginState; #endif