|
@@ -9,6 +9,8 @@
|
|
|
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("authenticator")
|
|
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("authenticator")
|
|
|
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
|
|
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
|
|
|
#define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup"
|
|
#define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup"
|
|
|
|
|
+#define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp"
|
|
|
|
|
+#define CONFIG_FILE_ORIG_PATH CONFIG_FILE_PATH ".orig"
|
|
|
#define CONFIG_FILE_PATH_PREVIOUS EXT_PATH("apps/Misc") "/totp.conf"
|
|
#define CONFIG_FILE_PATH_PREVIOUS EXT_PATH("apps/Misc") "/totp.conf"
|
|
|
|
|
|
|
|
static char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
|
static char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
|
@@ -36,15 +38,38 @@ static void token_info_set_algo_from_str(TokenInfo* token_info, const FuriString
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Storage* totp_open_storage() {
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @brief Opens storage record
|
|
|
|
|
+ * @return Storage record
|
|
|
|
|
+ */
|
|
|
|
|
+static Storage* totp_open_storage() {
|
|
|
return furi_record_open(RECORD_STORAGE);
|
|
return furi_record_open(RECORD_STORAGE);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_close_storage() {
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @brief Closes storage record
|
|
|
|
|
+ */
|
|
|
|
|
+static void totp_close_storage() {
|
|
|
furi_record_close(RECORD_STORAGE);
|
|
furi_record_close(RECORD_STORAGE);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-FlipperFormat* totp_open_config_file(Storage* storage) {
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * @brief Closes config file
|
|
|
|
|
+ * @param file config file reference
|
|
|
|
|
+ */
|
|
|
|
|
+static void totp_close_config_file(FlipperFormat* file) {
|
|
|
|
|
+ if(file == NULL) return;
|
|
|
|
|
+ flipper_format_file_close(file);
|
|
|
|
|
+ flipper_format_free(file);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @brief Opens or creates TOTP application standard config file
|
|
|
|
|
+ * @param storage storage record to use
|
|
|
|
|
+ * @param[out] file opened config file
|
|
|
|
|
+ * @return Config file open result
|
|
|
|
|
+ */
|
|
|
|
|
+static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperFormat** file) {
|
|
|
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
|
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
|
|
|
|
|
|
|
if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK) {
|
|
if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) == FSE_OK) {
|
|
@@ -52,7 +77,7 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
|
|
if(!flipper_format_file_open_existing(fff_data_file, 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);
|
|
FURI_LOG_E(LOGGING_TAG, "Error opening existing file %s", CONFIG_FILE_PATH);
|
|
|
totp_close_config_file(fff_data_file);
|
|
totp_close_config_file(fff_data_file);
|
|
|
- return NULL;
|
|
|
|
|
|
|
+ return TotpConfigFileOpenError;
|
|
|
}
|
|
}
|
|
|
} else if(storage_common_stat(storage, CONFIG_FILE_PATH_PREVIOUS, NULL) == FSE_OK) {
|
|
} else if(storage_common_stat(storage, CONFIG_FILE_PATH_PREVIOUS, NULL) == FSE_OK) {
|
|
|
FURI_LOG_D(LOGGING_TAG, "Old config file %s found", CONFIG_FILE_PATH_PREVIOUS);
|
|
FURI_LOG_D(LOGGING_TAG, "Old config file %s found", CONFIG_FILE_PATH_PREVIOUS);
|
|
@@ -63,15 +88,17 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
|
|
CONFIG_FILE_DIRECTORY_PATH);
|
|
CONFIG_FILE_DIRECTORY_PATH);
|
|
|
if(!storage_simply_mkdir(storage, 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);
|
|
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
|
|
|
- return NULL;
|
|
|
|
|
|
|
+ totp_close_config_file(fff_data_file);
|
|
|
|
|
+ return TotpConfigFileOpenError;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if(storage_common_rename(storage, CONFIG_FILE_PATH_PREVIOUS, CONFIG_FILE_PATH) != FSE_OK) {
|
|
if(storage_common_rename(storage, CONFIG_FILE_PATH_PREVIOUS, CONFIG_FILE_PATH) != FSE_OK) {
|
|
|
FURI_LOG_E(LOGGING_TAG, "Error moving config to %s", CONFIG_FILE_PATH);
|
|
FURI_LOG_E(LOGGING_TAG, "Error moving config to %s", CONFIG_FILE_PATH);
|
|
|
- return NULL;
|
|
|
|
|
|
|
+ totp_close_config_file(fff_data_file);
|
|
|
|
|
+ return TotpConfigFileOpenError;
|
|
|
}
|
|
}
|
|
|
FURI_LOG_I(LOGGING_TAG, "Applied config file path migration");
|
|
FURI_LOG_I(LOGGING_TAG, "Applied config file path migration");
|
|
|
- return totp_open_config_file(storage);
|
|
|
|
|
|
|
+ return totp_open_config_file(storage, file);
|
|
|
} else {
|
|
} else {
|
|
|
FURI_LOG_D(LOGGING_TAG, "Config file %s is not found. Will create new.", CONFIG_FILE_PATH);
|
|
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) {
|
|
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
|
|
@@ -81,14 +108,14 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
|
|
CONFIG_FILE_DIRECTORY_PATH);
|
|
CONFIG_FILE_DIRECTORY_PATH);
|
|
|
if(!storage_simply_mkdir(storage, 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);
|
|
FURI_LOG_E(LOGGING_TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
|
|
|
- return NULL;
|
|
|
|
|
|
|
+ return TotpConfigFileOpenError;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(!flipper_format_file_open_new(fff_data_file, CONFIG_FILE_PATH)) {
|
|
if(!flipper_format_file_open_new(fff_data_file, CONFIG_FILE_PATH)) {
|
|
|
totp_close_config_file(fff_data_file);
|
|
totp_close_config_file(fff_data_file);
|
|
|
FURI_LOG_E(LOGGING_TAG, "Error creating new file %s", CONFIG_FILE_PATH);
|
|
FURI_LOG_E(LOGGING_TAG, "Error creating new file %s", CONFIG_FILE_PATH);
|
|
|
- return NULL;
|
|
|
|
|
|
|
+ return TotpConfigFileOpenError;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
flipper_format_write_header_cstr(
|
|
flipper_format_write_header_cstr(
|
|
@@ -153,228 +180,415 @@ FlipperFormat* totp_open_config_file(Storage* storage) {
|
|
|
if(!flipper_format_rewind(fff_data_file)) {
|
|
if(!flipper_format_rewind(fff_data_file)) {
|
|
|
totp_close_config_file(fff_data_file);
|
|
totp_close_config_file(fff_data_file);
|
|
|
FURI_LOG_E(LOGGING_TAG, "Rewind error");
|
|
FURI_LOG_E(LOGGING_TAG, "Rewind error");
|
|
|
- return NULL;
|
|
|
|
|
|
|
+ return TotpConfigFileOpenError;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return fff_data_file;
|
|
|
|
|
|
|
+ *file = fff_data_file;
|
|
|
|
|
+ return TotpConfigFileOpenSuccess;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* token_info) {
|
|
|
|
|
- flipper_format_seek_to_end(file);
|
|
|
|
|
- flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name);
|
|
|
|
|
- bool token_is_valid = token_info->token != NULL && token_info->token_length > 0;
|
|
|
|
|
- if(!token_is_valid) {
|
|
|
|
|
- flipper_format_write_comment_cstr(file, "!!! WARNING BEGIN: INVALID TOKEN !!!");
|
|
|
|
|
- }
|
|
|
|
|
- flipper_format_write_hex(
|
|
|
|
|
- file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length);
|
|
|
|
|
- if(!token_is_valid) {
|
|
|
|
|
- flipper_format_write_comment_cstr(file, "!!! WARNING END !!!");
|
|
|
|
|
- }
|
|
|
|
|
- flipper_format_write_string_cstr(
|
|
|
|
|
- file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info));
|
|
|
|
|
- uint32_t tmp_uint32 = token_info->digits;
|
|
|
|
|
- flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &tmp_uint32, 1);
|
|
|
|
|
|
|
+TotpConfigFileUpdateResult
|
|
|
|
|
+ totp_config_file_save_new_token_i(FlipperFormat* file, const TokenInfo* token_info) {
|
|
|
|
|
+ TotpConfigFileUpdateResult update_result;
|
|
|
|
|
+ do {
|
|
|
|
|
+ if(!flipper_format_seek_to_end(file)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_string_cstr(file, TOTP_CONFIG_KEY_TOKEN_NAME, token_info->name)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bool token_is_valid = token_info->token != NULL && token_info->token_length > 0;
|
|
|
|
|
+ if(!token_is_valid &&
|
|
|
|
|
+ !flipper_format_write_comment_cstr(file, "!!! WARNING BEGIN: INVALID TOKEN !!!")) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_hex(
|
|
|
|
|
+ file, TOTP_CONFIG_KEY_TOKEN_SECRET, token_info->token, token_info->token_length)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!token_is_valid && !flipper_format_write_comment_cstr(file, "!!! WARNING END !!!")) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_string_cstr(
|
|
|
|
|
+ file, TOTP_CONFIG_KEY_TOKEN_ALGO, token_info_get_algo_as_cstr(token_info))) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ uint32_t tmp_uint32 = token_info->digits;
|
|
|
|
|
+ if(!flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &tmp_uint32, 1)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ update_result = TotpConfigFileUpdateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
+
|
|
|
|
|
+ return update_result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_config_file_save_new_token(const TokenInfo* token_info) {
|
|
|
|
|
|
|
+TotpConfigFileUpdateResult totp_config_file_save_new_token(const TokenInfo* token_info) {
|
|
|
Storage* cfg_storage = totp_open_storage();
|
|
Storage* cfg_storage = totp_open_storage();
|
|
|
- FlipperFormat* file = totp_open_config_file(cfg_storage);
|
|
|
|
|
|
|
+ FlipperFormat* file;
|
|
|
|
|
+ TotpConfigFileUpdateResult update_result;
|
|
|
|
|
+
|
|
|
|
|
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ do {
|
|
|
|
|
+ if(totp_config_file_save_new_token_i(file, token_info) !=
|
|
|
|
|
+ TotpConfigFileUpdateSuccess) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- totp_config_file_save_new_token_i(file, token_info);
|
|
|
|
|
|
|
+ update_result = TotpConfigFileUpdateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
+
|
|
|
|
|
+ totp_close_config_file(file);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- totp_close_config_file(file);
|
|
|
|
|
totp_close_storage();
|
|
totp_close_storage();
|
|
|
|
|
+ return update_result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_config_file_update_timezone_offset(float new_timezone_offset) {
|
|
|
|
|
|
|
+TotpConfigFileUpdateResult totp_config_file_update_timezone_offset(float new_timezone_offset) {
|
|
|
Storage* cfg_storage = totp_open_storage();
|
|
Storage* cfg_storage = totp_open_storage();
|
|
|
- FlipperFormat* file = totp_open_config_file(cfg_storage);
|
|
|
|
|
|
|
+ FlipperFormat* file;
|
|
|
|
|
+ TotpConfigFileUpdateResult update_result;
|
|
|
|
|
+
|
|
|
|
|
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ do {
|
|
|
|
|
+ if(!flipper_format_insert_or_update_float(
|
|
|
|
|
+ file, TOTP_CONFIG_KEY_TIMEZONE, &new_timezone_offset, 1)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- flipper_format_insert_or_update_float(file, TOTP_CONFIG_KEY_TIMEZONE, &new_timezone_offset, 1);
|
|
|
|
|
|
|
+ update_result = TotpConfigFileUpdateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
+
|
|
|
|
|
+ totp_close_config_file(file);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- totp_close_config_file(file);
|
|
|
|
|
totp_close_storage();
|
|
totp_close_storage();
|
|
|
|
|
+ return update_result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_config_file_update_notification_method(NotificationMethod new_notification_method) {
|
|
|
|
|
|
|
+TotpConfigFileUpdateResult
|
|
|
|
|
+ totp_config_file_update_notification_method(NotificationMethod new_notification_method) {
|
|
|
Storage* cfg_storage = totp_open_storage();
|
|
Storage* cfg_storage = totp_open_storage();
|
|
|
- FlipperFormat* file = totp_open_config_file(cfg_storage);
|
|
|
|
|
|
|
+ FlipperFormat* file;
|
|
|
|
|
+ TotpConfigFileUpdateResult update_result;
|
|
|
|
|
+
|
|
|
|
|
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ do {
|
|
|
|
|
+ uint32_t tmp_uint32 = new_notification_method;
|
|
|
|
|
+ if(!flipper_format_insert_or_update_uint32(
|
|
|
|
|
+ file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ update_result = TotpConfigFileUpdateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
|
|
|
- uint32_t tmp_uint32 = new_notification_method;
|
|
|
|
|
- flipper_format_insert_or_update_uint32(
|
|
|
|
|
- file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
|
|
|
|
|
|
|
+ totp_close_config_file(file);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- totp_close_config_file(file);
|
|
|
|
|
totp_close_storage();
|
|
totp_close_storage();
|
|
|
|
|
+ return update_result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
|
|
|
|
|
|
+TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginState* plugin_state) {
|
|
|
Storage* cfg_storage = totp_open_storage();
|
|
Storage* cfg_storage = totp_open_storage();
|
|
|
- FlipperFormat* file = totp_open_config_file(cfg_storage);
|
|
|
|
|
|
|
+ FlipperFormat* file;
|
|
|
|
|
+ TotpConfigFileUpdateResult update_result;
|
|
|
|
|
+ if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ do {
|
|
|
|
|
+ if(!flipper_format_insert_or_update_float(
|
|
|
|
|
+ file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ uint32_t tmp_uint32 = plugin_state->notification_method;
|
|
|
|
|
+ if(!flipper_format_insert_or_update_uint32(
|
|
|
|
|
+ file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ update_result = TotpConfigFileUpdateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
|
|
|
- flipper_format_insert_or_update_float(
|
|
|
|
|
- file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1);
|
|
|
|
|
- uint32_t tmp_uint32 = plugin_state->notification_method;
|
|
|
|
|
- flipper_format_insert_or_update_uint32(
|
|
|
|
|
- file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
|
|
|
|
|
|
|
+ totp_close_config_file(file);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- totp_close_config_file(file);
|
|
|
|
|
totp_close_storage();
|
|
totp_close_storage();
|
|
|
|
|
+ return update_result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_full_save_config_file(const PluginState* const plugin_state) {
|
|
|
|
|
|
|
+TotpConfigFileUpdateResult totp_full_save_config_file(const PluginState* const plugin_state) {
|
|
|
Storage* storage = totp_open_storage();
|
|
Storage* storage = totp_open_storage();
|
|
|
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
|
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
|
|
|
|
+ TotpConfigFileUpdateResult result = TotpConfigFileUpdateSuccess;
|
|
|
|
|
|
|
|
- flipper_format_file_open_always(fff_data_file, CONFIG_FILE_PATH);
|
|
|
|
|
- flipper_format_write_header_cstr(
|
|
|
|
|
- fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION);
|
|
|
|
|
- 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);
|
|
|
|
|
- flipper_format_write_bool(fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1);
|
|
|
|
|
- uint32_t tmp_uint32 = plugin_state->notification_method;
|
|
|
|
|
- flipper_format_write_uint32(
|
|
|
|
|
- fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
|
|
|
|
|
-
|
|
|
|
|
- TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
|
|
|
|
- const TokenInfo* token_info = node->data;
|
|
|
|
|
- totp_config_file_save_new_token_i(fff_data_file, token_info);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ do {
|
|
|
|
|
+ if(!flipper_format_file_open_always(fff_data_file, CONFIG_FILE_TEMP_PATH)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_header_cstr(
|
|
|
|
|
+ fff_data_file, CONFIG_FILE_HEADER, CONFIG_FILE_ACTUAL_VERSION)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_hex(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_BASE_IV, &plugin_state->base_iv[0], TOTP_IV_SIZE)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_hex(
|
|
|
|
|
+ fff_data_file,
|
|
|
|
|
+ TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
|
|
|
|
+ plugin_state->crypto_verify_data,
|
|
|
|
|
+ plugin_state->crypto_verify_data_length)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_float(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_write_bool(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ uint32_t tmp_uint32 = plugin_state->notification_method;
|
|
|
|
|
+ if(!flipper_format_write_uint32(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bool tokens_written = true;
|
|
|
|
|
+ TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
|
|
|
|
+ const TokenInfo* token_info = node->data;
|
|
|
|
|
+ tokens_written = tokens_written &&
|
|
|
|
|
+ totp_config_file_save_new_token_i(fff_data_file, token_info) ==
|
|
|
|
|
+ TotpConfigFileUpdateSuccess;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ if(!tokens_written) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ } while(false);
|
|
|
|
|
|
|
|
totp_close_config_file(fff_data_file);
|
|
totp_close_config_file(fff_data_file);
|
|
|
|
|
+
|
|
|
|
|
+ if(result == TotpConfigFileUpdateSuccess) {
|
|
|
|
|
+ if(storage_file_exists(storage, CONFIG_FILE_ORIG_PATH)) {
|
|
|
|
|
+ storage_simply_remove(storage, CONFIG_FILE_ORIG_PATH);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(storage_common_rename(storage, CONFIG_FILE_PATH, CONFIG_FILE_ORIG_PATH) != FSE_OK) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ } else if(storage_common_rename(storage, CONFIG_FILE_TEMP_PATH, CONFIG_FILE_PATH) != FSE_OK) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ } else if(!storage_simply_remove(storage, CONFIG_FILE_ORIG_PATH)) {
|
|
|
|
|
+ result = TotpConfigFileUpdateError;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
totp_close_storage();
|
|
totp_close_storage();
|
|
|
|
|
+ return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_config_file_load_base(PluginState* const plugin_state) {
|
|
|
|
|
|
|
+TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_state) {
|
|
|
Storage* storage = totp_open_storage();
|
|
Storage* storage = totp_open_storage();
|
|
|
- FlipperFormat* fff_data_file = totp_open_config_file(storage);
|
|
|
|
|
|
|
+ FlipperFormat* fff_data_file;
|
|
|
|
|
+
|
|
|
|
|
+ TotpConfigFileOpenResult result;
|
|
|
|
|
+ if((result = totp_open_config_file(storage, &fff_data_file)) != TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ totp_close_storage();
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
plugin_state->timezone_offset = 0;
|
|
plugin_state->timezone_offset = 0;
|
|
|
|
|
|
|
|
FuriString* temp_str = furi_string_alloc();
|
|
FuriString* temp_str = furi_string_alloc();
|
|
|
|
|
|
|
|
- uint32_t file_version;
|
|
|
|
|
- if(!flipper_format_read_header(fff_data_file, temp_str, &file_version)) {
|
|
|
|
|
- FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
|
|
|
|
|
- furi_string_free(temp_str);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ do {
|
|
|
|
|
+ uint32_t file_version;
|
|
|
|
|
+ if(!flipper_format_read_header(fff_data_file, temp_str, &file_version)) {
|
|
|
|
|
+ FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(file_version < CONFIG_FILE_ACTUAL_VERSION) {
|
|
|
|
|
- FURI_LOG_I(
|
|
|
|
|
- LOGGING_TAG,
|
|
|
|
|
- "Obsolete config file version detected. Current version: %" PRIu32
|
|
|
|
|
- "; Actual version: %" PRId16,
|
|
|
|
|
- file_version,
|
|
|
|
|
- CONFIG_FILE_ACTUAL_VERSION);
|
|
|
|
|
- totp_close_config_file(fff_data_file);
|
|
|
|
|
|
|
+ if(file_version < CONFIG_FILE_ACTUAL_VERSION) {
|
|
|
|
|
+ FURI_LOG_I(
|
|
|
|
|
+ LOGGING_TAG,
|
|
|
|
|
+ "Obsolete config file version detected. Current version: %" PRIu32
|
|
|
|
|
+ "; Actual version: %" PRId16,
|
|
|
|
|
+ file_version,
|
|
|
|
|
+ CONFIG_FILE_ACTUAL_VERSION);
|
|
|
|
|
+ totp_close_config_file(fff_data_file);
|
|
|
|
|
|
|
|
- if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) {
|
|
|
|
|
- storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) {
|
|
|
|
|
+ storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) {
|
|
|
|
|
- FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH);
|
|
|
|
|
- fff_data_file = totp_open_config_file(storage);
|
|
|
|
|
- FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
|
|
|
|
|
- flipper_format_file_open_existing(fff_backup_data_file, CONFIG_FILE_BACKUP_PATH);
|
|
|
|
|
|
|
+ if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) {
|
|
|
|
|
+ FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH);
|
|
|
|
|
+ if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(file_version == 1) {
|
|
|
|
|
- if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
|
|
|
|
|
- FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
|
|
|
|
|
- } else {
|
|
|
|
|
- FURI_LOG_W(LOGGING_TAG, "An error occurred during migration from v1 to v2");
|
|
|
|
|
|
|
+ FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
|
|
|
|
|
+ if(!flipper_format_file_open_existing(
|
|
|
|
|
+ fff_backup_data_file, CONFIG_FILE_BACKUP_PATH)) {
|
|
|
|
|
+ flipper_format_file_close(fff_backup_data_file);
|
|
|
|
|
+ flipper_format_free(fff_backup_data_file);
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- flipper_format_file_close(fff_backup_data_file);
|
|
|
|
|
- flipper_format_free(fff_backup_data_file);
|
|
|
|
|
- flipper_format_rewind(fff_data_file);
|
|
|
|
|
- } else {
|
|
|
|
|
- FURI_LOG_E(
|
|
|
|
|
- LOGGING_TAG,
|
|
|
|
|
- "An error occurred during taking backup of %s into %s before migration",
|
|
|
|
|
- CONFIG_FILE_PATH,
|
|
|
|
|
- CONFIG_FILE_BACKUP_PATH);
|
|
|
|
|
|
|
+ if(file_version == 1) {
|
|
|
|
|
+ if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
|
|
|
|
|
+ FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ FURI_LOG_W(
|
|
|
|
|
+ LOGGING_TAG, "An error occurred during migration from v1 to v2");
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ flipper_format_file_close(fff_backup_data_file);
|
|
|
|
|
+ flipper_format_free(fff_backup_data_file);
|
|
|
|
|
+ flipper_format_rewind(fff_data_file);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ FURI_LOG_E(
|
|
|
|
|
+ LOGGING_TAG,
|
|
|
|
|
+ "An error occurred during taking backup of %s into %s before migration",
|
|
|
|
|
+ CONFIG_FILE_PATH,
|
|
|
|
|
+ CONFIG_FILE_BACKUP_PATH);
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- 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");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ 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");
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- flipper_format_rewind(fff_data_file);
|
|
|
|
|
|
|
+ if(!flipper_format_rewind(fff_data_file)) {
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- uint32_t crypto_size;
|
|
|
|
|
- if(flipper_format_get_value_count(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) &&
|
|
|
|
|
- crypto_size > 0) {
|
|
|
|
|
- plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size);
|
|
|
|
|
- furi_check(plugin_state->crypto_verify_data != NULL);
|
|
|
|
|
- plugin_state->crypto_verify_data_length = crypto_size;
|
|
|
|
|
- if(!flipper_format_read_hex(
|
|
|
|
|
- fff_data_file,
|
|
|
|
|
- TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
|
|
|
|
- plugin_state->crypto_verify_data,
|
|
|
|
|
- crypto_size)) {
|
|
|
|
|
- FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
|
|
|
|
|
- free(plugin_state->crypto_verify_data);
|
|
|
|
|
|
|
+ uint32_t crypto_size;
|
|
|
|
|
+ if(flipper_format_get_value_count(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, &crypto_size) &&
|
|
|
|
|
+ crypto_size > 0) {
|
|
|
|
|
+ plugin_state->crypto_verify_data = malloc(sizeof(uint8_t) * crypto_size);
|
|
|
|
|
+ furi_check(plugin_state->crypto_verify_data != NULL);
|
|
|
|
|
+ plugin_state->crypto_verify_data_length = crypto_size;
|
|
|
|
|
+ if(!flipper_format_read_hex(
|
|
|
|
|
+ fff_data_file,
|
|
|
|
|
+ TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
|
|
|
|
+ plugin_state->crypto_verify_data,
|
|
|
|
|
+ crypto_size)) {
|
|
|
|
|
+ FURI_LOG_D(LOGGING_TAG, "Missing crypto verify token");
|
|
|
|
|
+ free(plugin_state->crypto_verify_data);
|
|
|
|
|
+ plugin_state->crypto_verify_data = NULL;
|
|
|
|
|
+ plugin_state->crypto_verify_data_length = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
plugin_state->crypto_verify_data = NULL;
|
|
plugin_state->crypto_verify_data = NULL;
|
|
|
plugin_state->crypto_verify_data_length = 0;
|
|
plugin_state->crypto_verify_data_length = 0;
|
|
|
}
|
|
}
|
|
|
- } else {
|
|
|
|
|
- plugin_state->crypto_verify_data = NULL;
|
|
|
|
|
- plugin_state->crypto_verify_data_length = 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- flipper_format_rewind(fff_data_file);
|
|
|
|
|
|
|
+ if(!flipper_format_rewind(fff_data_file)) {
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(!flipper_format_read_float(
|
|
|
|
|
- fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
|
|
|
|
- plugin_state->timezone_offset = 0;
|
|
|
|
|
- FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if(!flipper_format_read_float(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, &plugin_state->timezone_offset, 1)) {
|
|
|
|
|
+ plugin_state->timezone_offset = 0;
|
|
|
|
|
+ FURI_LOG_D(LOGGING_TAG, "Missing timezone offset information, defaulting to 0");
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- flipper_format_rewind(fff_data_file);
|
|
|
|
|
|
|
+ if(!flipper_format_rewind(fff_data_file)) {
|
|
|
|
|
+ result = TotpConfigFileOpenError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if(!flipper_format_read_bool(
|
|
|
|
|
- fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
|
|
|
|
- plugin_state->pin_set = true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if(!flipper_format_read_bool(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
|
|
|
|
+ plugin_state->pin_set = true;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- flipper_format_rewind(fff_data_file);
|
|
|
|
|
|
|
+ flipper_format_rewind(fff_data_file);
|
|
|
|
|
|
|
|
- uint32_t tmp_uint32;
|
|
|
|
|
- if(!flipper_format_read_uint32(
|
|
|
|
|
- fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
|
|
|
|
- tmp_uint32 = NotificationMethodSound | NotificationMethodVibro;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ uint32_t tmp_uint32;
|
|
|
|
|
+ if(!flipper_format_read_uint32(
|
|
|
|
|
+ fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1)) {
|
|
|
|
|
+ tmp_uint32 = NotificationMethodSound | NotificationMethodVibro;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- plugin_state->notification_method = tmp_uint32;
|
|
|
|
|
|
|
+ plugin_state->notification_method = tmp_uint32;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
|
|
|
furi_string_free(temp_str);
|
|
furi_string_free(temp_str);
|
|
|
totp_close_config_file(fff_data_file);
|
|
totp_close_config_file(fff_data_file);
|
|
|
totp_close_storage();
|
|
totp_close_storage();
|
|
|
|
|
+ return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) {
|
|
TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) {
|
|
|
Storage* storage = totp_open_storage();
|
|
Storage* storage = totp_open_storage();
|
|
|
- FlipperFormat* fff_data_file = totp_open_config_file(storage);
|
|
|
|
|
|
|
+ FlipperFormat* fff_data_file;
|
|
|
|
|
+ if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ totp_close_storage();
|
|
|
|
|
+ return TokenLoadingResultError;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
FuriString* temp_str = furi_string_alloc();
|
|
FuriString* temp_str = furi_string_alloc();
|
|
|
uint32_t temp_data32;
|
|
uint32_t temp_data32;
|
|
|
|
|
|
|
|
if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
|
|
if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
|
|
|
FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
|
|
FURI_LOG_E(LOGGING_TAG, "Missing or incorrect header");
|
|
|
|
|
+ totp_close_storage();
|
|
|
furi_string_free(temp_str);
|
|
furi_string_free(temp_str);
|
|
|
return TokenLoadingResultError;
|
|
return TokenLoadingResultError;
|
|
|
}
|
|
}
|
|
@@ -478,8 +692,42 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state)
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void totp_close_config_file(FlipperFormat* file) {
|
|
|
|
|
- if(file == NULL) return;
|
|
|
|
|
- flipper_format_file_close(file);
|
|
|
|
|
- flipper_format_free(file);
|
|
|
|
|
-}
|
|
|
|
|
|
|
+TotpConfigFileUpdateResult
|
|
|
|
|
+ totp_config_file_update_crypto_signatures(const PluginState* plugin_state) {
|
|
|
|
|
+ Storage* storage = totp_open_storage();
|
|
|
|
|
+ FlipperFormat* config_file;
|
|
|
|
|
+ TotpConfigFileUpdateResult update_result;
|
|
|
|
|
+ if(totp_open_config_file(storage, &config_file) == TotpConfigFileOpenSuccess) {
|
|
|
|
|
+ do {
|
|
|
|
|
+ if(!flipper_format_insert_or_update_hex(
|
|
|
|
|
+ config_file, TOTP_CONFIG_KEY_BASE_IV, plugin_state->base_iv, TOTP_IV_SIZE)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_insert_or_update_hex(
|
|
|
|
|
+ config_file,
|
|
|
|
|
+ TOTP_CONFIG_KEY_CRYPTO_VERIFY,
|
|
|
|
|
+ plugin_state->crypto_verify_data,
|
|
|
|
|
+ plugin_state->crypto_verify_data_length)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!flipper_format_insert_or_update_bool(
|
|
|
|
|
+ config_file, TOTP_CONFIG_KEY_PINSET, &plugin_state->pin_set, 1)) {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ update_result = TotpConfigFileUpdateSuccess;
|
|
|
|
|
+ } while(false);
|
|
|
|
|
+
|
|
|
|
|
+ totp_close_config_file(config_file);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ update_result = TotpConfigFileUpdateError;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ totp_close_storage();
|
|
|
|
|
+ return update_result;
|
|
|
|
|
+}
|