mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 23:28:36 -07:00
@@ -121,6 +121,19 @@ void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cl
|
|||||||
memset(&new_pin[0], 0, TOTP_IV_SIZE);
|
memset(&new_pin[0], 0, TOTP_IV_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* backup_path = totp_config_file_backup();
|
||||||
|
if(backup_path != NULL) {
|
||||||
|
TOTP_CLI_PRINTF_WARNING("Backup conf file %s has been created\r\n", backup_path);
|
||||||
|
TOTP_CLI_PRINTF_WARNING(
|
||||||
|
"Once you make sure everything is fine and works as expected, please delete this backup file\r\n");
|
||||||
|
free(backup_path);
|
||||||
|
} else {
|
||||||
|
memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE);
|
||||||
|
TOTP_CLI_PRINTF_ERROR(
|
||||||
|
"An error has occurred during taking backup of config file\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(plugin_state->current_scene == TotpSceneGenerateToken) {
|
if(plugin_state->current_scene == TotpSceneGenerateToken) {
|
||||||
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
|
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
|
||||||
load_generate_token_scene = true;
|
load_generate_token_scene = true;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "reset.h"
|
#include "reset.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <furi/furi.h>
|
#include <furi/core/string.h>
|
||||||
#include "../../cli_helpers.h"
|
#include "../../cli_helpers.h"
|
||||||
#include "../../../services/config/config.h"
|
#include "../../../services/config/config.h"
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ static const uint8_t dtable[] = {0x3e, 0x80, 0x80, 0x80, 0x3f, 0x34, 0x35, 0x36,
|
|||||||
0x80, 0x80, 0x80, 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
0x80, 0x80, 0x80, 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
|
||||||
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33};
|
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33};
|
||||||
// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
static uint8_t get_dtable_value(uint8_t index) {
|
static uint8_t get_dtable_value(uint8_t index) {
|
||||||
return (index < 43 || index > 122) ? 0x80 : dtable[index - 43];
|
return (index < 43 || index > 122) ? 0x80 : dtable[index - 43];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* base64_decode(const uint8_t* src, size_t len, size_t* out_len, size_t* out_size) {
|
uint8_t* base64_decode(const uint8_t* src, size_t len, size_t* out_len, size_t* out_size) {
|
||||||
uint8_t *out;
|
uint8_t* out;
|
||||||
uint8_t *pos;
|
uint8_t* pos;
|
||||||
uint8_t in[4];
|
uint8_t in[4];
|
||||||
uint8_t block[4];
|
uint8_t block[4];
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
#pragma weak strnlen
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
size_t strnlen(const char* s, size_t maxlen);
|
size_t strnlen(const char* s, size_t maxlen);
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#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_BASE_PATH CONFIG_FILE_PATH ".backup"
|
||||||
#define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp"
|
#define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp"
|
||||||
#define CONFIG_FILE_ORIG_PATH CONFIG_FILE_PATH ".orig"
|
#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"
|
||||||
@@ -39,6 +39,34 @@ static void totp_close_config_file(FlipperFormat* file) {
|
|||||||
flipper_format_free(file);
|
flipper_format_free(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tries to take a config file backup
|
||||||
|
* @param storage storage record
|
||||||
|
* @return backup path if backup successfully taken; \c NULL otherwise
|
||||||
|
*/
|
||||||
|
static char* totp_config_file_backup_i(Storage* storage) {
|
||||||
|
uint8_t backup_path_size = sizeof(CONFIG_FILE_BACKUP_BASE_PATH) + 5;
|
||||||
|
char* backup_path = malloc(backup_path_size);
|
||||||
|
furi_check(backup_path != NULL);
|
||||||
|
memcpy(backup_path, CONFIG_FILE_BACKUP_BASE_PATH, sizeof(CONFIG_FILE_BACKUP_BASE_PATH));
|
||||||
|
uint16_t i = 1;
|
||||||
|
bool backup_file_exists;
|
||||||
|
while((backup_file_exists = storage_common_exists(storage, backup_path)) && i <= 9999) {
|
||||||
|
snprintf(backup_path, backup_path_size, CONFIG_FILE_BACKUP_BASE_PATH ".%" PRIu16, i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(backup_file_exists ||
|
||||||
|
storage_common_copy(storage, CONFIG_FILE_PATH, backup_path) != FSE_OK) {
|
||||||
|
FURI_LOG_E(LOGGING_TAG, "Unable to take a backup");
|
||||||
|
free(backup_path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", backup_path);
|
||||||
|
return backup_path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Opens or creates TOTP application standard config file
|
* @brief Opens or creates TOTP application standard config file
|
||||||
* @param storage storage record to use
|
* @param storage storage record to use
|
||||||
@@ -250,6 +278,13 @@ static TotpConfigFileUpdateResult
|
|||||||
return update_result;
|
return update_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* totp_config_file_backup() {
|
||||||
|
Storage* storage = totp_open_storage();
|
||||||
|
char* result = totp_config_file_backup_i(storage);
|
||||||
|
totp_close_storage();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
TotpConfigFileUpdateResult 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;
|
FlipperFormat* file;
|
||||||
@@ -513,20 +548,16 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st
|
|||||||
CONFIG_FILE_ACTUAL_VERSION);
|
CONFIG_FILE_ACTUAL_VERSION);
|
||||||
totp_close_config_file(fff_data_file);
|
totp_close_config_file(fff_data_file);
|
||||||
|
|
||||||
if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) {
|
char* backup_path = totp_config_file_backup_i(storage);
|
||||||
storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) {
|
if(backup_path != NULL) {
|
||||||
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) {
|
if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) {
|
||||||
result = TotpConfigFileOpenError;
|
result = TotpConfigFileOpenError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
|
FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage);
|
||||||
if(!flipper_format_file_open_existing(
|
if(!flipper_format_file_open_existing(fff_backup_data_file, backup_path)) {
|
||||||
fff_backup_data_file, CONFIG_FILE_BACKUP_PATH)) {
|
|
||||||
flipper_format_file_close(fff_backup_data_file);
|
flipper_format_file_close(fff_backup_data_file);
|
||||||
flipper_format_free(fff_backup_data_file);
|
flipper_format_free(fff_backup_data_file);
|
||||||
result = TotpConfigFileOpenError;
|
result = TotpConfigFileOpenError;
|
||||||
@@ -551,12 +582,12 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st
|
|||||||
flipper_format_file_close(fff_backup_data_file);
|
flipper_format_file_close(fff_backup_data_file);
|
||||||
flipper_format_free(fff_backup_data_file);
|
flipper_format_free(fff_backup_data_file);
|
||||||
flipper_format_rewind(fff_data_file);
|
flipper_format_rewind(fff_data_file);
|
||||||
|
free(backup_path);
|
||||||
} else {
|
} else {
|
||||||
FURI_LOG_E(
|
FURI_LOG_E(
|
||||||
LOGGING_TAG,
|
LOGGING_TAG,
|
||||||
"An error occurred during taking backup of %s into %s before migration",
|
"An error occurred during taking backup of %s before migration",
|
||||||
CONFIG_FILE_PATH,
|
CONFIG_FILE_PATH);
|
||||||
CONFIG_FILE_BACKUP_PATH);
|
|
||||||
result = TotpConfigFileOpenError;
|
result = TotpConfigFileOpenError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <flipper_format/flipper_format.h>
|
#include <flipper_format/flipper_format.h>
|
||||||
#include <furi.h>
|
|
||||||
#include "../../types/plugin_state.h"
|
#include "../../types/plugin_state.h"
|
||||||
#include "../../types/token_info.h"
|
#include "../../types/token_info.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
@@ -60,6 +59,12 @@ enum TotpConfigFileUpdateResults {
|
|||||||
TotpConfigFileUpdateError
|
TotpConfigFileUpdateError
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tries to take a config file backup
|
||||||
|
* @return backup path if backup successfully taken; \c NULL otherwise
|
||||||
|
*/
|
||||||
|
char* totp_config_file_backup();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Saves all the settings and tokens to an application config file
|
* @brief Saves all the settings and tokens to an application config file
|
||||||
* @param plugin_state application state
|
* @param plugin_state application state
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
|
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
|
||||||
#define CONFIG_FILE_ACTUAL_VERSION 4
|
#define CONFIG_FILE_ACTUAL_VERSION (4)
|
||||||
|
|
||||||
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
|
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
|
||||||
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
|
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include <furi.h>
|
#include <furi_hal_crypto.h>
|
||||||
#include <furi_hal.h>
|
#include <furi_hal_random.h>
|
||||||
|
#include <furi_hal_version.h>
|
||||||
#include "../config/config.h"
|
#include "../config/config.h"
|
||||||
#include "../../types/common.h"
|
#include "../../types/common.h"
|
||||||
#include "memset_s.h"
|
#include "memset_s.h"
|
||||||
|
|
||||||
#define CRYPTO_KEY_SLOT 2
|
#define CRYPTO_KEY_SLOT (2)
|
||||||
#define CRYPTO_VERIFY_KEY "FFF_Crypto_pass"
|
#define CRYPTO_VERIFY_KEY "FFF_Crypto_pass"
|
||||||
#define CRYPTO_VERIFY_KEY_LENGTH 16
|
#define CRYPTO_VERIFY_KEY_LENGTH (16)
|
||||||
#define CRYPTO_ALIGNMENT_FACTOR 16
|
#define CRYPTO_ALIGNMENT_FACTOR (16)
|
||||||
|
|
||||||
uint8_t* totp_crypto_encrypt(
|
uint8_t* totp_crypto_encrypt(
|
||||||
const uint8_t* plain_data,
|
const uint8_t* plain_data,
|
||||||
|
|||||||
@@ -9,11 +9,7 @@
|
|||||||
#define _GLHMAC_CONCAT_(prefix, suffix) prefix##suffix
|
#define _GLHMAC_CONCAT_(prefix, suffix) prefix##suffix
|
||||||
#define _GLHMAC_CONCAT(prefix, suffix) _GLHMAC_CONCAT_(prefix, suffix)
|
#define _GLHMAC_CONCAT(prefix, suffix) _GLHMAC_CONCAT_(prefix, suffix)
|
||||||
|
|
||||||
#if GL_HMAC_NAME == 5
|
|
||||||
#define HMAC_ALG md5
|
|
||||||
#else
|
|
||||||
#define HMAC_ALG _GLHMAC_CONCAT(sha, GL_HMAC_NAME)
|
#define HMAC_ALG _GLHMAC_CONCAT(sha, GL_HMAC_NAME)
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GL_HMAC_CTX _GLHMAC_CONCAT(HMAC_ALG, _ctx)
|
#define GL_HMAC_CTX _GLHMAC_CONCAT(HMAC_ALG, _ctx)
|
||||||
#define GL_HMAC_FN _GLHMAC_CONCAT(hmac_, HMAC_ALG)
|
#define GL_HMAC_FN _GLHMAC_CONCAT(hmac_, HMAC_ALG)
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
#include "totp.h"
|
#include "totp.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <timezone_utils.h>
|
||||||
#include "../hmac/hmac_sha1.h"
|
#include "../hmac/hmac_sha1.h"
|
||||||
#include "../hmac/hmac_sha256.h"
|
#include "../hmac/hmac_sha256.h"
|
||||||
#include "../hmac/hmac_sha512.h"
|
#include "../hmac/hmac_sha512.h"
|
||||||
#include "../hmac/byteswap.h"
|
#include "../hmac/byteswap.h"
|
||||||
#include "../../lib/timezone_utils/timezone_utils.h"
|
|
||||||
|
|
||||||
#define HMAC_MAX_RESULT_SIZE HMAC_SHA512_RESULT_SIZE
|
#define HMAC_MAX_RESULT_SIZE HMAC_SHA512_RESULT_SIZE
|
||||||
|
|
||||||
|
|||||||
13
applications/external/totp/totp_app.c
vendored
13
applications/external/totp/totp_app.c
vendored
@@ -1,10 +1,7 @@
|
|||||||
#include <furi.h>
|
|
||||||
#include <furi_hal.h>
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <input/input.h>
|
#include <input/input.h>
|
||||||
#include <dialogs/dialogs.h>
|
#include <dialogs/dialogs.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <flipper_format/flipper_format.h>
|
|
||||||
#include <notification/notification.h>
|
#include <notification/notification.h>
|
||||||
#include <notification/notification_messages.h>
|
#include <notification/notification_messages.h>
|
||||||
#include <dolphin/dolphin.h>
|
#include <dolphin/dolphin.h>
|
||||||
@@ -21,7 +18,7 @@
|
|||||||
#include "services/crypto/crypto.h"
|
#include "services/crypto/crypto.h"
|
||||||
#include "cli/cli.h"
|
#include "cli/cli.h"
|
||||||
|
|
||||||
#define IDLE_TIMEOUT 60000
|
#define IDLE_TIMEOUT (60000)
|
||||||
|
|
||||||
static void render_callback(Canvas* const canvas, void* ctx) {
|
static void render_callback(Canvas* const canvas, void* ctx) {
|
||||||
furi_assert(ctx);
|
furi_assert(ctx);
|
||||||
@@ -97,6 +94,7 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
|||||||
plugin_state->gui = furi_record_open(RECORD_GUI);
|
plugin_state->gui = furi_record_open(RECORD_GUI);
|
||||||
plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
|
plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION);
|
||||||
plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
|
plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS);
|
||||||
|
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
|
||||||
|
|
||||||
if(totp_config_file_load_base(plugin_state) != TotpConfigFileOpenSuccess) {
|
if(totp_config_file_load_base(plugin_state) != TotpConfigFileOpenSuccess) {
|
||||||
totp_dialogs_config_loading_error(plugin_state);
|
totp_dialogs_config_loading_error(plugin_state);
|
||||||
@@ -104,10 +102,6 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
if(plugin_state->mutex == NULL) {
|
|
||||||
FURI_LOG_E(LOGGING_TAG, "Cannot create mutex\r\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||||
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
if(plugin_state->automation_method & AutomationMethodBadBt) {
|
||||||
@@ -162,7 +156,7 @@ int32_t totp_app() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TotpCliContext* cli_context = totp_cli_register_command_handler(plugin_state, event_queue);
|
TotpCliContext* cli_context = totp_cli_register_command_handler(plugin_state, event_queue);
|
||||||
totp_scene_director_init_scenes(plugin_state);
|
|
||||||
if(!totp_activate_initial_scene(plugin_state)) {
|
if(!totp_activate_initial_scene(plugin_state)) {
|
||||||
FURI_LOG_E(LOGGING_TAG, "An error ocurred during activating initial scene\r\n");
|
FURI_LOG_E(LOGGING_TAG, "An error ocurred during activating initial scene\r\n");
|
||||||
totp_plugin_state_free(plugin_state);
|
totp_plugin_state_free(plugin_state);
|
||||||
@@ -210,7 +204,6 @@ int32_t totp_app() {
|
|||||||
|
|
||||||
totp_cli_unregister_command_handler(cli_context);
|
totp_cli_unregister_command_handler(cli_context);
|
||||||
totp_scene_director_deactivate_active_scene(plugin_state);
|
totp_scene_director_deactivate_active_scene(plugin_state);
|
||||||
totp_scene_director_dispose(plugin_state);
|
|
||||||
|
|
||||||
view_port_enabled_set(view_port, false);
|
view_port_enabled_set(view_port, false);
|
||||||
gui_remove_view_port(plugin_state->gui, view_port);
|
gui_remove_view_port(plugin_state->gui, view_port);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "../workers/bt_type_code/bt_type_code.h"
|
#include "../workers/bt_type_code/bt_type_code.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TOTP_IV_SIZE 16
|
#define TOTP_IV_SIZE (16)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Application state structure
|
* @brief Application state structure
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#include "token_info.h"
|
#include "token_info.h"
|
||||||
#include <furi_hal.h>
|
|
||||||
#include <base32.h>
|
#include <base32.h>
|
||||||
#include <base64.h>
|
#include <base64.h>
|
||||||
#include <memset_s.h>
|
#include <memset_s.h>
|
||||||
#include <strnlen.h>
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "../services/crypto/crypto.h"
|
#include "../services/crypto/crypto.h"
|
||||||
|
|
||||||
|
|||||||
19
applications/external/totp/types/token_info.h
vendored
19
applications/external/totp/types/token_info.h
vendored
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <furi/furi.h>
|
#include <furi/core/string.h>
|
||||||
|
|
||||||
#define TOTP_TOKEN_DURATION_DEFAULT 30
|
#define TOTP_TOKEN_DURATION_DEFAULT (30)
|
||||||
|
|
||||||
#define TOTP_TOKEN_ALGO_SHA1_NAME "sha1"
|
#define TOTP_TOKEN_ALGO_SHA1_NAME "sha1"
|
||||||
#define TOTP_TOKEN_ALGO_STEAM_NAME "steam"
|
#define TOTP_TOKEN_ALGO_STEAM_NAME "steam"
|
||||||
#define TOTP_TOKEN_ALGO_SHA256_NAME "sha256"
|
#define TOTP_TOKEN_ALGO_SHA256_NAME "sha256"
|
||||||
#define TOTP_TOKEN_ALGO_SHA512_NAME "sha512"
|
#define TOTP_TOKEN_ALGO_SHA512_NAME "sha512"
|
||||||
#define TOTP_TOKEN_MAX_LENGTH 255
|
#define TOTP_TOKEN_MAX_LENGTH (255)
|
||||||
|
|
||||||
#define PLAIN_TOKEN_ENCODING_BASE32_NAME "base32"
|
#define PLAIN_TOKEN_ENCODING_BASE32_NAME "base32"
|
||||||
#define PLAIN_TOKEN_ENCODING_BASE64_NAME "base64"
|
#define PLAIN_TOKEN_ENCODING_BASE64_NAME "base64"
|
||||||
@@ -95,12 +95,23 @@ enum TokenAutomationFeatures {
|
|||||||
TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER = 0b100
|
TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER = 0b100
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Plain token secret encodings.
|
||||||
|
*/
|
||||||
enum PlainTokenSecretEncodings {
|
enum PlainTokenSecretEncodings {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base32 encoding
|
||||||
|
*/
|
||||||
PLAIN_TOKEN_ENCODING_BASE32 = 0,
|
PLAIN_TOKEN_ENCODING_BASE32 = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base64 encoding
|
||||||
|
*/
|
||||||
PLAIN_TOKEN_ENCODING_BASE64 = 1
|
PLAIN_TOKEN_ENCODING_BASE64 = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TOTP_TOKEN_DIGITS_MAX_COUNT 8
|
#define TOTP_TOKEN_DIGITS_MAX_COUNT (8)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief TOTP token information
|
* @brief TOTP token information
|
||||||
|
|||||||
4
applications/external/totp/ui/constants.h
vendored
4
applications/external/totp/ui/constants.h
vendored
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define SCREEN_WIDTH 128
|
#define SCREEN_WIDTH (128)
|
||||||
#define SCREEN_HEIGHT 64
|
#define SCREEN_HEIGHT (64)
|
||||||
#define SCREEN_WIDTH_CENTER (SCREEN_WIDTH >> 1)
|
#define SCREEN_WIDTH_CENTER (SCREEN_WIDTH >> 1)
|
||||||
#define SCREEN_HEIGHT_CENTER (SCREEN_HEIGHT >> 1)
|
#define SCREEN_HEIGHT_CENTER (SCREEN_HEIGHT >> 1)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "mode_nine.h"
|
#include "mode_nine.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/* GENERATED BY https://github.com/pavius/the-dot-factory */
|
/* GENERATED BY https://github.com/pavius/the-dot-factory */
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
/* GENERATED BY https://github.com/pavius/the-dot-factory */
|
/* GENERATED BY https://github.com/pavius/the-dot-factory */
|
||||||
|
|
||||||
#include "../font_info.h"
|
#include "../font_info.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* Font data for ModeNine 15pt */
|
/* Font data for ModeNine 15pt */
|
||||||
extern const FONT_INFO modeNine_15ptFontInfo;
|
extern const FONT_INFO modeNine_15ptFontInfo;
|
||||||
|
|||||||
16
applications/external/totp/ui/scene_director.c
vendored
16
applications/external/totp/ui/scene_director.c
vendored
@@ -62,14 +62,6 @@ void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_director_init_scenes(PluginState* const plugin_state) {
|
|
||||||
totp_scene_authenticate_init(plugin_state);
|
|
||||||
totp_scene_generate_token_init(plugin_state);
|
|
||||||
totp_scene_add_new_token_init(plugin_state);
|
|
||||||
totp_scene_token_menu_init(plugin_state);
|
|
||||||
totp_scene_app_settings_init(plugin_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state) {
|
void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state) {
|
||||||
switch(plugin_state->current_scene) {
|
switch(plugin_state->current_scene) {
|
||||||
case TotpSceneGenerateToken:
|
case TotpSceneGenerateToken:
|
||||||
@@ -94,14 +86,6 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_director_dispose(const PluginState* const plugin_state) {
|
|
||||||
totp_scene_generate_token_free(plugin_state);
|
|
||||||
totp_scene_authenticate_free(plugin_state);
|
|
||||||
totp_scene_add_new_token_free(plugin_state);
|
|
||||||
totp_scene_token_menu_free(plugin_state);
|
|
||||||
totp_scene_app_settings_free(plugin_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* const plugin_state) {
|
bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* const plugin_state) {
|
||||||
bool processing = true;
|
bool processing = true;
|
||||||
switch(plugin_state->current_scene) {
|
switch(plugin_state->current_scene) {
|
||||||
|
|||||||
12
applications/external/totp/ui/scene_director.h
vendored
12
applications/external/totp/ui/scene_director.h
vendored
@@ -22,12 +22,6 @@ void totp_scene_director_activate_scene(
|
|||||||
*/
|
*/
|
||||||
void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state);
|
void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes all the available scenes
|
|
||||||
* @param plugin_state application state
|
|
||||||
*/
|
|
||||||
void totp_scene_director_init_scenes(PluginState* const plugin_state);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Renders current scene
|
* @brief Renders current scene
|
||||||
* @param canvas canvas to render at
|
* @param canvas canvas to render at
|
||||||
@@ -35,12 +29,6 @@ void totp_scene_director_init_scenes(PluginState* const plugin_state);
|
|||||||
*/
|
*/
|
||||||
void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state);
|
void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Disposes all the available scenes
|
|
||||||
* @param plugin_state application state
|
|
||||||
*/
|
|
||||||
void totp_scene_director_dispose(const PluginState* const plugin_state);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles application event for the current scene
|
* @brief Handles application event for the current scene
|
||||||
* @param event event to be handled
|
* @param event event to be handled
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "totp_input_text.h"
|
#include "totp_input_text.h"
|
||||||
#include <gui/view_i.h>
|
#include <gui/view_i.h>
|
||||||
#include "../../../lib/polyfills/strnlen.h"
|
|
||||||
|
|
||||||
void view_draw(View* view, Canvas* canvas) {
|
void view_draw(View* view, Canvas* canvas) {
|
||||||
furi_assert(view);
|
furi_assert(view);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "../../../types/plugin_state.h"
|
#include "../../../types/plugin_state.h"
|
||||||
#include "../../../types/plugin_event.h"
|
#include "../../../types/plugin_event.h"
|
||||||
|
|
||||||
|
#define INPUT_BUFFER_SIZE (255)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* user_input;
|
char* user_input;
|
||||||
size_t user_input_length;
|
size_t user_input_length;
|
||||||
@@ -20,8 +22,6 @@ typedef struct {
|
|||||||
void* callback_data;
|
void* callback_data;
|
||||||
} InputTextSceneContext;
|
} InputTextSceneContext;
|
||||||
|
|
||||||
#define INPUT_BUFFER_SIZE 255
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TextInput* text_input;
|
TextInput* text_input;
|
||||||
View* text_input_view;
|
View* text_input_view;
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ typedef struct {
|
|||||||
FuriString* duration_text;
|
FuriString* duration_text;
|
||||||
} SceneState;
|
} SceneState;
|
||||||
|
|
||||||
void totp_scene_add_new_token_init(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) {
|
static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) {
|
||||||
SceneState* scene_state = result->callback_data;
|
SceneState* scene_state = result->callback_data;
|
||||||
free(scene_state->token_name);
|
free(scene_state->token_name);
|
||||||
@@ -354,7 +350,3 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
|
|||||||
free(plugin_state->current_scene_state);
|
free(plugin_state->current_scene_state);
|
||||||
plugin_state->current_scene_state = NULL;
|
plugin_state->current_scene_state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_add_new_token_free(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <furi.h>
|
|
||||||
#include <furi_hal.h>
|
|
||||||
#include "../../../types/plugin_state.h"
|
#include "../../../types/plugin_state.h"
|
||||||
#include "../../../types/plugin_event.h"
|
#include "../../../types/plugin_event.h"
|
||||||
|
|
||||||
@@ -10,11 +8,9 @@ typedef struct {
|
|||||||
uint16_t current_token_index;
|
uint16_t current_token_index;
|
||||||
} TokenAddEditSceneContext;
|
} TokenAddEditSceneContext;
|
||||||
|
|
||||||
void totp_scene_add_new_token_init(const PluginState* plugin_state);
|
|
||||||
void totp_scene_add_new_token_activate(
|
void totp_scene_add_new_token_activate(
|
||||||
PluginState* plugin_state,
|
PluginState* plugin_state,
|
||||||
const TokenAddEditSceneContext* context);
|
const TokenAddEditSceneContext* context);
|
||||||
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state);
|
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state);
|
||||||
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state);
|
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state);
|
||||||
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);
|
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);
|
||||||
void totp_scene_add_new_token_free(const PluginState* plugin_state);
|
|
||||||
|
|||||||
@@ -44,10 +44,6 @@ typedef struct {
|
|||||||
Control selected_control;
|
Control selected_control;
|
||||||
} SceneState;
|
} SceneState;
|
||||||
|
|
||||||
void totp_scene_app_settings_init(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void totp_scene_app_settings_activate(
|
void totp_scene_app_settings_activate(
|
||||||
PluginState* plugin_state,
|
PluginState* plugin_state,
|
||||||
const AppSettingsSceneContext* context) {
|
const AppSettingsSceneContext* context) {
|
||||||
@@ -332,7 +328,3 @@ void totp_scene_app_settings_deactivate(PluginState* plugin_state) {
|
|||||||
free(plugin_state->current_scene_state);
|
free(plugin_state->current_scene_state);
|
||||||
plugin_state->current_scene_state = NULL;
|
plugin_state->current_scene_state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_app_settings_free(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,6 @@ typedef struct {
|
|||||||
uint16_t current_token_index;
|
uint16_t current_token_index;
|
||||||
} AppSettingsSceneContext;
|
} AppSettingsSceneContext;
|
||||||
|
|
||||||
void totp_scene_app_settings_init(const PluginState* plugin_state);
|
|
||||||
void totp_scene_app_settings_activate(
|
void totp_scene_app_settings_activate(
|
||||||
PluginState* plugin_state,
|
PluginState* plugin_state,
|
||||||
const AppSettingsSceneContext* context);
|
const AppSettingsSceneContext* context);
|
||||||
@@ -17,4 +16,3 @@ bool totp_scene_app_settings_handle_event(
|
|||||||
const PluginEvent* const event,
|
const PluginEvent* const event,
|
||||||
PluginState* plugin_state);
|
PluginState* plugin_state);
|
||||||
void totp_scene_app_settings_deactivate(PluginState* plugin_state);
|
void totp_scene_app_settings_deactivate(PluginState* plugin_state);
|
||||||
void totp_scene_app_settings_free(const PluginState* plugin_state);
|
|
||||||
@@ -18,10 +18,6 @@ typedef struct {
|
|||||||
uint8_t code_length;
|
uint8_t code_length;
|
||||||
} SceneState;
|
} SceneState;
|
||||||
|
|
||||||
void totp_scene_authenticate_init(PluginState* plugin_state) {
|
|
||||||
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void totp_scene_authenticate_activate(PluginState* plugin_state) {
|
void totp_scene_authenticate_activate(PluginState* plugin_state) {
|
||||||
SceneState* scene_state = malloc(sizeof(SceneState));
|
SceneState* scene_state = malloc(sizeof(SceneState));
|
||||||
furi_check(scene_state != NULL);
|
furi_check(scene_state != NULL);
|
||||||
@@ -162,7 +158,3 @@ void totp_scene_authenticate_deactivate(PluginState* plugin_state) {
|
|||||||
free(plugin_state->current_scene_state);
|
free(plugin_state->current_scene_state);
|
||||||
plugin_state->current_scene_state = NULL;
|
plugin_state->current_scene_state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_authenticate_free(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,11 +4,9 @@
|
|||||||
#include "../../../types/plugin_state.h"
|
#include "../../../types/plugin_state.h"
|
||||||
#include "../../../types/plugin_event.h"
|
#include "../../../types/plugin_event.h"
|
||||||
|
|
||||||
void totp_scene_authenticate_init(PluginState* plugin_state);
|
|
||||||
void totp_scene_authenticate_activate(PluginState* plugin_state);
|
void totp_scene_authenticate_activate(PluginState* plugin_state);
|
||||||
void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state);
|
void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state);
|
||||||
bool totp_scene_authenticate_handle_event(
|
bool totp_scene_authenticate_handle_event(
|
||||||
const PluginEvent* const event,
|
const PluginEvent* const event,
|
||||||
PluginState* plugin_state);
|
PluginState* plugin_state);
|
||||||
void totp_scene_authenticate_deactivate(PluginState* plugin_state);
|
void totp_scene_authenticate_deactivate(PluginState* plugin_state);
|
||||||
void totp_scene_authenticate_free(const PluginState* plugin_state);
|
|
||||||
|
|||||||
@@ -2,39 +2,44 @@
|
|||||||
#include <notification/notification.h>
|
#include <notification/notification.h>
|
||||||
#include <notification/notification_messages.h>
|
#include <notification/notification_messages.h>
|
||||||
#include <totp_icons.h>
|
#include <totp_icons.h>
|
||||||
|
#include <roll_value.h>
|
||||||
#include "totp_scene_generate_token.h"
|
#include "totp_scene_generate_token.h"
|
||||||
#include "../../../types/token_info.h"
|
#include "../../../types/token_info.h"
|
||||||
#include "../../../types/common.h"
|
#include "../../../types/common.h"
|
||||||
#include "../../constants.h"
|
#include "../../constants.h"
|
||||||
#include "../../../services/totp/totp.h"
|
|
||||||
#include "../../../services/config/config.h"
|
#include "../../../services/config/config.h"
|
||||||
#include "../../../services/crypto/crypto.h"
|
|
||||||
#include "../../../services/convert/convert.h"
|
|
||||||
#include "../../../lib/polyfills/memset_s.h"
|
|
||||||
#include "../../../lib/roll_value/roll_value.h"
|
|
||||||
#include "../../scene_director.h"
|
#include "../../scene_director.h"
|
||||||
#include "../token_menu/totp_scene_token_menu.h"
|
#include "../token_menu/totp_scene_token_menu.h"
|
||||||
#include "../../../features_config.h"
|
#include "../../../features_config.h"
|
||||||
|
#include "../../../workers/generate_totp_code/generate_totp_code.h"
|
||||||
#include "../../../workers/usb_type_code/usb_type_code.h"
|
#include "../../../workers/usb_type_code/usb_type_code.h"
|
||||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||||
#endif
|
#endif
|
||||||
#include "../../fonts/mode-nine/mode_nine.h"
|
#include "../../fonts/mode-nine/mode_nine.h"
|
||||||
|
|
||||||
static const char* STEAM_ALGO_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY";
|
#define PROGRESS_BAR_MARGIN (3)
|
||||||
static const uint8_t PROGRESS_BAR_MARGIN = 3;
|
#define PROGRESS_BAR_HEIGHT (4)
|
||||||
static const uint8_t PROGRESS_BAR_HEIGHT = 4;
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t progress_bar_x;
|
||||||
|
uint8_t progress_bar_width;
|
||||||
|
uint8_t code_total_length;
|
||||||
|
uint8_t code_offset_x;
|
||||||
|
uint8_t code_offset_x_inc;
|
||||||
|
uint8_t code_offset_y;
|
||||||
|
} UiPrecalculatedDimensions;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t current_token_index;
|
uint16_t current_token_index;
|
||||||
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
|
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
|
||||||
bool need_token_update;
|
|
||||||
TokenInfo* current_token;
|
TokenInfo* current_token;
|
||||||
uint32_t last_token_gen_time;
|
|
||||||
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
|
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
|
||||||
NotificationMessage const** notification_sequence_new_token;
|
NotificationMessage const** notification_sequence_new_token;
|
||||||
NotificationMessage const** notification_sequence_badusb;
|
NotificationMessage const** notification_sequence_automation;
|
||||||
FuriMutex* last_code_update_sync;
|
FuriMutex* last_code_update_sync;
|
||||||
|
TotpGenerateCodeWorkerContext* generate_code_worker_context;
|
||||||
|
UiPrecalculatedDimensions ui_precalculated_dimensions;
|
||||||
} SceneState;
|
} SceneState;
|
||||||
|
|
||||||
static const NotificationSequence*
|
static const NotificationSequence*
|
||||||
@@ -80,7 +85,7 @@ static const NotificationSequence*
|
|||||||
|
|
||||||
static const NotificationSequence*
|
static const NotificationSequence*
|
||||||
get_notification_sequence_automation(const PluginState* plugin_state, SceneState* scene_state) {
|
get_notification_sequence_automation(const PluginState* plugin_state, SceneState* scene_state) {
|
||||||
if(scene_state->notification_sequence_badusb == NULL) {
|
if(scene_state->notification_sequence_automation == NULL) {
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint8_t length = 3;
|
uint8_t length = 3;
|
||||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||||
@@ -91,110 +96,100 @@ static const NotificationSequence*
|
|||||||
length += 6;
|
length += 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene_state->notification_sequence_badusb = malloc(sizeof(void*) * length);
|
scene_state->notification_sequence_automation = malloc(sizeof(void*) * length);
|
||||||
furi_check(scene_state->notification_sequence_badusb != NULL);
|
furi_check(scene_state->notification_sequence_automation != NULL);
|
||||||
|
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_blue_255;
|
scene_state->notification_sequence_automation[i++] = &message_blue_255;
|
||||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_vibro_on;
|
scene_state->notification_sequence_automation[i++] = &message_vibro_on;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_note_d5; //-V525
|
scene_state->notification_sequence_automation[i++] = &message_note_d5; //-V525
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_delay_50;
|
scene_state->notification_sequence_automation[i++] = &message_delay_50;
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_note_e4;
|
scene_state->notification_sequence_automation[i++] = &message_note_e4;
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_delay_50;
|
scene_state->notification_sequence_automation[i++] = &message_delay_50;
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_note_f3;
|
scene_state->notification_sequence_automation[i++] = &message_note_f3;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_delay_50;
|
scene_state->notification_sequence_automation[i++] = &message_delay_50;
|
||||||
|
|
||||||
if(plugin_state->notification_method & NotificationMethodVibro) {
|
if(plugin_state->notification_method & NotificationMethodVibro) {
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_vibro_off;
|
scene_state->notification_sequence_automation[i++] = &message_vibro_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(plugin_state->notification_method & NotificationMethodSound) {
|
if(plugin_state->notification_method & NotificationMethodSound) {
|
||||||
scene_state->notification_sequence_badusb[i++] = &message_sound_off;
|
scene_state->notification_sequence_automation[i++] = &message_sound_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene_state->notification_sequence_badusb[i++] = NULL;
|
scene_state->notification_sequence_automation[i++] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (NotificationSequence*)scene_state->notification_sequence_badusb;
|
return (NotificationSequence*)scene_state->notification_sequence_automation;
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
int_token_to_str(uint64_t i_token_code, char* str, TokenDigitsCount len, TokenHashAlgo algo) {
|
|
||||||
if(i_token_code == OTP_ERROR) {
|
|
||||||
memset(&str[0], '-', len);
|
|
||||||
} else {
|
|
||||||
if(algo == STEAM) {
|
|
||||||
for(uint8_t i = 0; i < len; i++) {
|
|
||||||
str[i] = STEAM_ALGO_ALPHABET[i_token_code % 26];
|
|
||||||
i_token_code = i_token_code / 26;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(int8_t i = len - 1; i >= 0; i--) {
|
|
||||||
str[i] = CONVERT_DIGIT_TO_CHAR(i_token_code % 10);
|
|
||||||
i_token_code = i_token_code / 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
str[len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
|
|
||||||
switch(algo) {
|
|
||||||
case SHA1:
|
|
||||||
case STEAM:
|
|
||||||
return TOTP_ALGO_SHA1;
|
|
||||||
case SHA256:
|
|
||||||
return TOTP_ALGO_SHA256;
|
|
||||||
case SHA512:
|
|
||||||
return TOTP_ALGO_SHA512;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_totp_params(PluginState* const plugin_state) {
|
static void update_totp_params(PluginState* const plugin_state) {
|
||||||
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||||
|
|
||||||
if(scene_state->current_token_index < plugin_state->tokens_count) {
|
if(scene_state->current_token_index < plugin_state->tokens_count) {
|
||||||
TokenInfo* tokenInfo =
|
scene_state->current_token =
|
||||||
list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data;
|
list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data;
|
||||||
|
totp_generate_code_worker_notify(
|
||||||
scene_state->need_token_update = true;
|
scene_state->generate_code_worker_context, TotpGenerateCodeWorkerEventForceUpdate);
|
||||||
scene_state->current_token = tokenInfo;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_totp_code(Canvas* const canvas, const SceneState* const scene_state) {
|
static void draw_totp_code(Canvas* const canvas, const SceneState* const scene_state) {
|
||||||
uint8_t code_length = scene_state->current_token->digits;
|
uint8_t code_length = scene_state->current_token->digits;
|
||||||
|
uint8_t offset_x = scene_state->ui_precalculated_dimensions.code_offset_x;
|
||||||
uint8_t char_width = modeNine_15ptFontInfo.charInfo[0].width;
|
uint8_t char_width = modeNine_15ptFontInfo.charInfo[0].width;
|
||||||
uint8_t total_length = code_length * (char_width + modeNine_15ptFontInfo.spacePixels);
|
uint8_t offset_x_inc = scene_state->ui_precalculated_dimensions.code_offset_x_inc;
|
||||||
uint8_t offset_x = (SCREEN_WIDTH - total_length) >> 1;
|
|
||||||
uint8_t offset_y = SCREEN_HEIGHT_CENTER - (modeNine_15ptFontInfo.height >> 1);
|
|
||||||
for(uint8_t i = 0; i < code_length; i++) {
|
for(uint8_t i = 0; i < code_length; i++) {
|
||||||
char ch = scene_state->last_code[i];
|
char ch = scene_state->last_code[i];
|
||||||
uint8_t char_index = ch - modeNine_15ptFontInfo.startChar;
|
if(ch >= modeNine_15ptFontInfo.startChar && ch <= modeNine_15ptFontInfo.endChar) {
|
||||||
canvas_draw_xbm(
|
uint8_t char_index = ch - modeNine_15ptFontInfo.startChar;
|
||||||
canvas,
|
canvas_draw_xbm(
|
||||||
offset_x,
|
canvas,
|
||||||
offset_y,
|
offset_x,
|
||||||
char_width,
|
scene_state->ui_precalculated_dimensions.code_offset_y,
|
||||||
modeNine_15ptFontInfo.height,
|
char_width,
|
||||||
&modeNine_15ptFontInfo.data[modeNine_15ptFontInfo.charInfo[char_index].offset]);
|
modeNine_15ptFontInfo.height,
|
||||||
|
&modeNine_15ptFontInfo.data[modeNine_15ptFontInfo.charInfo[char_index].offset]);
|
||||||
|
}
|
||||||
|
|
||||||
offset_x += char_width + modeNine_15ptFontInfo.spacePixels;
|
offset_x += offset_x_inc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_generate_token_init(const PluginState* plugin_state) {
|
static void on_new_token_code_generated(bool time_left, void* context) {
|
||||||
UNUSED(plugin_state);
|
const PluginState* plugin_state = context;
|
||||||
|
SceneState* scene_state = plugin_state->current_scene_state;
|
||||||
|
uint8_t char_width = modeNine_15ptFontInfo.charInfo[0].width;
|
||||||
|
scene_state->ui_precalculated_dimensions.code_total_length =
|
||||||
|
scene_state->current_token->digits * (char_width + modeNine_15ptFontInfo.spacePixels);
|
||||||
|
scene_state->ui_precalculated_dimensions.code_offset_x =
|
||||||
|
(SCREEN_WIDTH - scene_state->ui_precalculated_dimensions.code_total_length) >> 1;
|
||||||
|
scene_state->ui_precalculated_dimensions.code_offset_x_inc =
|
||||||
|
char_width + modeNine_15ptFontInfo.spacePixels;
|
||||||
|
scene_state->ui_precalculated_dimensions.code_offset_y =
|
||||||
|
SCREEN_HEIGHT_CENTER - (modeNine_15ptFontInfo.height >> 1);
|
||||||
|
|
||||||
|
if(time_left) {
|
||||||
|
notification_message(
|
||||||
|
plugin_state->notification_app,
|
||||||
|
get_notification_sequence_new_token(plugin_state, plugin_state->current_scene_state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_code_lifetime_updated_generated(float code_lifetime_percent, void* context) {
|
||||||
|
SceneState* scene_state = context;
|
||||||
|
scene_state->ui_precalculated_dimensions.progress_bar_width =
|
||||||
|
(uint8_t)((float)(SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1)) * code_lifetime_percent);
|
||||||
|
scene_state->ui_precalculated_dimensions.progress_bar_x =
|
||||||
|
((SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1) -
|
||||||
|
scene_state->ui_precalculated_dimensions.progress_bar_width) >>
|
||||||
|
1) +
|
||||||
|
PROGRESS_BAR_MARGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_generate_token_activate(
|
void totp_scene_generate_token_activate(
|
||||||
@@ -234,15 +229,14 @@ void totp_scene_generate_token_activate(
|
|||||||
} else {
|
} else {
|
||||||
scene_state->current_token_index = context->current_token_index;
|
scene_state->current_token_index = context->current_token_index;
|
||||||
}
|
}
|
||||||
scene_state->need_token_update = true;
|
|
||||||
plugin_state->current_scene_state = scene_state;
|
plugin_state->current_scene_state = scene_state;
|
||||||
FURI_LOG_D(LOGGING_TAG, "Timezone set to: %f", (double)plugin_state->timezone_offset);
|
FURI_LOG_D(LOGGING_TAG, "Timezone set to: %f", (double)plugin_state->timezone_offset);
|
||||||
update_totp_params(plugin_state);
|
|
||||||
|
|
||||||
scene_state->last_code_update_sync = furi_mutex_alloc(FuriMutexTypeNormal);
|
scene_state->last_code_update_sync = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||||
scene_state->usb_type_code_worker_context = totp_usb_type_code_worker_start(
|
scene_state->usb_type_code_worker_context = totp_usb_type_code_worker_start(
|
||||||
&scene_state->last_code[0],
|
scene_state->last_code,
|
||||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||||
scene_state->last_code_update_sync);
|
scene_state->last_code_update_sync);
|
||||||
}
|
}
|
||||||
@@ -255,11 +249,28 @@ void totp_scene_generate_token_activate(
|
|||||||
}
|
}
|
||||||
totp_bt_type_code_worker_start(
|
totp_bt_type_code_worker_start(
|
||||||
plugin_state->bt_type_code_worker_context,
|
plugin_state->bt_type_code_worker_context,
|
||||||
&scene_state->last_code[0],
|
scene_state->last_code,
|
||||||
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
|
||||||
scene_state->last_code_update_sync);
|
scene_state->last_code_update_sync);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
scene_state->generate_code_worker_context = totp_generate_code_worker_start(
|
||||||
|
scene_state->last_code,
|
||||||
|
&scene_state->current_token,
|
||||||
|
scene_state->last_code_update_sync,
|
||||||
|
plugin_state->timezone_offset,
|
||||||
|
plugin_state->iv);
|
||||||
|
|
||||||
|
totp_generate_code_worker_set_code_generated_handler(
|
||||||
|
scene_state->generate_code_worker_context, &on_new_token_code_generated, plugin_state);
|
||||||
|
|
||||||
|
totp_generate_code_worker_set_lifetime_changed_handler(
|
||||||
|
scene_state->generate_code_worker_context,
|
||||||
|
&on_code_lifetime_updated_generated,
|
||||||
|
scene_state);
|
||||||
|
|
||||||
|
update_totp_params(plugin_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) {
|
void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) {
|
||||||
@@ -281,54 +292,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||||
FuriHalRtcDateTime curr_dt;
|
|
||||||
furi_hal_rtc_get_datetime(&curr_dt);
|
|
||||||
uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
|
|
||||||
|
|
||||||
bool is_new_token_time = curr_ts % scene_state->current_token->duration == 0;
|
|
||||||
if(is_new_token_time && scene_state->last_token_gen_time != curr_ts) {
|
|
||||||
scene_state->need_token_update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(scene_state->need_token_update) {
|
|
||||||
scene_state->need_token_update = false;
|
|
||||||
scene_state->last_token_gen_time = curr_ts;
|
|
||||||
|
|
||||||
const TokenInfo* tokenInfo = scene_state->current_token;
|
|
||||||
|
|
||||||
if(tokenInfo->token != NULL && tokenInfo->token_length > 0) {
|
|
||||||
furi_mutex_acquire(scene_state->last_code_update_sync, FuriWaitForever);
|
|
||||||
size_t key_length;
|
|
||||||
uint8_t* key = totp_crypto_decrypt(
|
|
||||||
tokenInfo->token, tokenInfo->token_length, &plugin_state->iv[0], &key_length);
|
|
||||||
|
|
||||||
int_token_to_str(
|
|
||||||
totp_at(
|
|
||||||
get_totp_algo_impl(tokenInfo->algo),
|
|
||||||
key,
|
|
||||||
key_length,
|
|
||||||
curr_ts,
|
|
||||||
plugin_state->timezone_offset,
|
|
||||||
tokenInfo->duration),
|
|
||||||
scene_state->last_code,
|
|
||||||
tokenInfo->digits,
|
|
||||||
tokenInfo->algo);
|
|
||||||
memset_s(key, key_length, 0, key_length);
|
|
||||||
free(key);
|
|
||||||
} else {
|
|
||||||
furi_mutex_acquire(scene_state->last_code_update_sync, FuriWaitForever);
|
|
||||||
int_token_to_str(0, scene_state->last_code, tokenInfo->digits, tokenInfo->algo);
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_mutex_release(scene_state->last_code_update_sync);
|
|
||||||
|
|
||||||
if(is_new_token_time) {
|
|
||||||
notification_message(
|
|
||||||
plugin_state->notification_app,
|
|
||||||
get_notification_sequence_new_token(plugin_state, scene_state));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
uint16_t token_name_width = canvas_string_width(canvas, scene_state->current_token->name);
|
uint16_t token_name_width = canvas_string_width(canvas, scene_state->current_token->name);
|
||||||
@@ -356,17 +320,11 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
|
|
||||||
draw_totp_code(canvas, scene_state);
|
draw_totp_code(canvas, scene_state);
|
||||||
|
|
||||||
const uint8_t TOKEN_LIFETIME = scene_state->current_token->duration;
|
|
||||||
float percentDone = (float)(TOKEN_LIFETIME - curr_ts % TOKEN_LIFETIME) / (float)TOKEN_LIFETIME;
|
|
||||||
uint8_t barWidth = (uint8_t)((float)(SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1)) * percentDone);
|
|
||||||
uint8_t barX =
|
|
||||||
((SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1) - barWidth) >> 1) + PROGRESS_BAR_MARGIN;
|
|
||||||
|
|
||||||
canvas_draw_box(
|
canvas_draw_box(
|
||||||
canvas,
|
canvas,
|
||||||
barX,
|
scene_state->ui_precalculated_dimensions.progress_bar_x,
|
||||||
SCREEN_HEIGHT - PROGRESS_BAR_MARGIN - PROGRESS_BAR_HEIGHT,
|
SCREEN_HEIGHT - PROGRESS_BAR_MARGIN - PROGRESS_BAR_HEIGHT,
|
||||||
barWidth,
|
scene_state->ui_precalculated_dimensions.progress_bar_width,
|
||||||
PROGRESS_BAR_HEIGHT);
|
PROGRESS_BAR_HEIGHT);
|
||||||
|
|
||||||
if(plugin_state->tokens_count > 1) {
|
if(plugin_state->tokens_count > 1) {
|
||||||
@@ -496,6 +454,8 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
|
|||||||
if(plugin_state->current_scene_state == NULL) return;
|
if(plugin_state->current_scene_state == NULL) return;
|
||||||
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
||||||
|
|
||||||
|
totp_generate_code_worker_stop(scene_state->generate_code_worker_context);
|
||||||
|
|
||||||
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
if(plugin_state->automation_method & AutomationMethodBadUsb) {
|
||||||
totp_usb_type_code_worker_stop(scene_state->usb_type_code_worker_context);
|
totp_usb_type_code_worker_stop(scene_state->usb_type_code_worker_context);
|
||||||
}
|
}
|
||||||
@@ -509,8 +469,8 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
|
|||||||
free(scene_state->notification_sequence_new_token);
|
free(scene_state->notification_sequence_new_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scene_state->notification_sequence_badusb != NULL) {
|
if(scene_state->notification_sequence_automation != NULL) {
|
||||||
free(scene_state->notification_sequence_badusb);
|
free(scene_state->notification_sequence_automation);
|
||||||
}
|
}
|
||||||
|
|
||||||
furi_mutex_free(scene_state->last_code_update_sync);
|
furi_mutex_free(scene_state->last_code_update_sync);
|
||||||
@@ -518,7 +478,3 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
|
|||||||
free(scene_state);
|
free(scene_state);
|
||||||
plugin_state->current_scene_state = NULL;
|
plugin_state->current_scene_state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_generate_token_free(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ typedef struct {
|
|||||||
uint16_t current_token_index;
|
uint16_t current_token_index;
|
||||||
} GenerateTokenSceneContext;
|
} GenerateTokenSceneContext;
|
||||||
|
|
||||||
void totp_scene_generate_token_init(const PluginState* plugin_state);
|
|
||||||
void totp_scene_generate_token_activate(
|
void totp_scene_generate_token_activate(
|
||||||
PluginState* plugin_state,
|
PluginState* plugin_state,
|
||||||
const GenerateTokenSceneContext* context);
|
const GenerateTokenSceneContext* context);
|
||||||
@@ -17,4 +16,3 @@ bool totp_scene_generate_token_handle_event(
|
|||||||
const PluginEvent* const event,
|
const PluginEvent* const event,
|
||||||
PluginState* plugin_state);
|
PluginState* plugin_state);
|
||||||
void totp_scene_generate_token_deactivate(PluginState* plugin_state);
|
void totp_scene_generate_token_deactivate(PluginState* plugin_state);
|
||||||
void totp_scene_generate_token_free(const PluginState* plugin_state);
|
|
||||||
|
|||||||
@@ -24,10 +24,6 @@ typedef struct {
|
|||||||
TotpNullable_uint16_t current_token_index;
|
TotpNullable_uint16_t current_token_index;
|
||||||
} SceneState;
|
} SceneState;
|
||||||
|
|
||||||
void totp_scene_token_menu_init(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void totp_scene_token_menu_activate(
|
void totp_scene_token_menu_activate(
|
||||||
PluginState* plugin_state,
|
PluginState* plugin_state,
|
||||||
const TokenMenuSceneContext* context) {
|
const TokenMenuSceneContext* context) {
|
||||||
@@ -204,7 +200,3 @@ void totp_scene_token_menu_deactivate(PluginState* plugin_state) {
|
|||||||
free(plugin_state->current_scene_state);
|
free(plugin_state->current_scene_state);
|
||||||
plugin_state->current_scene_state = NULL;
|
plugin_state->current_scene_state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_scene_token_menu_free(const PluginState* plugin_state) {
|
|
||||||
UNUSED(plugin_state);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ typedef struct {
|
|||||||
uint16_t current_token_index;
|
uint16_t current_token_index;
|
||||||
} TokenMenuSceneContext;
|
} TokenMenuSceneContext;
|
||||||
|
|
||||||
void totp_scene_token_menu_init(const PluginState* plugin_state);
|
|
||||||
void totp_scene_token_menu_activate(
|
void totp_scene_token_menu_activate(
|
||||||
PluginState* plugin_state,
|
PluginState* plugin_state,
|
||||||
const TokenMenuSceneContext* context);
|
const TokenMenuSceneContext* context);
|
||||||
void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state);
|
void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state);
|
||||||
bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginState* plugin_state);
|
bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginState* plugin_state);
|
||||||
void totp_scene_token_menu_deactivate(PluginState* plugin_state);
|
void totp_scene_token_menu_deactivate(PluginState* plugin_state);
|
||||||
void totp_scene_token_menu_free(const PluginState* plugin_state);
|
|
||||||
|
|||||||
4
applications/external/totp/ui/ui_controls.c
vendored
4
applications/external/totp/ui/ui_controls.c
vendored
@@ -2,8 +2,8 @@
|
|||||||
#include <totp_icons.h>
|
#include <totp_icons.h>
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
#define TEXT_BOX_HEIGHT 13
|
#define TEXT_BOX_HEIGHT (13)
|
||||||
#define TEXT_BOX_MARGIN 4
|
#define TEXT_BOX_MARGIN (4)
|
||||||
|
|
||||||
void ui_control_text_box_render(
|
void ui_control_text_box_render(
|
||||||
Canvas* const canvas,
|
Canvas* const canvas,
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#include "bt_type_code.h"
|
#include "bt_type_code.h"
|
||||||
#include <furi_hal_bt_hid.h>
|
#include <furi_hal_bt_hid.h>
|
||||||
|
#include <furi_hal_version.h>
|
||||||
#include <bt/bt_service/bt_i.h>
|
#include <bt/bt_service/bt_i.h>
|
||||||
#include <storage/storage.h>
|
#include <storage/storage.h>
|
||||||
#include "../../types/common.h"
|
#include "../../types/common.h"
|
||||||
#include "../../types/token_info.h"
|
#include "../../types/token_info.h"
|
||||||
#include "../common.h"
|
#include "../type_code_common.h"
|
||||||
|
|
||||||
#define HID_BT_KEYS_STORAGE_PATH EXT_PATH("authenticator/.bt_hid.keys")
|
#define HID_BT_KEYS_STORAGE_PATH EXT_PATH("authenticator/.bt_hid.keys")
|
||||||
|
|
||||||
@@ -16,15 +17,15 @@ static inline bool totp_type_code_worker_stop_requested() {
|
|||||||
static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) {
|
static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) {
|
||||||
uint8_t max_i;
|
uint8_t max_i;
|
||||||
size_t uid_size = furi_hal_version_uid_size();
|
size_t uid_size = furi_hal_version_uid_size();
|
||||||
if(uid_size < 6) {
|
if(uid_size < TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN) {
|
||||||
max_i = uid_size;
|
max_i = uid_size;
|
||||||
} else {
|
} else {
|
||||||
max_i = 6;
|
max_i = TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* uid = furi_hal_version_uid();
|
const uint8_t* uid = furi_hal_version_uid();
|
||||||
memcpy(mac, uid, max_i);
|
memcpy(mac, uid, max_i);
|
||||||
for(uint8_t i = max_i; i < 6; i++) {
|
for(uint8_t i = max_i; i < TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN; i++) {
|
||||||
mac[i] = 0;
|
mac[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,23 +40,21 @@ static void totp_type_code_worker_type_code(TotpBtTypeCodeWorkerContext* context
|
|||||||
i++;
|
i++;
|
||||||
} while(!context->is_connected && i < 100 && !totp_type_code_worker_stop_requested());
|
} while(!context->is_connected && i < 100 && !totp_type_code_worker_stop_requested());
|
||||||
|
|
||||||
if(context->is_connected && furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) {
|
if(context->is_connected &&
|
||||||
|
furi_mutex_acquire(context->code_buffer_sync, 500) == FuriStatusOk) {
|
||||||
totp_type_code_worker_execute_automation(
|
totp_type_code_worker_execute_automation(
|
||||||
&furi_hal_bt_hid_kb_press,
|
&furi_hal_bt_hid_kb_press,
|
||||||
&furi_hal_bt_hid_kb_release,
|
&furi_hal_bt_hid_kb_release,
|
||||||
context->string,
|
context->code_buffer,
|
||||||
context->string_length,
|
context->code_buffer_size,
|
||||||
context->flags);
|
context->flags);
|
||||||
furi_mutex_release(context->string_sync);
|
furi_mutex_release(context->code_buffer_sync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t totp_type_code_worker_callback(void* context) {
|
static int32_t totp_type_code_worker_callback(void* context) {
|
||||||
furi_check(context);
|
furi_check(context);
|
||||||
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
if(context_mutex == NULL) {
|
|
||||||
return 251;
|
|
||||||
}
|
|
||||||
|
|
||||||
TotpBtTypeCodeWorkerContext* bt_context = context;
|
TotpBtTypeCodeWorkerContext* bt_context = context;
|
||||||
|
|
||||||
@@ -92,13 +91,13 @@ static void connection_status_changed_callback(BtStatus status, void* context) {
|
|||||||
|
|
||||||
void totp_bt_type_code_worker_start(
|
void totp_bt_type_code_worker_start(
|
||||||
TotpBtTypeCodeWorkerContext* context,
|
TotpBtTypeCodeWorkerContext* context,
|
||||||
char* code_buf,
|
char* code_buffer,
|
||||||
uint8_t code_buf_length,
|
uint8_t code_buffer_size,
|
||||||
FuriMutex* code_buf_update_sync) {
|
FuriMutex* code_buffer_sync) {
|
||||||
furi_check(context != NULL);
|
furi_check(context != NULL);
|
||||||
context->string = code_buf;
|
context->code_buffer = code_buffer;
|
||||||
context->string_length = code_buf_length;
|
context->code_buffer_size = code_buffer_size;
|
||||||
context->string_sync = code_buf_update_sync;
|
context->code_buffer_sync = code_buffer_sync;
|
||||||
context->thread = furi_thread_alloc();
|
context->thread = furi_thread_alloc();
|
||||||
furi_thread_set_name(context->thread, "TOTPBtHidWorker");
|
furi_thread_set_name(context->thread, "TOTPBtHidWorker");
|
||||||
furi_thread_set_stack_size(context->thread, 1024);
|
furi_thread_set_stack_size(context->thread, 1024);
|
||||||
@@ -137,7 +136,6 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
|||||||
bt_keys_storage_set_storage_path(context->bt, HID_BT_KEYS_STORAGE_PATH);
|
bt_keys_storage_set_storage_path(context->bt, HID_BT_KEYS_STORAGE_PATH);
|
||||||
|
|
||||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||||
totp_type_code_worker_bt_set_app_mac(&context->bt_mac[0]);
|
|
||||||
memcpy(
|
memcpy(
|
||||||
&context->previous_bt_name[0],
|
&context->previous_bt_name[0],
|
||||||
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
|
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
|
||||||
@@ -148,8 +146,10 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
|||||||
TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN);
|
TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN);
|
||||||
char new_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN];
|
char new_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN];
|
||||||
snprintf(new_name, sizeof(new_name), "%s TOTP Auth", furi_hal_version_get_name_ptr());
|
snprintf(new_name, sizeof(new_name), "%s TOTP Auth", furi_hal_version_get_name_ptr());
|
||||||
|
uint8_t new_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN];
|
||||||
|
totp_type_code_worker_bt_set_app_mac(new_bt_mac);
|
||||||
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, new_name);
|
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, new_name);
|
||||||
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, context->bt_mac);
|
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, new_bt_mac);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!bt_set_profile(context->bt, BtProfileHidKeyboard)) {
|
if(!bt_set_profile(context->bt, BtProfileHidKeyboard)) {
|
||||||
|
|||||||
@@ -1,47 +1,48 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <furi/furi.h>
|
#include <furi/core/thread.h>
|
||||||
#include <furi_hal.h>
|
#include <furi/core/mutex.h>
|
||||||
|
#include <furi/core/string.h>
|
||||||
|
#include <furi/core/kernel.h>
|
||||||
#include <bt/bt_service/bt.h>
|
#include <bt/bt_service/bt.h>
|
||||||
#include "../../features_config.h"
|
#include "../../features_config.h"
|
||||||
|
|
||||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||||
#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN 18
|
#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH
|
||||||
#define TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE
|
#define TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef uint8_t TotpBtTypeCodeWorkerEvent;
|
typedef uint8_t TotpBtTypeCodeWorkerEvent;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* string;
|
char* code_buffer;
|
||||||
uint8_t string_length;
|
uint8_t code_buffer_size;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
FuriThread* thread;
|
FuriThread* thread;
|
||||||
FuriMutex* string_sync;
|
FuriMutex* code_buffer_sync;
|
||||||
Bt* bt;
|
Bt* bt;
|
||||||
bool is_advertising;
|
bool is_advertising;
|
||||||
bool is_connected;
|
bool is_connected;
|
||||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||||
uint8_t bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN];
|
char previous_bt_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN];
|
||||||
char previous_bt_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN + 1];
|
|
||||||
uint8_t previous_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN];
|
uint8_t previous_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN];
|
||||||
#endif
|
#endif
|
||||||
} TotpBtTypeCodeWorkerContext;
|
} TotpBtTypeCodeWorkerContext;
|
||||||
|
|
||||||
enum TotpBtTypeCodeWorkerEvents {
|
enum TotpBtTypeCodeWorkerEvents {
|
||||||
TotpBtTypeCodeWorkerEventReserved = 0b0000,
|
TotpBtTypeCodeWorkerEventReserved = 0b00,
|
||||||
TotpBtTypeCodeWorkerEventStop = 0b0100,
|
TotpBtTypeCodeWorkerEventStop = 0b01,
|
||||||
TotpBtTypeCodeWorkerEventType = 0b1000
|
TotpBtTypeCodeWorkerEventType = 0b10
|
||||||
};
|
};
|
||||||
|
|
||||||
TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init();
|
TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init();
|
||||||
void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context);
|
void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context);
|
||||||
void totp_bt_type_code_worker_start(
|
void totp_bt_type_code_worker_start(
|
||||||
TotpBtTypeCodeWorkerContext* context,
|
TotpBtTypeCodeWorkerContext* context,
|
||||||
char* code_buf,
|
char* code_buffer,
|
||||||
uint8_t code_buf_length,
|
uint8_t code_buffer_size,
|
||||||
FuriMutex* code_buf_update_sync);
|
FuriMutex* code_buffer_sync);
|
||||||
void totp_bt_type_code_worker_stop(TotpBtTypeCodeWorkerContext* context);
|
void totp_bt_type_code_worker_stop(TotpBtTypeCodeWorkerContext* context);
|
||||||
void totp_bt_type_code_worker_notify(
|
void totp_bt_type_code_worker_notify(
|
||||||
TotpBtTypeCodeWorkerContext* context,
|
TotpBtTypeCodeWorkerContext* context,
|
||||||
|
|||||||
181
applications/external/totp/workers/generate_totp_code/generate_totp_code.c
vendored
Normal file
181
applications/external/totp/workers/generate_totp_code/generate_totp_code.c
vendored
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
#include "generate_totp_code.h"
|
||||||
|
#include "../../services/crypto/crypto.h"
|
||||||
|
#include "../../services/totp/totp.h"
|
||||||
|
#include "../../services/convert/convert.h"
|
||||||
|
#include <furi_hal_rtc.h>
|
||||||
|
#include <memset_s.h>
|
||||||
|
|
||||||
|
#define ONE_SEC_MS (1000)
|
||||||
|
|
||||||
|
static const char* STEAM_ALGO_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY";
|
||||||
|
|
||||||
|
static void
|
||||||
|
int_token_to_str(uint64_t i_token_code, char* str, TokenDigitsCount len, TokenHashAlgo algo) {
|
||||||
|
str[len] = '\0';
|
||||||
|
if(i_token_code == OTP_ERROR) {
|
||||||
|
memset(&str[0], '-', len);
|
||||||
|
} else {
|
||||||
|
if(algo == STEAM) {
|
||||||
|
for(uint8_t i = 0; i < len; i++) {
|
||||||
|
str[i] = STEAM_ALGO_ALPHABET[i_token_code % 26];
|
||||||
|
i_token_code = i_token_code / 26;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(int8_t i = len - 1; i >= 0; i--) {
|
||||||
|
str[i] = CONVERT_DIGIT_TO_CHAR(i_token_code % 10);
|
||||||
|
i_token_code = i_token_code / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) {
|
||||||
|
switch(algo) {
|
||||||
|
case SHA1:
|
||||||
|
case STEAM:
|
||||||
|
return TOTP_ALGO_SHA1;
|
||||||
|
case SHA256:
|
||||||
|
return TOTP_ALGO_SHA256;
|
||||||
|
case SHA512:
|
||||||
|
return TOTP_ALGO_SHA512;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generate_totp_code(
|
||||||
|
TotpGenerateCodeWorkerContext* context,
|
||||||
|
const TokenInfo* token_info,
|
||||||
|
uint32_t current_ts) {
|
||||||
|
if(token_info->token != NULL && token_info->token_length > 0) {
|
||||||
|
size_t key_length;
|
||||||
|
uint8_t* key = totp_crypto_decrypt(
|
||||||
|
token_info->token, token_info->token_length, context->iv, &key_length);
|
||||||
|
|
||||||
|
int_token_to_str(
|
||||||
|
totp_at(
|
||||||
|
get_totp_algo_impl(token_info->algo),
|
||||||
|
key,
|
||||||
|
key_length,
|
||||||
|
current_ts,
|
||||||
|
context->timezone_offset,
|
||||||
|
token_info->duration),
|
||||||
|
context->code_buffer,
|
||||||
|
token_info->digits,
|
||||||
|
token_info->algo);
|
||||||
|
memset_s(key, key_length, 0, key_length);
|
||||||
|
free(key);
|
||||||
|
} else {
|
||||||
|
int_token_to_str(0, context->code_buffer, token_info->digits, token_info->algo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t totp_generate_worker_callback(void* context) {
|
||||||
|
furi_check(context);
|
||||||
|
|
||||||
|
TotpGenerateCodeWorkerContext* t_context = context;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
uint32_t flags = furi_thread_flags_wait(
|
||||||
|
TotpGenerateCodeWorkerEventStop | TotpGenerateCodeWorkerEventForceUpdate,
|
||||||
|
FuriFlagWaitAny,
|
||||||
|
ONE_SEC_MS);
|
||||||
|
|
||||||
|
if(flags ==
|
||||||
|
(uint32_t)
|
||||||
|
FuriFlagErrorTimeout) { // If timeout, consider as no error, as we expect this and can handle gracefully
|
||||||
|
flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_check((flags & FuriFlagError) == 0); //-V562
|
||||||
|
|
||||||
|
if(flags & TotpGenerateCodeWorkerEventStop) break;
|
||||||
|
|
||||||
|
const TokenInfo* token_info = *(t_context->token_info);
|
||||||
|
if(token_info == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t curr_ts = furi_hal_rtc_get_timestamp();
|
||||||
|
|
||||||
|
bool time_left = false;
|
||||||
|
if(flags & TotpGenerateCodeWorkerEventForceUpdate ||
|
||||||
|
(time_left = (curr_ts % token_info->duration) == 0)) {
|
||||||
|
if(furi_mutex_acquire(t_context->code_buffer_sync, FuriWaitForever) == FuriStatusOk) {
|
||||||
|
generate_totp_code(t_context, token_info, curr_ts);
|
||||||
|
curr_ts = furi_hal_rtc_get_timestamp();
|
||||||
|
furi_mutex_release(t_context->code_buffer_sync);
|
||||||
|
if(t_context->on_new_code_generated_handler != NULL) {
|
||||||
|
(*(t_context->on_new_code_generated_handler))(
|
||||||
|
time_left, t_context->on_new_code_generated_handler_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(t_context->on_code_lifetime_changed_handler != NULL) {
|
||||||
|
(*(t_context->on_code_lifetime_changed_handler))(
|
||||||
|
(float)(token_info->duration - curr_ts % token_info->duration) /
|
||||||
|
(float)token_info->duration,
|
||||||
|
t_context->on_code_lifetime_changed_handler_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TotpGenerateCodeWorkerContext* totp_generate_code_worker_start(
|
||||||
|
char* code_buffer,
|
||||||
|
TokenInfo** token_info,
|
||||||
|
FuriMutex* code_buffer_sync,
|
||||||
|
float timezone_offset,
|
||||||
|
uint8_t* iv) {
|
||||||
|
TotpGenerateCodeWorkerContext* context = malloc(sizeof(TotpGenerateCodeWorkerContext));
|
||||||
|
furi_check(context != NULL);
|
||||||
|
context->code_buffer = code_buffer;
|
||||||
|
context->token_info = token_info;
|
||||||
|
context->code_buffer_sync = code_buffer_sync;
|
||||||
|
context->timezone_offset = timezone_offset;
|
||||||
|
context->iv = iv;
|
||||||
|
context->thread = furi_thread_alloc();
|
||||||
|
furi_thread_set_name(context->thread, "TOTPGenerateWorker");
|
||||||
|
furi_thread_set_stack_size(context->thread, 2048);
|
||||||
|
furi_thread_set_context(context->thread, context);
|
||||||
|
furi_thread_set_callback(context->thread, totp_generate_worker_callback);
|
||||||
|
furi_thread_start(context->thread);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void totp_generate_code_worker_stop(TotpGenerateCodeWorkerContext* context) {
|
||||||
|
furi_check(context != NULL);
|
||||||
|
furi_thread_flags_set(furi_thread_get_id(context->thread), TotpGenerateCodeWorkerEventStop);
|
||||||
|
furi_thread_join(context->thread);
|
||||||
|
furi_thread_free(context->thread);
|
||||||
|
free(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void totp_generate_code_worker_notify(
|
||||||
|
TotpGenerateCodeWorkerContext* context,
|
||||||
|
TotpGenerateCodeWorkerEvent event) {
|
||||||
|
furi_check(context != NULL);
|
||||||
|
furi_thread_flags_set(furi_thread_get_id(context->thread), event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void totp_generate_code_worker_set_code_generated_handler(
|
||||||
|
TotpGenerateCodeWorkerContext* context,
|
||||||
|
TOTP_NEW_CODE_GENERATED_HANDLER on_new_code_generated_handler,
|
||||||
|
void* on_new_code_generated_handler_context) {
|
||||||
|
furi_check(context != NULL);
|
||||||
|
context->on_new_code_generated_handler = on_new_code_generated_handler;
|
||||||
|
context->on_new_code_generated_handler_context = on_new_code_generated_handler_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void totp_generate_code_worker_set_lifetime_changed_handler(
|
||||||
|
TotpGenerateCodeWorkerContext* context,
|
||||||
|
TOTP_CODE_LIFETIME_CHANGED_HANDLER on_code_lifetime_changed_handler,
|
||||||
|
void* on_code_lifetime_changed_handler_context) {
|
||||||
|
furi_check(context != NULL);
|
||||||
|
context->on_code_lifetime_changed_handler = on_code_lifetime_changed_handler;
|
||||||
|
context->on_code_lifetime_changed_handler_context = on_code_lifetime_changed_handler_context;
|
||||||
|
}
|
||||||
49
applications/external/totp/workers/generate_totp_code/generate_totp_code.h
vendored
Normal file
49
applications/external/totp/workers/generate_totp_code/generate_totp_code.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <furi/core/thread.h>
|
||||||
|
#include <furi/core/mutex.h>
|
||||||
|
#include "../../types/token_info.h"
|
||||||
|
|
||||||
|
typedef uint8_t TotpGenerateCodeWorkerEvent;
|
||||||
|
|
||||||
|
typedef void (*TOTP_NEW_CODE_GENERATED_HANDLER)(bool time_left, void* context);
|
||||||
|
typedef void (*TOTP_CODE_LIFETIME_CHANGED_HANDLER)(float code_lifetime_percent, void* context);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* code_buffer;
|
||||||
|
FuriThread* thread;
|
||||||
|
FuriMutex* code_buffer_sync;
|
||||||
|
TokenInfo** token_info;
|
||||||
|
float timezone_offset;
|
||||||
|
uint8_t* iv;
|
||||||
|
TOTP_NEW_CODE_GENERATED_HANDLER on_new_code_generated_handler;
|
||||||
|
void* on_new_code_generated_handler_context;
|
||||||
|
TOTP_CODE_LIFETIME_CHANGED_HANDLER on_code_lifetime_changed_handler;
|
||||||
|
void* on_code_lifetime_changed_handler_context;
|
||||||
|
} TotpGenerateCodeWorkerContext;
|
||||||
|
|
||||||
|
enum TotGenerateCodeWorkerEvents {
|
||||||
|
TotpGenerateCodeWorkerEventReserved = 0b00,
|
||||||
|
TotpGenerateCodeWorkerEventStop = 0b01,
|
||||||
|
TotpGenerateCodeWorkerEventForceUpdate = 0b10
|
||||||
|
};
|
||||||
|
|
||||||
|
TotpGenerateCodeWorkerContext* totp_generate_code_worker_start(
|
||||||
|
char* code_buffer,
|
||||||
|
TokenInfo** token_info,
|
||||||
|
FuriMutex* code_buffer_sync,
|
||||||
|
float timezone_offset,
|
||||||
|
uint8_t* iv);
|
||||||
|
void totp_generate_code_worker_stop(TotpGenerateCodeWorkerContext* context);
|
||||||
|
void totp_generate_code_worker_notify(
|
||||||
|
TotpGenerateCodeWorkerContext* context,
|
||||||
|
TotpGenerateCodeWorkerEvent event);
|
||||||
|
void totp_generate_code_worker_set_code_generated_handler(
|
||||||
|
TotpGenerateCodeWorkerContext* context,
|
||||||
|
TOTP_NEW_CODE_GENERATED_HANDLER on_new_code_generated_handler,
|
||||||
|
void* on_new_code_generated_handler_context);
|
||||||
|
void totp_generate_code_worker_set_lifetime_changed_handler(
|
||||||
|
TotpGenerateCodeWorkerContext* context,
|
||||||
|
TOTP_CODE_LIFETIME_CHANGED_HANDLER on_code_lifetime_changed_handler,
|
||||||
|
void* on_code_lifetime_changed_handler_context);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "common.h"
|
#include "type_code_common.h"
|
||||||
#include <furi/furi.h>
|
#include <furi_hal_usb_hid.h>
|
||||||
#include <furi_hal.h>
|
#include <furi/core/kernel.h>
|
||||||
#include "../../services/convert/convert.h"
|
#include "../../services/convert/convert.h"
|
||||||
|
|
||||||
static const uint8_t hid_number_keys[] = {
|
static const uint8_t hid_number_keys[] = {
|
||||||
@@ -42,18 +42,18 @@ static void totp_type_code_worker_press_key(
|
|||||||
void totp_type_code_worker_execute_automation(
|
void totp_type_code_worker_execute_automation(
|
||||||
TOTP_AUTOMATION_KEY_HANDLER key_press_fn,
|
TOTP_AUTOMATION_KEY_HANDLER key_press_fn,
|
||||||
TOTP_AUTOMATION_KEY_HANDLER key_release_fn,
|
TOTP_AUTOMATION_KEY_HANDLER key_release_fn,
|
||||||
const char* string,
|
const char* code_buffer,
|
||||||
uint8_t string_length,
|
uint8_t code_buffer_size,
|
||||||
TokenAutomationFeature features) {
|
TokenAutomationFeature features) {
|
||||||
furi_delay_ms(500);
|
furi_delay_ms(500);
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
totp_type_code_worker_press_key(
|
totp_type_code_worker_press_key(
|
||||||
HID_KEYBOARD_CAPS_LOCK, key_press_fn, key_release_fn, features);
|
HID_KEYBOARD_CAPS_LOCK, key_press_fn, key_release_fn, features);
|
||||||
|
|
||||||
while(i < string_length && string[i] != 0) {
|
while(i < code_buffer_size && code_buffer[i] != 0) {
|
||||||
uint8_t char_index = CONVERT_CHAR_TO_DIGIT(string[i]);
|
uint8_t char_index = CONVERT_CHAR_TO_DIGIT(code_buffer[i]);
|
||||||
if(char_index > 9) {
|
if(char_index > 9) {
|
||||||
char_index = string[i] - 0x41 + 10;
|
char_index = code_buffer[i] - 0x41 + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(char_index > 35) break;
|
if(char_index > 35) break;
|
||||||
@@ -7,6 +7,6 @@ typedef bool (*TOTP_AUTOMATION_KEY_HANDLER)(uint16_t key);
|
|||||||
void totp_type_code_worker_execute_automation(
|
void totp_type_code_worker_execute_automation(
|
||||||
TOTP_AUTOMATION_KEY_HANDLER key_press_fn,
|
TOTP_AUTOMATION_KEY_HANDLER key_press_fn,
|
||||||
TOTP_AUTOMATION_KEY_HANDLER key_release_fn,
|
TOTP_AUTOMATION_KEY_HANDLER key_release_fn,
|
||||||
const char* string,
|
const char* code_buffer,
|
||||||
uint8_t string_length,
|
uint8_t code_buffer_size,
|
||||||
TokenAutomationFeature features);
|
TokenAutomationFeature features);
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#include "usb_type_code.h"
|
#include "usb_type_code.h"
|
||||||
|
#include <furi_hal_usb_hid.h>
|
||||||
#include "../../services/convert/convert.h"
|
#include "../../services/convert/convert.h"
|
||||||
#include "../../types/token_info.h"
|
#include "../../types/token_info.h"
|
||||||
#include "../common.h"
|
#include "../type_code_common.h"
|
||||||
|
|
||||||
static void totp_type_code_worker_restore_usb_mode(TotpUsbTypeCodeWorkerContext* context) {
|
static void totp_type_code_worker_restore_usb_mode(TotpUsbTypeCodeWorkerContext* context) {
|
||||||
if(context->usb_mode_prev != NULL) {
|
if(context->usb_mode_prev != NULL) {
|
||||||
@@ -25,14 +26,14 @@ static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* contex
|
|||||||
} while(!furi_hal_hid_is_connected() && i < 100 && !totp_type_code_worker_stop_requested());
|
} while(!furi_hal_hid_is_connected() && i < 100 && !totp_type_code_worker_stop_requested());
|
||||||
|
|
||||||
if(furi_hal_hid_is_connected() &&
|
if(furi_hal_hid_is_connected() &&
|
||||||
furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) {
|
furi_mutex_acquire(context->code_buffer_sync, 500) == FuriStatusOk) {
|
||||||
totp_type_code_worker_execute_automation(
|
totp_type_code_worker_execute_automation(
|
||||||
&furi_hal_hid_kb_press,
|
&furi_hal_hid_kb_press,
|
||||||
&furi_hal_hid_kb_release,
|
&furi_hal_hid_kb_release,
|
||||||
context->string,
|
context->code_buffer,
|
||||||
context->string_length,
|
context->code_buffer_size,
|
||||||
context->flags);
|
context->flags);
|
||||||
furi_mutex_release(context->string_sync);
|
furi_mutex_release(context->code_buffer_sync);
|
||||||
|
|
||||||
furi_delay_ms(100);
|
furi_delay_ms(100);
|
||||||
}
|
}
|
||||||
@@ -43,9 +44,6 @@ static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* contex
|
|||||||
static int32_t totp_type_code_worker_callback(void* context) {
|
static int32_t totp_type_code_worker_callback(void* context) {
|
||||||
furi_check(context);
|
furi_check(context);
|
||||||
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
if(context_mutex == NULL) {
|
|
||||||
return 251;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
uint32_t flags = furi_thread_flags_wait(
|
uint32_t flags = furi_thread_flags_wait(
|
||||||
@@ -70,14 +68,14 @@ static int32_t totp_type_code_worker_callback(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start(
|
TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start(
|
||||||
char* code_buf,
|
char* code_buffer,
|
||||||
uint8_t code_buf_length,
|
uint8_t code_buffer_size,
|
||||||
FuriMutex* code_buf_update_sync) {
|
FuriMutex* code_buffer_sync) {
|
||||||
TotpUsbTypeCodeWorkerContext* context = malloc(sizeof(TotpUsbTypeCodeWorkerContext));
|
TotpUsbTypeCodeWorkerContext* context = malloc(sizeof(TotpUsbTypeCodeWorkerContext));
|
||||||
furi_check(context != NULL);
|
furi_check(context != NULL);
|
||||||
context->string = code_buf;
|
context->code_buffer = code_buffer;
|
||||||
context->string_length = code_buf_length;
|
context->code_buffer_size = code_buffer_size;
|
||||||
context->string_sync = code_buf_update_sync;
|
context->code_buffer_sync = code_buffer_sync;
|
||||||
context->thread = furi_thread_alloc();
|
context->thread = furi_thread_alloc();
|
||||||
context->usb_mode_prev = NULL;
|
context->usb_mode_prev = NULL;
|
||||||
furi_thread_set_name(context->thread, "TOTPUsbHidWorker");
|
furi_thread_set_name(context->thread, "TOTPUsbHidWorker");
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <furi/furi.h>
|
#include <furi/core/thread.h>
|
||||||
#include <furi_hal.h>
|
#include <furi/core/mutex.h>
|
||||||
|
#include <furi/core/kernel.h>
|
||||||
|
#include <furi/core/check.h>
|
||||||
|
#include <furi_hal_usb.h>
|
||||||
|
|
||||||
typedef uint8_t TotpUsbTypeCodeWorkerEvent;
|
typedef uint8_t TotpUsbTypeCodeWorkerEvent;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* string;
|
char* code_buffer;
|
||||||
uint8_t string_length;
|
uint8_t code_buffer_size;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
FuriThread* thread;
|
FuriThread* thread;
|
||||||
FuriMutex* string_sync;
|
FuriMutex* code_buffer_sync;
|
||||||
FuriHalUsbInterface* usb_mode_prev;
|
FuriHalUsbInterface* usb_mode_prev;
|
||||||
} TotpUsbTypeCodeWorkerContext;
|
} TotpUsbTypeCodeWorkerContext;
|
||||||
|
|
||||||
@@ -22,9 +25,9 @@ enum TotpUsbTypeCodeWorkerEvents {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start(
|
TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start(
|
||||||
char* code_buf,
|
char* code_buffer,
|
||||||
uint8_t code_buf_length,
|
uint8_t code_buffer_size,
|
||||||
FuriMutex* code_buf_update_sync);
|
FuriMutex* code_buffer_sync);
|
||||||
void totp_usb_type_code_worker_stop(TotpUsbTypeCodeWorkerContext* context);
|
void totp_usb_type_code_worker_stop(TotpUsbTypeCodeWorkerContext* context);
|
||||||
void totp_usb_type_code_worker_notify(
|
void totp_usb_type_code_worker_notify(
|
||||||
TotpUsbTypeCodeWorkerContext* context,
|
TotpUsbTypeCodeWorkerContext* context,
|
||||||
|
|||||||
Reference in New Issue
Block a user