mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-23 05:14:16 +03:00
parent
3cdb05364b
commit
563ec6c2ab
5
applications/external/totp/application.fam
vendored
5
applications/external/totp/application.fam
vendored
@ -25,7 +25,10 @@ App(
|
||||
name="base32",
|
||||
),
|
||||
Lib(
|
||||
name="list",
|
||||
name="base64",
|
||||
),
|
||||
Lib(
|
||||
name="linked_list"
|
||||
),
|
||||
Lib(
|
||||
name="timezone_utils",
|
||||
|
4
applications/external/totp/cli/cli_helpers.c
vendored
4
applications/external/totp/cli/cli_helpers.c
vendored
@ -41,7 +41,9 @@ bool totp_cli_read_line(Cli* cli, FuriString* out_str, bool mask_user_input) {
|
||||
} else if(c == CliSymbolAsciiETX) {
|
||||
cli_nl();
|
||||
return false;
|
||||
} else if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
|
||||
} else if(
|
||||
(c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||
c == '/' || c == '=' || c == '+') {
|
||||
if(mask_user_input) {
|
||||
putc('*', stdout);
|
||||
} else {
|
||||
|
23
applications/external/totp/cli/cli_helpers.h
vendored
23
applications/external/totp/cli/cli_helpers.h
vendored
@ -14,24 +14,13 @@
|
||||
#define DOCOPT_OPTIONS "[options]"
|
||||
#define DOCOPT_DEFAULT(val) "[default: " val "]"
|
||||
|
||||
#define TOTP_CLI_PRINTF(format, ...) \
|
||||
do { \
|
||||
_Pragma(STRINGIFY(GCC diagnostic push)) \
|
||||
_Pragma(STRINGIFY(GCC diagnostic ignored "-Wdouble-promotion")) \
|
||||
printf(format, ##__VA_ARGS__); \
|
||||
_Pragma(STRINGIFY(GCC diagnostic pop)) \
|
||||
} while(false)
|
||||
#define TOTP_CLI_PRINTF(format, ...) printf(format, ##__VA_ARGS__)
|
||||
|
||||
#define TOTP_CLI_PRINTF_COLORFUL(color, format, ...) \
|
||||
do { \
|
||||
_Pragma(STRINGIFY(GCC diagnostic push)) \
|
||||
_Pragma(STRINGIFY(GCC diagnostic ignored "-Wdouble-promotion")) \
|
||||
printf("\e[%s", color); \
|
||||
printf(format, ##__VA_ARGS__); \
|
||||
printf("\e[0m"); \
|
||||
fflush(stdout); \
|
||||
_Pragma(STRINGIFY(GCC diagnostic pop)) \
|
||||
} while(false)
|
||||
#define TOTP_CLI_PRINTF_COLORFUL(color, format, ...) \
|
||||
printf("\e[%s", color); \
|
||||
printf(format, ##__VA_ARGS__); \
|
||||
printf("\e[0m"); \
|
||||
fflush(stdout)
|
||||
|
||||
#define TOTP_CLI_COLOR_ERROR "91m"
|
||||
#define TOTP_CLI_COLOR_WARNING "93m"
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "add.h"
|
||||
#include <stdlib.h>
|
||||
#include <lib/toolbox/args.h>
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../../services/convert/convert.h"
|
||||
@ -17,11 +17,11 @@ void totp_cli_command_add_docopt_commands() {
|
||||
void totp_cli_command_add_docopt_usage() {
|
||||
TOTP_CLI_PRINTF(
|
||||
" " TOTP_CLI_COMMAND_NAME
|
||||
" " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_ADD " | " TOTP_CLI_COMMAND_ADD_ALT " | " TOTP_CLI_COMMAND_ADD_ALT2) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_NAME) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_ALGO))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_DIGITS))) " " DOCOPT_OPTIONAL(
|
||||
" " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_ADD " | " TOTP_CLI_COMMAND_ADD_ALT " | " TOTP_CLI_COMMAND_ADD_ALT2) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_NAME) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_ALGO))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_SECRET_ENCODING))) " " DOCOPT_OPTIONAL(
|
||||
DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION_PREFIX,
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ARG_UNSECURE_PREFIX)) " " DOCOPT_MULTIPLE(DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)))) "\r\n");
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_DURATION_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_DURATION))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ARG_UNSECURE_PREFIX)) " " DOCOPT_MULTIPLE(DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)))) "\r\n");
|
||||
}
|
||||
|
||||
void totp_cli_command_add_docopt_arguments() {
|
||||
@ -35,11 +35,21 @@ void totp_cli_command_add_docopt_options() {
|
||||
TOTP_CLI_COMMAND_ARG_ALGO)) " Token hashing algorithm. Must be one of: " TOTP_TOKEN_ALGO_SHA1_NAME
|
||||
", " TOTP_TOKEN_ALGO_SHA256_NAME
|
||||
", " TOTP_TOKEN_ALGO_SHA512_NAME
|
||||
", " TOTP_TOKEN_ALGO_STEAM_NAME
|
||||
" " DOCOPT_DEFAULT(TOTP_TOKEN_ALGO_SHA1_NAME) "\r\n");
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS)) " Number of digits to generate, one of: 6, 8 " DOCOPT_DEFAULT("6") "\r\n");
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS)) " Number of digits to generate, one of: 5, 6, 8 " DOCOPT_DEFAULT("6") "\r\n");
|
||||
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_SECRET_ENCODING)) " Token secret encoding, one of " PLAIN_TOKEN_ENCODING_BASE32_NAME
|
||||
", " PLAIN_TOKEN_ENCODING_BASE64_NAME
|
||||
" " DOCOPT_DEFAULT(
|
||||
PLAIN_TOKEN_ENCODING_BASE32_NAME) "\r\n");
|
||||
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DURATION_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
@ -83,13 +93,16 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
|
||||
|
||||
// Read optional arguments
|
||||
bool mask_user_input = true;
|
||||
PlainTokenSecretEncoding token_secret_encoding = PLAIN_TOKEN_ENCODING_BASE32;
|
||||
while(args_read_string_and_trim(args, temp_str)) {
|
||||
bool parsed = false;
|
||||
if(!totp_cli_try_read_algo(token_info, temp_str, args, &parsed) &&
|
||||
!totp_cli_try_read_digits(token_info, temp_str, args, &parsed) &&
|
||||
!totp_cli_try_read_duration(token_info, temp_str, args, &parsed) &&
|
||||
!totp_cli_try_read_unsecure_flag(temp_str, &parsed, &mask_user_input) &&
|
||||
!totp_cli_try_read_automation_features(token_info, temp_str, args, &parsed)) {
|
||||
!totp_cli_try_read_automation_features(token_info, temp_str, args, &parsed) &&
|
||||
!totp_cli_try_read_plain_token_secret_encoding(
|
||||
temp_str, args, &parsed, &token_secret_encoding)) {
|
||||
totp_cli_printf_unknown_argument(temp_str);
|
||||
}
|
||||
|
||||
@ -115,31 +128,34 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
|
||||
|
||||
TOTP_CLI_DELETE_LAST_LINE();
|
||||
|
||||
if(!token_info_set_secret(
|
||||
token_info,
|
||||
furi_string_get_cstr(temp_str),
|
||||
furi_string_size(temp_str),
|
||||
plugin_state->iv)) {
|
||||
TOTP_CLI_PRINTF_ERROR("Token secret seems to be invalid and can not be parsed\r\n");
|
||||
furi_string_secure_free(temp_str);
|
||||
token_info_free(token_info);
|
||||
return;
|
||||
}
|
||||
|
||||
furi_string_secure_free(temp_str);
|
||||
|
||||
bool load_generate_token_scene = false;
|
||||
if(plugin_state->current_scene == TotpSceneGenerateToken) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
|
||||
load_generate_token_scene = true;
|
||||
}
|
||||
|
||||
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, token_info, furi_check);
|
||||
plugin_state->tokens_count++;
|
||||
if(totp_config_file_save_new_token(token_info) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF_SUCCESS("Token \"%s\" has been successfully added\r\n", token_info->name);
|
||||
bool secret_set = token_info_set_secret(
|
||||
token_info,
|
||||
furi_string_get_cstr(temp_str),
|
||||
furi_string_size(temp_str),
|
||||
token_secret_encoding,
|
||||
plugin_state->iv);
|
||||
|
||||
furi_string_secure_free(temp_str);
|
||||
|
||||
if(secret_set) {
|
||||
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, token_info, furi_check);
|
||||
plugin_state->tokens_count++;
|
||||
|
||||
if(totp_config_file_save_new_token(token_info) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF_SUCCESS(
|
||||
"Token \"%s\" has been successfully added\r\n", token_info->name);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
token_info_free(token_info);
|
||||
TOTP_CLI_PRINTF_ERROR("Token secret seems to be invalid and can not be parsed\r\n");
|
||||
}
|
||||
|
||||
if(load_generate_token_scene) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <lib/toolbox/args.h>
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../cli_helpers.h"
|
||||
#include "../../../ui/scene_director.h"
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "details.h"
|
||||
#include <stdlib.h>
|
||||
#include <lib/toolbox/args.h>
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../services/config/constants.h"
|
||||
#include "../../cli_helpers.h"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "list.h"
|
||||
#include <stdlib.h>
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../services/config/constants.h"
|
||||
#include "../../cli_helpers.h"
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <lib/toolbox/args.h>
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../cli_helpers.h"
|
||||
|
@ -2,11 +2,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <lib/toolbox/args.h>
|
||||
#include <linked_list.h>
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../types/user_pin_codes.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../cli_helpers.h"
|
||||
#include "../../../lib/polyfills/memset_s.h"
|
||||
#include <memset_s.h>
|
||||
#include "../../../services/crypto/crypto.h"
|
||||
#include "../../../ui/scene_director.h"
|
||||
|
||||
|
@ -35,7 +35,7 @@ void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* arg
|
||||
if(*strtof_endptr == 0 && tz >= -12.75f && tz <= 12.75f) {
|
||||
plugin_state->timezone_offset = tz;
|
||||
if(totp_config_file_update_timezone_offset(tz) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF_SUCCESS("Timezone is set to %f\r\n", tz);
|
||||
TOTP_CLI_PRINTF_SUCCESS("Timezone is set to %f\r\n", (double)tz);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
}
|
||||
@ -50,7 +50,8 @@ void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* arg
|
||||
TOTP_CLI_PRINTF_ERROR("Invalid timezone offset\r\n");
|
||||
}
|
||||
} else {
|
||||
TOTP_CLI_PRINTF_INFO("Current timezone offset is %f\r\n", plugin_state->timezone_offset);
|
||||
TOTP_CLI_PRINTF_INFO(
|
||||
"Current timezone offset is %f\r\n", (double)plugin_state->timezone_offset);
|
||||
}
|
||||
furi_string_free(temp_str);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#include "update.h"
|
||||
#include <stdlib.h>
|
||||
#include <lib/toolbox/args.h>
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../../services/convert/convert.h"
|
||||
@ -18,17 +18,20 @@ void totp_cli_command_update_docopt_commands() {
|
||||
void totp_cli_command_update_docopt_usage() {
|
||||
TOTP_CLI_PRINTF(
|
||||
" " TOTP_CLI_COMMAND_NAME
|
||||
" " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_UPDATE) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_INDEX) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_ALGO))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_NAME_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_NAME))) " " DOCOPT_OPTIONAL(
|
||||
" " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_UPDATE) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_INDEX) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_ALGO))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_SECRET_ENCODING))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_NAME_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_NAME))) " " DOCOPT_OPTIONAL(
|
||||
DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS_PREFIX,
|
||||
DOCOPT_ARGUMENT(
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_DURATION_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_DURATION))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ARG_UNSECURE_PREFIX)) " " DOCOPT_MULTIPLE(DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)))) "\r\n");
|
||||
TOTP_CLI_COMMAND_ARG_DIGITS))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_DURATION_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_DURATION))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ARG_UNSECURE_PREFIX)) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_UPDATE_ARG_SECRET_PREFIX)) " " DOCOPT_MULTIPLE(DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE)))) "\r\n");
|
||||
}
|
||||
|
||||
void totp_cli_command_update_docopt_options() {
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||
TOTP_CLI_COMMAND_ARG_NAME_PREFIX,
|
||||
DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ARG_NAME)) " Token name\r\n");
|
||||
|
||||
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(
|
||||
TOTP_CLI_COMMAND_UPDATE_ARG_SECRET_PREFIX) " Update token secret\r\n");
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -85,6 +88,7 @@ void totp_cli_command_update_handle(PluginState* plugin_state, FuriString* args,
|
||||
// Read optional arguments
|
||||
bool mask_user_input = true;
|
||||
bool update_token_secret = false;
|
||||
PlainTokenSecretEncoding token_secret_encoding = PLAIN_TOKEN_ENCODING_BASE32;
|
||||
while(args_read_string_and_trim(args, temp_str)) {
|
||||
bool parsed = false;
|
||||
if(!totp_cli_try_read_name(token_info, temp_str, args, &parsed) &&
|
||||
@ -93,7 +97,9 @@ void totp_cli_command_update_handle(PluginState* plugin_state, FuriString* args,
|
||||
!totp_cli_try_read_duration(token_info, temp_str, args, &parsed) &&
|
||||
!totp_cli_try_read_unsecure_flag(temp_str, &parsed, &mask_user_input) &&
|
||||
!totp_cli_try_read_change_secret_flag(temp_str, &parsed, &update_token_secret) &&
|
||||
!totp_cli_try_read_automation_features(token_info, temp_str, args, &parsed)) {
|
||||
!totp_cli_try_read_automation_features(token_info, temp_str, args, &parsed) &&
|
||||
!totp_cli_try_read_plain_token_secret_encoding(
|
||||
temp_str, args, &parsed, &token_secret_encoding)) {
|
||||
totp_cli_printf_unknown_argument(temp_str);
|
||||
}
|
||||
|
||||
@ -105,54 +111,55 @@ void totp_cli_command_update_handle(PluginState* plugin_state, FuriString* args,
|
||||
}
|
||||
}
|
||||
|
||||
bool token_secret_read = false;
|
||||
if(update_token_secret) {
|
||||
// Reading token secret
|
||||
furi_string_reset(temp_str);
|
||||
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n");
|
||||
if(!totp_cli_read_line(cli, temp_str, mask_user_input) ||
|
||||
!totp_cli_ensure_authenticated(plugin_state, cli)) {
|
||||
TOTP_CLI_DELETE_LAST_LINE();
|
||||
TOTP_CLI_PRINTF_INFO("Cancelled by user\r\n");
|
||||
furi_string_secure_free(temp_str);
|
||||
token_info_free(token_info);
|
||||
return;
|
||||
}
|
||||
|
||||
token_secret_read = totp_cli_read_line(cli, temp_str, mask_user_input);
|
||||
TOTP_CLI_DELETE_LAST_LINE();
|
||||
|
||||
if(token_info->token != NULL) {
|
||||
free(token_info->token);
|
||||
}
|
||||
|
||||
if(!token_info_set_secret(
|
||||
token_info,
|
||||
furi_string_get_cstr(temp_str),
|
||||
furi_string_size(temp_str),
|
||||
plugin_state->iv)) {
|
||||
TOTP_CLI_PRINTF_ERROR("Token secret seems to be invalid and can not be parsed\r\n");
|
||||
furi_string_secure_free(temp_str);
|
||||
token_info_free(token_info);
|
||||
return;
|
||||
if(!token_secret_read) {
|
||||
TOTP_CLI_PRINTF_INFO("Cancelled by user\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
furi_string_secure_free(temp_str);
|
||||
|
||||
bool load_generate_token_scene = false;
|
||||
if(plugin_state->current_scene == TotpSceneGenerateToken) {
|
||||
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
|
||||
load_generate_token_scene = true;
|
||||
}
|
||||
|
||||
list_item->data = token_info;
|
||||
bool token_secret_set = false;
|
||||
if(update_token_secret && token_secret_read) {
|
||||
if(token_info->token != NULL) {
|
||||
free(token_info->token);
|
||||
}
|
||||
token_secret_set = token_info_set_secret(
|
||||
token_info,
|
||||
furi_string_get_cstr(temp_str),
|
||||
furi_string_size(temp_str),
|
||||
token_secret_encoding,
|
||||
plugin_state->iv);
|
||||
if(!token_secret_set) {
|
||||
TOTP_CLI_PRINTF_ERROR("Token secret seems to be invalid and can not be parsed\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF_SUCCESS(
|
||||
"Token \"%s\" has been successfully updated\r\n", token_info->name);
|
||||
token_info_free(existing_token_info);
|
||||
furi_string_secure_free(temp_str);
|
||||
|
||||
if(!update_token_secret || (token_secret_read && token_secret_set)) {
|
||||
list_item->data = token_info;
|
||||
|
||||
if(totp_full_save_config_file(plugin_state) == TotpConfigFileUpdateSuccess) {
|
||||
TOTP_CLI_PRINTF_SUCCESS(
|
||||
"Token \"%s\" has been successfully updated\r\n", token_info->name);
|
||||
token_info_free(existing_token_info);
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
list_item->data = existing_token_info;
|
||||
token_info_free(token_info);
|
||||
}
|
||||
} else {
|
||||
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
|
||||
list_item->data = existing_token_info;
|
||||
token_info_free(token_info);
|
||||
}
|
||||
|
||||
|
@ -108,5 +108,34 @@ bool totp_cli_try_read_unsecure_flag(const FuriString* arg, bool* parsed, bool*
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool totp_cli_try_read_plain_token_secret_encoding(
|
||||
FuriString* arg,
|
||||
FuriString* args,
|
||||
bool* parsed,
|
||||
PlainTokenSecretEncoding* secret_encoding) {
|
||||
if(furi_string_cmpi_str(arg, TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX) == 0) {
|
||||
if(!args_read_string_and_trim(args, arg)) {
|
||||
totp_cli_printf_missed_argument_value(TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX);
|
||||
} else {
|
||||
if(furi_string_cmpi_str(arg, PLAIN_TOKEN_ENCODING_BASE32_NAME) == 0) {
|
||||
*secret_encoding = PLAIN_TOKEN_ENCODING_BASE32;
|
||||
*parsed = true;
|
||||
} else if(furi_string_cmpi_str(arg, PLAIN_TOKEN_ENCODING_BASE64_NAME) == 0) {
|
||||
*secret_encoding = PLAIN_TOKEN_ENCODING_BASE64;
|
||||
*parsed = true;
|
||||
} else {
|
||||
TOTP_CLI_PRINTF_ERROR(
|
||||
"\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX
|
||||
"\"\r\n",
|
||||
furi_string_get_cstr(arg));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
#define TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE_PREFIX "-b"
|
||||
#define TOTP_CLI_COMMAND_ARG_AUTOMATION_FEATURE "feature"
|
||||
#define TOTP_CLI_COMMAND_ARG_INDEX "index"
|
||||
#define TOTP_CLI_COMMAND_ARG_SECRET_ENCODING_PREFIX "-e"
|
||||
#define TOTP_CLI_COMMAND_ARG_SECRET_ENCODING "encoding"
|
||||
|
||||
void totp_cli_printf_unknown_argument(const FuriString* arg);
|
||||
void totp_cli_printf_missed_argument_value(char* arg);
|
||||
@ -34,4 +36,10 @@ bool totp_cli_try_read_automation_features(
|
||||
FuriString* arg,
|
||||
FuriString* args,
|
||||
bool* parsed);
|
||||
bool totp_cli_try_read_unsecure_flag(const FuriString* arg, bool* parsed, bool* unsecure_flag);
|
||||
bool totp_cli_try_read_unsecure_flag(const FuriString* arg, bool* parsed, bool* unsecure_flag);
|
||||
|
||||
bool totp_cli_try_read_plain_token_secret_encoding(
|
||||
FuriString* arg,
|
||||
FuriString* args,
|
||||
bool* parsed,
|
||||
PlainTokenSecretEncoding* secret_encoding);
|
14
applications/external/totp/features_config.h
vendored
14
applications/external/totp/features_config.h
vendored
@ -1,2 +1,14 @@
|
||||
// Include Bluetooth token input automation
|
||||
#define TOTP_BADBT_TYPE_ENABLED
|
||||
#define TOTP_AUTOMATION_ICONS_ENABLED
|
||||
|
||||
// Include token input automation icons on the main screen
|
||||
#define TOTP_AUTOMATION_ICONS_ENABLED
|
||||
|
||||
// List of compatible firmwares
|
||||
#define TOTP_FIRMWARE_OFFICIAL_STABLE 1
|
||||
#define TOTP_FIRMWARE_OFFICIAL_DEV 2
|
||||
#define TOTP_FIRMWARE_XTREME 3
|
||||
// End of list
|
||||
|
||||
// Target firmware to build for
|
||||
#define TOTP_TARGET_FIRMWARE TOTP_FIRMWARE_OFFICIAL_DEV
|
@ -17,10 +17,10 @@
|
||||
|
||||
#include "base32.h"
|
||||
|
||||
int base32_decode(const uint8_t* encoded, uint8_t* result, int bufSize) {
|
||||
size_t base32_decode(const uint8_t* encoded, uint8_t* result, size_t bufSize) {
|
||||
int buffer = 0;
|
||||
int bitsLeft = 0;
|
||||
int count = 0;
|
||||
size_t count = 0;
|
||||
for(const uint8_t* ptr = encoded; count < bufSize && *ptr; ++ptr) {
|
||||
uint8_t ch = *ptr;
|
||||
if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') {
|
||||
@ -43,7 +43,7 @@ int base32_decode(const uint8_t* encoded, uint8_t* result, int bufSize) {
|
||||
} else if(ch >= '2' && ch <= '7') {
|
||||
ch -= '2' - 26;
|
||||
} else {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer |= ch;
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
@ -34,6 +35,6 @@
|
||||
* @param encoded Base-32 encoded bytes
|
||||
* @param[out] result result output buffer
|
||||
* @param bufSize result output buffer size
|
||||
* @return Decoded result length in bytes if successfully decoded; \c -1 otherwise
|
||||
* @return Decoded result length in bytes if successfully decoded; \c 0 otherwise
|
||||
*/
|
||||
int base32_decode(const uint8_t* encoded, uint8_t* result, int bufSize);
|
||||
size_t base32_decode(const uint8_t* encoded, uint8_t* result, size_t bufSize);
|
||||
|
72
applications/external/totp/lib/base64/base64.c
vendored
Normal file
72
applications/external/totp/lib/base64/base64.c
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Base64 encoding/decoding (RFC1341)
|
||||
* Copyright (c) 2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base64.h"
|
||||
#include <string.h>
|
||||
|
||||
static const uint8_t dtable[] = {0x3e, 0x80, 0x80, 0x80, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||
0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x80, 0x80, 0x80, 0x0, 0x80,
|
||||
0x80, 0x80, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
|
||||
0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11,
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
|
||||
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33};
|
||||
// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static uint8_t get_dtable_value(uint8_t index) {
|
||||
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 *out;
|
||||
uint8_t *pos;
|
||||
uint8_t in[4];
|
||||
uint8_t block[4];
|
||||
uint8_t tmp;
|
||||
size_t i;
|
||||
size_t count;
|
||||
size_t olen;
|
||||
|
||||
count = 0;
|
||||
for(i = 0; i < len; i++) {
|
||||
if(get_dtable_value(src[i]) != 0x80) count++;
|
||||
}
|
||||
|
||||
if(count == 0 || count % 4) return NULL;
|
||||
olen = count / 4 * 3;
|
||||
pos = out = malloc(olen);
|
||||
*out_size = olen;
|
||||
if(out == NULL) return NULL;
|
||||
count = 0;
|
||||
for(i = 0; i < len; i++) {
|
||||
tmp = get_dtable_value(src[i]);
|
||||
if(tmp == 0x80) continue;
|
||||
in[count] = src[i];
|
||||
block[count] = tmp;
|
||||
count++;
|
||||
if(count == 4) {
|
||||
*pos++ = (block[0] << 2) | (block[1] >> 4);
|
||||
*pos++ = (block[1] << 4) | (block[2] >> 2);
|
||||
*pos++ = (block[2] << 6) | block[3];
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
if(pos > out) {
|
||||
if(in[2] == '=')
|
||||
pos -= 2;
|
||||
else if(in[3] == '=')
|
||||
pos--;
|
||||
}
|
||||
*out_len = pos - out;
|
||||
return out;
|
||||
}
|
14
applications/external/totp/lib/base64/base64.h
vendored
Normal file
14
applications/external/totp/lib/base64/base64.h
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Decodes Base-64 encoded bytes into plain bytes.
|
||||
* @param src Base-64 encoded bytes
|
||||
* @param len Base-64 encoded bytes count
|
||||
* @param[out] out_len decoded buffer length
|
||||
* @param[out] out_size decoded buffer allocated size
|
||||
* @return Decoded result buffer if successfully decoded; \c NULL otherwise
|
||||
*/
|
||||
uint8_t* base64_decode(const uint8_t* src, size_t len, size_t* out_len, size_t* out_size);
|
@ -1,4 +1,4 @@
|
||||
#include "list.h"
|
||||
#include "linked_list.h"
|
||||
|
||||
ListNode* list_init_head(void* data) {
|
||||
ListNode* new = malloc(sizeof(ListNode));
|
@ -84,19 +84,15 @@ ListNode* list_insert_at(ListNode* head, uint16_t index, void* data);
|
||||
void list_free(ListNode* head);
|
||||
|
||||
#define TOTP_LIST_INIT_OR_ADD(head, item, assert) \
|
||||
do { \
|
||||
if(head == NULL) { \
|
||||
head = list_init_head(item); \
|
||||
assert(head != NULL); \
|
||||
} else { \
|
||||
assert(list_add(head, item) != NULL); \
|
||||
} \
|
||||
} while(false)
|
||||
if(head == NULL) { \
|
||||
head = list_init_head(item); \
|
||||
assert(head != NULL); \
|
||||
} else { \
|
||||
assert(list_add(head, item) != NULL); \
|
||||
}
|
||||
|
||||
#define TOTP_LIST_FOREACH(head, node, action) \
|
||||
do { \
|
||||
ListNode* node = head; \
|
||||
while(node != NULL) { \
|
||||
action node = node->next; \
|
||||
} \
|
||||
} while(false)
|
||||
ListNode* node = head; \
|
||||
while(node != NULL) { \
|
||||
action node = node->next; \
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../types/common.h"
|
||||
#include "../../types/token_info.h"
|
||||
#include "../../features_config.h"
|
||||
@ -139,10 +139,11 @@ static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperF
|
||||
|
||||
furi_string_printf(
|
||||
temp_str,
|
||||
" # Token hashing algorithm to use during code generation. Supported options are %s, %s and %s. If you are not use which one to use - use %s",
|
||||
" # Token hashing algorithm to use during code generation. Supported options are %s, %s, %s, and %s. If you are not use which one to use - use %s",
|
||||
TOTP_TOKEN_ALGO_SHA1_NAME,
|
||||
TOTP_TOKEN_ALGO_SHA256_NAME,
|
||||
TOTP_TOKEN_ALGO_SHA512_NAME,
|
||||
TOTP_TOKEN_ALGO_STEAM_NAME,
|
||||
TOTP_TOKEN_ALGO_SHA1_NAME);
|
||||
flipper_format_write_comment(fff_data_file, temp_str);
|
||||
furi_string_printf(
|
||||
@ -152,7 +153,7 @@ static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperF
|
||||
|
||||
flipper_format_write_comment_cstr(
|
||||
fff_data_file,
|
||||
"# How many digits there should be in generated code. Available options are 6 and 8. Majority websites requires 6 digits code, however some rare websites wants to get 8 digits code. If you are not sure which one to use - use 6");
|
||||
"# How many digits there should be in generated code. Available options are 5, 6 and 8. Majority websites requires 6 digits code, however some rare websites wants to get 8 digits code. If you are not sure which one to use - use 6");
|
||||
furi_string_printf(temp_str, "%s: 6", TOTP_CONFIG_KEY_TOKEN_DIGITS);
|
||||
flipper_format_write_comment(fff_data_file, temp_str);
|
||||
flipper_format_write_comment_cstr(fff_data_file, " ");
|
||||
@ -686,6 +687,7 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state)
|
||||
tokenInfo,
|
||||
furi_string_get_cstr(temp_str),
|
||||
furi_string_size(temp_str),
|
||||
PLAIN_TOKEN_ENCODING_BASE32,
|
||||
&plugin_state->iv[0])) {
|
||||
FURI_LOG_W(LOGGING_TAG, "Token \"%s\" has plain secret", tokenInfo->name);
|
||||
} else {
|
||||
|
@ -26,12 +26,9 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define SWAP(n) (n)
|
||||
#else
|
||||
#include "byteswap.h"
|
||||
|
||||
#define SWAP(n) swap_uint64(n)
|
||||
#endif
|
||||
|
||||
/* This array contains the bytes used to pad the buffer to the next
|
||||
128-byte boundary. */
|
||||
|
18
applications/external/totp/services/totp/totp.c
vendored
18
applications/external/totp/services/totp/totp.c
vendored
@ -11,7 +11,7 @@
|
||||
#include "../hmac/byteswap.h"
|
||||
#include "../../lib/timezone_utils/timezone_utils.h"
|
||||
|
||||
#define HMAC_MAX_SIZE 64
|
||||
#define HMAC_MAX_RESULT_SIZE HMAC_SHA512_RESULT_SIZE
|
||||
|
||||
/**
|
||||
* @brief Generates the timeblock for a time in seconds.
|
||||
@ -29,19 +29,17 @@ uint64_t totp_timecode(uint8_t interval, uint64_t for_time) {
|
||||
/**
|
||||
* @brief Generates an OTP (One Time Password)
|
||||
* @param algo hashing algorithm to be used
|
||||
* @param digits desired TOTP code length
|
||||
* @param plain_secret plain token secret
|
||||
* @param plain_secret_length plain token secret length
|
||||
* @param input input data for OTP code generation
|
||||
* @return OTP code if code was successfully generated; 0 otherwise
|
||||
*/
|
||||
uint32_t otp_generate(
|
||||
uint64_t otp_generate(
|
||||
TOTP_ALGO algo,
|
||||
uint8_t digits,
|
||||
const uint8_t* plain_secret,
|
||||
size_t plain_secret_length,
|
||||
uint64_t input) {
|
||||
uint8_t hmac[HMAC_MAX_SIZE] = {0};
|
||||
uint8_t hmac[HMAC_MAX_RESULT_SIZE] = {0};
|
||||
|
||||
uint64_t input_swapped = swap_uint64(input);
|
||||
|
||||
@ -55,14 +53,12 @@ uint32_t otp_generate(
|
||||
uint64_t i_code =
|
||||
((hmac[offset] & 0x7F) << 24 | (hmac[offset + 1] & 0xFF) << 16 |
|
||||
(hmac[offset + 2] & 0xFF) << 8 | (hmac[offset + 3] & 0xFF));
|
||||
i_code %= (uint64_t)pow(10, digits);
|
||||
|
||||
return i_code;
|
||||
}
|
||||
|
||||
uint32_t totp_at(
|
||||
uint64_t totp_at(
|
||||
TOTP_ALGO algo,
|
||||
uint8_t digits,
|
||||
const uint8_t* plain_secret,
|
||||
size_t plain_secret_length,
|
||||
uint64_t for_time,
|
||||
@ -71,11 +67,7 @@ uint32_t totp_at(
|
||||
uint64_t for_time_adjusted =
|
||||
timezone_offset_apply(for_time, timezone_offset_from_hours(timezone));
|
||||
return otp_generate(
|
||||
algo,
|
||||
digits,
|
||||
plain_secret,
|
||||
plain_secret_length,
|
||||
totp_timecode(interval, for_time_adjusted));
|
||||
algo, plain_secret, plain_secret_length, totp_timecode(interval, for_time_adjusted));
|
||||
}
|
||||
|
||||
static int totp_algo_sha1(
|
||||
|
@ -39,7 +39,6 @@ extern const TOTP_ALGO TOTP_ALGO_SHA512;
|
||||
/**
|
||||
* @brief Generates a OTP key using the totp algorithm.
|
||||
* @param algo hashing algorithm to be used
|
||||
* @param digits desired TOTP code length
|
||||
* @param plain_secret plain token secret
|
||||
* @param plain_secret_length plain token secret length
|
||||
* @param for_time the time the generated key will be created for
|
||||
@ -47,9 +46,8 @@ extern const TOTP_ALGO TOTP_ALGO_SHA512;
|
||||
* @param interval token lifetime in seconds
|
||||
* @return TOTP code if code was successfully generated; 0 otherwise
|
||||
*/
|
||||
uint32_t totp_at(
|
||||
uint64_t totp_at(
|
||||
TOTP_ALGO algo,
|
||||
uint8_t digits,
|
||||
const uint8_t* plain_secret,
|
||||
size_t plain_secret_length,
|
||||
uint64_t for_time,
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <gui/gui.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
#include "../features_config.h"
|
||||
#include "../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../ui/totp_scenes_enum.h"
|
||||
#include "notification_method.h"
|
||||
#include "automation_method.h"
|
||||
|
49
applications/external/totp/types/token_info.c
vendored
49
applications/external/totp/types/token_info.c
vendored
@ -1,11 +1,11 @@
|
||||
#include <furi_hal.h>
|
||||
#include "token_info.h"
|
||||
#include "stdlib.h"
|
||||
#include <furi_hal.h>
|
||||
#include <base32.h>
|
||||
#include <base64.h>
|
||||
#include <memset_s.h>
|
||||
#include <strnlen.h>
|
||||
#include "common.h"
|
||||
#include "../lib/base32/base32.h"
|
||||
#include "../services/crypto/crypto.h"
|
||||
#include "../lib/polyfills/memset_s.h"
|
||||
#include "../lib/polyfills/strnlen.h"
|
||||
|
||||
TokenInfo* token_info_alloc() {
|
||||
TokenInfo* tokenInfo = malloc(sizeof(TokenInfo));
|
||||
@ -26,15 +26,32 @@ void token_info_free(TokenInfo* token_info) {
|
||||
|
||||
bool token_info_set_secret(
|
||||
TokenInfo* token_info,
|
||||
const char* base32_token_secret,
|
||||
const char* plain_token_secret,
|
||||
size_t token_secret_length,
|
||||
PlainTokenSecretEncoding plain_token_secret_encoding,
|
||||
const uint8_t* iv) {
|
||||
if(token_secret_length == 0) return false;
|
||||
uint8_t* plain_secret;
|
||||
size_t plain_secret_length;
|
||||
size_t plain_secret_size;
|
||||
if(plain_token_secret_encoding == PLAIN_TOKEN_ENCODING_BASE32) {
|
||||
plain_secret_size = token_secret_length;
|
||||
plain_secret = malloc(plain_secret_size);
|
||||
furi_check(plain_secret != NULL);
|
||||
plain_secret_length =
|
||||
base32_decode((const uint8_t*)plain_token_secret, plain_secret, plain_secret_size);
|
||||
} else if(plain_token_secret_encoding == PLAIN_TOKEN_ENCODING_BASE64) {
|
||||
plain_secret_length = 0;
|
||||
plain_secret = base64_decode(
|
||||
(const uint8_t*)plain_token_secret,
|
||||
token_secret_length,
|
||||
&plain_secret_length,
|
||||
&plain_secret_size);
|
||||
furi_check(plain_secret != NULL);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* plain_secret = malloc(token_secret_length);
|
||||
furi_check(plain_secret != NULL);
|
||||
int plain_secret_length =
|
||||
base32_decode((const uint8_t*)base32_token_secret, plain_secret, token_secret_length);
|
||||
bool result;
|
||||
if(plain_secret_length > 0) {
|
||||
token_info->token =
|
||||
@ -44,13 +61,16 @@ bool token_info_set_secret(
|
||||
result = false;
|
||||
}
|
||||
|
||||
memset_s(plain_secret, token_secret_length, 0, token_secret_length);
|
||||
memset_s(plain_secret, plain_secret_size, 0, plain_secret_size);
|
||||
free(plain_secret);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) {
|
||||
switch(digits) {
|
||||
case 5:
|
||||
token_info->digits = TOTP_5_DIGITS;
|
||||
return true;
|
||||
case 6:
|
||||
token_info->digits = TOTP_6_DIGITS;
|
||||
return true;
|
||||
@ -89,6 +109,11 @@ bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str)
|
||||
return true;
|
||||
}
|
||||
|
||||
if(furi_string_cmpi_str(str, TOTP_TOKEN_ALGO_STEAM_NAME) == 0) {
|
||||
token_info->algo = STEAM;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -100,6 +125,8 @@ char* token_info_get_algo_as_cstr(const TokenInfo* token_info) {
|
||||
return TOTP_TOKEN_ALGO_SHA256_NAME;
|
||||
case SHA512:
|
||||
return TOTP_TOKEN_ALGO_SHA512_NAME;
|
||||
case STEAM:
|
||||
return TOTP_TOKEN_ALGO_STEAM_NAME;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
26
applications/external/totp/types/token_info.h
vendored
26
applications/external/totp/types/token_info.h
vendored
@ -7,10 +7,14 @@
|
||||
#define TOTP_TOKEN_DURATION_DEFAULT 30
|
||||
|
||||
#define TOTP_TOKEN_ALGO_SHA1_NAME "sha1"
|
||||
#define TOTP_TOKEN_ALGO_STEAM_NAME "steam"
|
||||
#define TOTP_TOKEN_ALGO_SHA256_NAME "sha256"
|
||||
#define TOTP_TOKEN_ALGO_SHA512_NAME "sha512"
|
||||
#define TOTP_TOKEN_MAX_LENGTH 255
|
||||
|
||||
#define PLAIN_TOKEN_ENCODING_BASE32_NAME "base32"
|
||||
#define PLAIN_TOKEN_ENCODING_BASE64_NAME "base64"
|
||||
|
||||
#define TOTP_TOKEN_AUTOMATION_FEATURE_NONE_NAME "none"
|
||||
#define TOTP_TOKEN_AUTOMATION_FEATURE_ENTER_AT_THE_END_NAME "enter"
|
||||
#define TOTP_TOKEN_AUTOMATION_FEATURE_TAB_AT_THE_END_NAME "tab"
|
||||
@ -19,6 +23,7 @@
|
||||
typedef uint8_t TokenHashAlgo;
|
||||
typedef uint8_t TokenDigitsCount;
|
||||
typedef uint8_t TokenAutomationFeature;
|
||||
typedef uint8_t PlainTokenSecretEncoding;
|
||||
|
||||
/**
|
||||
* @brief Hashing algorithm to be used to generate token
|
||||
@ -37,13 +42,23 @@ enum TokenHashAlgos {
|
||||
/**
|
||||
* @brief SHA512 hashing algorithm
|
||||
*/
|
||||
SHA512
|
||||
SHA512,
|
||||
|
||||
/**
|
||||
* @brief Algorithm used by Steam (Valve)
|
||||
*/
|
||||
STEAM
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Token digits count to be generated.
|
||||
*/
|
||||
enum TokenDigitsCounts {
|
||||
/**
|
||||
* @brief 6 digits
|
||||
*/
|
||||
TOTP_5_DIGITS = 5,
|
||||
|
||||
/**
|
||||
* @brief 6 digits
|
||||
*/
|
||||
@ -80,6 +95,11 @@ enum TokenAutomationFeatures {
|
||||
TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER = 0b100
|
||||
};
|
||||
|
||||
enum PlainTokenSecretEncodings {
|
||||
PLAIN_TOKEN_ENCODING_BASE32 = 0,
|
||||
PLAIN_TOKEN_ENCODING_BASE64 = 1
|
||||
};
|
||||
|
||||
#define TOTP_TOKEN_DIGITS_MAX_COUNT 8
|
||||
|
||||
/**
|
||||
@ -139,13 +159,15 @@ void token_info_free(TokenInfo* token_info);
|
||||
* @param token_info instance where secret should be updated
|
||||
* @param base32_token_secret plain token secret in Base32 format
|
||||
* @param token_secret_length plain token secret length
|
||||
* @param plain_token_secret_encoding plain token secret encoding
|
||||
* @param iv initialization vecor (IV) to be used for encryption
|
||||
* @return \c true if token successfully set; \c false otherwise
|
||||
*/
|
||||
bool token_info_set_secret(
|
||||
TokenInfo* token_info,
|
||||
const char* base32_token_secret,
|
||||
const char* plain_token_secret,
|
||||
size_t token_secret_length,
|
||||
PlainTokenSecretEncoding plain_token_secret_encoding,
|
||||
const uint8_t* iv);
|
||||
|
||||
/**
|
||||
|
24
applications/external/totp/ui/fonts/font_info.h
vendored
Normal file
24
applications/external/totp/ui/fonts/font_info.h
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
/* GENERATED BY https://github.com/pavius/the-dot-factory */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// This structure describes a single character's display information
|
||||
typedef struct {
|
||||
const uint8_t width; // width, in bits (or pixels), of the character
|
||||
const uint16_t
|
||||
offset; // offset of the character's bitmap, in bytes, into the the FONT_INFO's data array
|
||||
|
||||
} FONT_CHAR_INFO;
|
||||
|
||||
// Describes a single font
|
||||
typedef struct {
|
||||
const uint8_t height; // height, in pages (8 pixels), of the font's characters
|
||||
const uint8_t startChar; // the first character in the font (e.g. in charInfo and data)
|
||||
const uint8_t endChar; // the last character in the font
|
||||
const uint8_t spacePixels; // number of pixels that a space character takes up
|
||||
const FONT_CHAR_INFO* charInfo; // pointer to array of char information
|
||||
const uint8_t* data; // pointer to generated array of character visual representation
|
||||
|
||||
} FONT_INFO;
|
940
applications/external/totp/ui/fonts/mode-nine/mode_nine.c
vendored
Normal file
940
applications/external/totp/ui/fonts/mode-nine/mode_nine.c
vendored
Normal file
@ -0,0 +1,940 @@
|
||||
#include "mode_nine.h"
|
||||
|
||||
/* GENERATED BY https://github.com/pavius/the-dot-factory */
|
||||
|
||||
/*
|
||||
** Font data for ModeNine 15pt
|
||||
*/
|
||||
|
||||
/* Character bitmaps for ModeNine 15pt */
|
||||
const uint8_t modeNine_15ptBitmaps[] = {
|
||||
/* @0 '-' (10 pixels wide) */
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
/* @28 '0' (10 pixels wide) */
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @56 '1' (10 pixels wide) */
|
||||
0x30,
|
||||
0x00,
|
||||
0x38,
|
||||
0x00,
|
||||
0x3C,
|
||||
0x00,
|
||||
0x3C,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @84 '2' (10 pixels wide) */
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x80,
|
||||
0x03,
|
||||
0xFC,
|
||||
0x01,
|
||||
0xFE,
|
||||
0x00,
|
||||
0x07,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
|
||||
/* @112 '3' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x80,
|
||||
0x03,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xE0,
|
||||
0x00,
|
||||
0x70,
|
||||
0x00,
|
||||
0xF8,
|
||||
0x00,
|
||||
0xFC,
|
||||
0x01,
|
||||
0x80,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @140 '4' (10 pixels wide) */
|
||||
0xE0,
|
||||
0x00,
|
||||
0xF0,
|
||||
0x00,
|
||||
0xF8,
|
||||
0x00,
|
||||
0xDC,
|
||||
0x00,
|
||||
0xCE,
|
||||
0x00,
|
||||
0xC7,
|
||||
0x00,
|
||||
0xC3,
|
||||
0x00,
|
||||
0xC3,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0xC0,
|
||||
0x00,
|
||||
0xC0,
|
||||
0x00,
|
||||
0xC0,
|
||||
0x00,
|
||||
0xC0,
|
||||
0x00,
|
||||
|
||||
/* @168 '5' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x01,
|
||||
0x80,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @196 '6' (10 pixels wide) */
|
||||
0xF0,
|
||||
0x00,
|
||||
0xFC,
|
||||
0x00,
|
||||
0x0E,
|
||||
0x00,
|
||||
0x06,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @224 '7' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x80,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xE0,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x18,
|
||||
0x00,
|
||||
0x1C,
|
||||
0x00,
|
||||
0x0C,
|
||||
0x00,
|
||||
0x0C,
|
||||
0x00,
|
||||
0x0C,
|
||||
0x00,
|
||||
0x0C,
|
||||
0x00,
|
||||
0x0C,
|
||||
0x00,
|
||||
|
||||
/* @252 '8' (10 pixels wide) */
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @280 '9' (10 pixels wide) */
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x07,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x03,
|
||||
0xFC,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x80,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
0x3C,
|
||||
0x00,
|
||||
|
||||
/* @308 'B' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x83,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x01,
|
||||
0xFF,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x83,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x01,
|
||||
0xFF,
|
||||
0x00,
|
||||
|
||||
/* @336 'C' (10 pixels wide) */
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @364 'D' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x83,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x01,
|
||||
0xFF,
|
||||
0x00,
|
||||
|
||||
/* @392 'F' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
|
||||
/* @420 'G' (10 pixels wide) */
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0xC3,
|
||||
0x03,
|
||||
0xC3,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x07,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x03,
|
||||
0xFC,
|
||||
0x03,
|
||||
|
||||
/* @448 'H' (10 pixels wide) */
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
|
||||
/* @476 'J' (10 pixels wide) */
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
|
||||
/* @504 'K' (10 pixels wide) */
|
||||
0x83,
|
||||
0x03,
|
||||
0xC3,
|
||||
0x01,
|
||||
0xE3,
|
||||
0x00,
|
||||
0x73,
|
||||
0x00,
|
||||
0x3B,
|
||||
0x00,
|
||||
0x1F,
|
||||
0x00,
|
||||
0x0F,
|
||||
0x00,
|
||||
0x0F,
|
||||
0x00,
|
||||
0x1F,
|
||||
0x00,
|
||||
0x3B,
|
||||
0x00,
|
||||
0x73,
|
||||
0x00,
|
||||
0xE3,
|
||||
0x00,
|
||||
0xC3,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
|
||||
/* @532 'M' (10 pixels wide) */
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xCF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x7B,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
|
||||
/* @560 'N' (10 pixels wide) */
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x07,
|
||||
0x03,
|
||||
0x0F,
|
||||
0x03,
|
||||
0x1F,
|
||||
0x03,
|
||||
0x3B,
|
||||
0x03,
|
||||
0x73,
|
||||
0x03,
|
||||
0xE3,
|
||||
0x03,
|
||||
0xC3,
|
||||
0x03,
|
||||
0x83,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
|
||||
/* @588 'P' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x83,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x01,
|
||||
0xFF,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
0x03,
|
||||
0x00,
|
||||
|
||||
/* @616 'Q' (10 pixels wide) */
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x73,
|
||||
0x03,
|
||||
0xE7,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x03,
|
||||
|
||||
/* @644 'R' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x00,
|
||||
0xFF,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x83,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x01,
|
||||
0xFF,
|
||||
0x00,
|
||||
0x1F,
|
||||
0x00,
|
||||
0x3B,
|
||||
0x00,
|
||||
0x73,
|
||||
0x00,
|
||||
0xE3,
|
||||
0x00,
|
||||
0xC3,
|
||||
0x01,
|
||||
0x83,
|
||||
0x03,
|
||||
|
||||
/* @672 'T' (10 pixels wide) */
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
|
||||
/* @700 'V' (10 pixels wide) */
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x86,
|
||||
0x01,
|
||||
0x86,
|
||||
0x01,
|
||||
0xCC,
|
||||
0x00,
|
||||
0xCC,
|
||||
0x00,
|
||||
0x78,
|
||||
0x00,
|
||||
0x78,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
|
||||
/* @728 'W' (10 pixels wide) */
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0x33,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFE,
|
||||
0x01,
|
||||
|
||||
/* @756 'X' (10 pixels wide) */
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xCE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
0xFC,
|
||||
0x00,
|
||||
0xCE,
|
||||
0x01,
|
||||
0x87,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
|
||||
/* @784 'Y' (10 pixels wide) */
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x03,
|
||||
0x87,
|
||||
0x03,
|
||||
0xCE,
|
||||
0x01,
|
||||
0xFC,
|
||||
0x00,
|
||||
0x78,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
0x30,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* Character descriptors for ModeNine 15pt */
|
||||
/* { [Char width in bits], [Offset into modeNine_15ptCharBitmaps in bytes] } */
|
||||
const FONT_CHAR_INFO modeNine_15ptDescriptors[] = {
|
||||
{10, 0}, /* - */
|
||||
{0, 0}, /* . */
|
||||
{0, 0}, /* / */
|
||||
{10, 28}, /* 0 */
|
||||
{10, 56}, /* 1 */
|
||||
{10, 84}, /* 2 */
|
||||
{10, 112}, /* 3 */
|
||||
{10, 140}, /* 4 */
|
||||
{10, 168}, /* 5 */
|
||||
{10, 196}, /* 6 */
|
||||
{10, 224}, /* 7 */
|
||||
{10, 252}, /* 8 */
|
||||
{10, 280}, /* 9 */
|
||||
{0, 0}, /* : */
|
||||
{0, 0}, /* ; */
|
||||
{0, 0}, /* < */
|
||||
{0, 0}, /* = */
|
||||
{0, 0}, /* > */
|
||||
{0, 0}, /* ? */
|
||||
{0, 0}, /* @ */
|
||||
{0, 0}, /* A */
|
||||
{10, 308}, /* B */
|
||||
{10, 336}, /* C */
|
||||
{10, 364}, /* D */
|
||||
{0, 0}, /* E */
|
||||
{10, 392}, /* F */
|
||||
{10, 420}, /* G */
|
||||
{10, 448}, /* H */
|
||||
{0, 0}, /* I */
|
||||
{10, 476}, /* J */
|
||||
{10, 504}, /* K */
|
||||
{0, 0}, /* L */
|
||||
{10, 532}, /* M */
|
||||
{10, 560}, /* N */
|
||||
{0, 0}, /* O */
|
||||
{10, 588}, /* P */
|
||||
{10, 616}, /* Q */
|
||||
{10, 644}, /* R */
|
||||
{0, 0}, /* S */
|
||||
{10, 672}, /* T */
|
||||
{0, 0}, /* U */
|
||||
{10, 700}, /* V */
|
||||
{10, 728}, /* W */
|
||||
{10, 756}, /* X */
|
||||
{10, 784}, /* Y */
|
||||
};
|
||||
|
||||
/* Font information for ModeNine 15pt */
|
||||
const FONT_INFO modeNine_15ptFontInfo = {
|
||||
14, /* Character height */
|
||||
'-', /* Start character */
|
||||
'Y', /* End character */
|
||||
2, /* Width, in pixels, of space character */
|
||||
modeNine_15ptDescriptors, /* Character descriptor array */
|
||||
modeNine_15ptBitmaps, /* Character bitmap array */
|
||||
};
|
9
applications/external/totp/ui/fonts/mode-nine/mode_nine.h
vendored
Normal file
9
applications/external/totp/ui/fonts/mode-nine/mode_nine.h
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
/* GENERATED BY https://github.com/pavius/the-dot-factory */
|
||||
|
||||
#include "../font_info.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Font data for ModeNine 15pt */
|
||||
extern const FONT_INFO modeNine_15ptFontInfo;
|
@ -4,17 +4,17 @@
|
||||
#include "../../scene_director.h"
|
||||
#include "totp_input_text.h"
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../ui_controls.h"
|
||||
#include "../../common_dialogs.h"
|
||||
#include "../../../lib/roll_value/roll_value.h"
|
||||
#include <roll_value.h>
|
||||
#include "../../../types/nullable.h"
|
||||
#include "../generate_token/totp_scene_generate_token.h"
|
||||
|
||||
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512"};
|
||||
char* TOKEN_DIGITS_TEXT_LIST[] = {"6 digits", "8 digits"};
|
||||
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {TOTP_6_DIGITS, TOTP_8_DIGITS};
|
||||
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
|
||||
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
|
||||
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {TOTP_5_DIGITS, TOTP_6_DIGITS, TOTP_8_DIGITS};
|
||||
|
||||
typedef enum {
|
||||
TokenNameTextBox,
|
||||
@ -95,6 +95,8 @@ void totp_scene_add_new_token_activate(
|
||||
|
||||
scene_state->screen_y_offset = 0;
|
||||
|
||||
scene_state->digits_count_index = 1;
|
||||
|
||||
scene_state->input_state = NULL;
|
||||
scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||
scene_state->duration_text = furi_string_alloc();
|
||||
@ -216,10 +218,10 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
break;
|
||||
case InputKeyRight:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(&scene_state->algo, 1, SHA1, SHA512, RollOverflowBehaviorRoll);
|
||||
totp_roll_value_uint8_t(&scene_state->algo, 1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, 1, 0, 1, RollOverflowBehaviorRoll);
|
||||
&scene_state->digits_count_index, 1, 0, 2, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenDurationSelect) {
|
||||
totp_roll_value_uint8_t(&scene_state->duration, 15, 15, 255, RollOverflowBehaviorStop);
|
||||
update_duration_text(scene_state);
|
||||
@ -227,11 +229,10 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
if(scene_state->selected_control == TokenAlgoSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->algo, -1, SHA1, SHA512, RollOverflowBehaviorRoll);
|
||||
totp_roll_value_uint8_t(&scene_state->algo, -1, SHA1, STEAM, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->digits_count_index, -1, 0, 1, RollOverflowBehaviorRoll);
|
||||
&scene_state->digits_count_index, -1, 0, 2, RollOverflowBehaviorRoll);
|
||||
} else if(scene_state->selected_control == TokenDurationSelect) {
|
||||
totp_roll_value_uint8_t(
|
||||
&scene_state->duration, -15, 15, 255, RollOverflowBehaviorStop);
|
||||
@ -268,6 +269,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
||||
tokenInfo,
|
||||
scene_state->token_secret,
|
||||
scene_state->token_secret_length,
|
||||
PLAIN_TOKEN_ENCODING_BASE32,
|
||||
&plugin_state->iv[0]);
|
||||
|
||||
if(token_secret_set) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "../../constants.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../../services/convert/convert.h"
|
||||
#include "../../../lib/roll_value/roll_value.h"
|
||||
#include <roll_value.h>
|
||||
#include "../../../types/nullable.h"
|
||||
#include "../../../features_config.h"
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
|
@ -19,7 +19,9 @@
|
||||
#ifdef TOTP_BADBT_TYPE_ENABLED
|
||||
#include "../../../workers/bt_type_code/bt_type_code.h"
|
||||
#endif
|
||||
#include "../../fonts/mode-nine/mode_nine.h"
|
||||
|
||||
static const char* STEAM_ALGO_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY";
|
||||
static const uint8_t PROGRESS_BAR_MARGIN = 3;
|
||||
static const uint8_t PROGRESS_BAR_HEIGHT = 4;
|
||||
|
||||
@ -121,13 +123,21 @@ static const NotificationSequence*
|
||||
return (NotificationSequence*)scene_state->notification_sequence_badusb;
|
||||
}
|
||||
|
||||
static void int_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount len) {
|
||||
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 {
|
||||
for(int i = len - 1; i >= 0; i--) {
|
||||
str[i] = CONVERT_DIGIT_TO_CHAR(i_token_code % 10);
|
||||
i_token_code = i_token_code / 10;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,6 +147,7 @@ static void int_token_to_str(uint32_t i_token_code, char* str, TokenDigitsCount
|
||||
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;
|
||||
@ -161,6 +172,27 @@ static void update_totp_params(PluginState* const plugin_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 char_width = modeNine_15ptFontInfo.charInfo[0].width;
|
||||
uint8_t total_length = code_length * (char_width + modeNine_15ptFontInfo.spacePixels);
|
||||
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++) {
|
||||
char ch = scene_state->last_code[i];
|
||||
uint8_t char_index = ch - modeNine_15ptFontInfo.startChar;
|
||||
canvas_draw_xbm(
|
||||
canvas,
|
||||
offset_x,
|
||||
offset_y,
|
||||
char_width,
|
||||
modeNine_15ptFontInfo.height,
|
||||
&modeNine_15ptFontInfo.data[modeNine_15ptFontInfo.charInfo[char_index].offset]);
|
||||
|
||||
offset_x += char_width + modeNine_15ptFontInfo.spacePixels;
|
||||
}
|
||||
}
|
||||
|
||||
void totp_scene_generate_token_init(const PluginState* plugin_state) {
|
||||
UNUSED(plugin_state);
|
||||
}
|
||||
@ -274,19 +306,19 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
int_token_to_str(
|
||||
totp_at(
|
||||
get_totp_algo_impl(tokenInfo->algo),
|
||||
tokenInfo->digits,
|
||||
key,
|
||||
key_length,
|
||||
curr_ts,
|
||||
plugin_state->timezone_offset,
|
||||
tokenInfo->duration),
|
||||
scene_state->last_code,
|
||||
tokenInfo->digits);
|
||||
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);
|
||||
int_token_to_str(0, scene_state->last_code, tokenInfo->digits, tokenInfo->algo);
|
||||
}
|
||||
|
||||
furi_mutex_release(scene_state->last_code_update_sync);
|
||||
@ -322,14 +354,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
}
|
||||
|
||||
canvas_set_font(canvas, FontBigNumbers);
|
||||
canvas_draw_str_aligned(
|
||||
canvas,
|
||||
SCREEN_WIDTH_CENTER,
|
||||
SCREEN_HEIGHT_CENTER,
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
scene_state->last_code);
|
||||
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;
|
||||
|
@ -6,13 +6,13 @@
|
||||
#include "../../constants.h"
|
||||
#include "../../scene_director.h"
|
||||
#include "../../../services/config/config.h"
|
||||
#include "../../../lib/list/list.h"
|
||||
#include <linked_list.h>
|
||||
#include "../../../types/token_info.h"
|
||||
#include "../generate_token/totp_scene_generate_token.h"
|
||||
#include "../add_new_token/totp_scene_add_new_token.h"
|
||||
#include "../app_settings/totp_app_settings.h"
|
||||
#include "../../../types/nullable.h"
|
||||
#include "../../../lib/roll_value/roll_value.h"
|
||||
#include <roll_value.h>
|
||||
|
||||
#define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3)
|
||||
#define SCREEN_HEIGHT_THIRD_CENTER (SCREEN_HEIGHT_THIRD >> 1)
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "bt_type_code.h"
|
||||
#include <furi_hal_bt_hid.h>
|
||||
#include <bt/bt_service/bt_i.h>
|
||||
#include <storage/storage.h>
|
||||
#include "../../types/common.h"
|
||||
#include "../../types/token_info.h"
|
||||
@ -11,6 +12,26 @@ static inline bool totp_type_code_worker_stop_requested() {
|
||||
return furi_thread_flags_get() & TotpBtTypeCodeWorkerEventStop;
|
||||
}
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||
static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) {
|
||||
uint8_t max_i;
|
||||
size_t uid_size = furi_hal_version_uid_size();
|
||||
if(uid_size < 6) {
|
||||
max_i = uid_size;
|
||||
} else {
|
||||
max_i = 6;
|
||||
}
|
||||
|
||||
const uint8_t* uid = furi_hal_version_uid();
|
||||
memcpy(mac, uid, max_i);
|
||||
for(uint8_t i = max_i; i < 6; i++) {
|
||||
mac[i] = 0;
|
||||
}
|
||||
|
||||
mac[0] = 0b10;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void totp_type_code_worker_type_code(TotpBtTypeCodeWorkerContext* context) {
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
@ -30,7 +51,7 @@ static void totp_type_code_worker_type_code(TotpBtTypeCodeWorkerContext* context
|
||||
}
|
||||
|
||||
static int32_t totp_type_code_worker_callback(void* context) {
|
||||
furi_assert(context);
|
||||
furi_check(context);
|
||||
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(context_mutex == NULL) {
|
||||
return 251;
|
||||
@ -74,7 +95,7 @@ void totp_bt_type_code_worker_start(
|
||||
char* code_buf,
|
||||
uint8_t code_buf_length,
|
||||
FuriMutex* code_buf_update_sync) {
|
||||
furi_assert(context != NULL);
|
||||
furi_check(context != NULL);
|
||||
context->string = code_buf;
|
||||
context->string_length = code_buf_length;
|
||||
context->string_sync = code_buf_update_sync;
|
||||
@ -87,7 +108,7 @@ void totp_bt_type_code_worker_start(
|
||||
}
|
||||
|
||||
void totp_bt_type_code_worker_stop(TotpBtTypeCodeWorkerContext* context) {
|
||||
furi_assert(context != NULL);
|
||||
furi_check(context != NULL);
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), TotpBtTypeCodeWorkerEventStop);
|
||||
furi_thread_join(context->thread);
|
||||
furi_thread_free(context->thread);
|
||||
@ -98,7 +119,7 @@ void totp_bt_type_code_worker_notify(
|
||||
TotpBtTypeCodeWorkerContext* context,
|
||||
TotpBtTypeCodeWorkerEvent event,
|
||||
uint8_t flags) {
|
||||
furi_assert(context != NULL);
|
||||
furi_check(context != NULL);
|
||||
context->flags = flags;
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), event);
|
||||
}
|
||||
@ -114,11 +135,33 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
||||
furi_hal_bt_reinit();
|
||||
furi_delay_ms(200);
|
||||
bt_keys_storage_set_storage_path(context->bt, HID_BT_KEYS_STORAGE_PATH);
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||
totp_type_code_worker_bt_set_app_mac(&context->bt_mac[0]);
|
||||
memcpy(
|
||||
&context->previous_bt_name[0],
|
||||
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
|
||||
TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN);
|
||||
memcpy(
|
||||
&context->previous_bt_mac[0],
|
||||
furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard),
|
||||
TOTP_BT_WORKER_BT_MAC_ADDRESS_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());
|
||||
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, new_name);
|
||||
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, context->bt_mac);
|
||||
#endif
|
||||
|
||||
if(!bt_set_profile(context->bt, BtProfileHidKeyboard)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Failed to switch BT to keyboard HID profile");
|
||||
}
|
||||
|
||||
furi_hal_bt_start_advertising();
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||
bt_enable_peer_key_update(context->bt);
|
||||
#endif
|
||||
|
||||
context->is_advertising = true;
|
||||
bt_set_status_changed_callback(context->bt, connection_status_changed_callback, context);
|
||||
|
||||
@ -126,7 +169,7 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() {
|
||||
}
|
||||
|
||||
void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context) {
|
||||
furi_assert(context != NULL);
|
||||
furi_check(context != NULL);
|
||||
|
||||
if(context->thread != NULL) {
|
||||
totp_bt_type_code_worker_stop(context);
|
||||
@ -142,6 +185,11 @@ void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context) {
|
||||
furi_delay_ms(200);
|
||||
bt_keys_storage_set_default_path(context->bt);
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, context->previous_bt_name);
|
||||
furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, context->previous_bt_mac);
|
||||
#endif
|
||||
|
||||
if(!bt_set_profile(context->bt, BtProfileSerial)) {
|
||||
FURI_LOG_E(LOGGING_TAG, "Failed to switch BT to Serial profile");
|
||||
}
|
||||
|
@ -4,6 +4,12 @@
|
||||
#include <furi/furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <bt/bt_service/bt.h>
|
||||
#include "../../features_config.h"
|
||||
|
||||
#if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME
|
||||
#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN 18
|
||||
#define TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE
|
||||
#endif
|
||||
|
||||
typedef uint8_t TotpBtTypeCodeWorkerEvent;
|
||||
|
||||
@ -16,6 +22,11 @@ typedef struct {
|
||||
Bt* bt;
|
||||
bool is_advertising;
|
||||
bool is_connected;
|
||||
#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 + 1];
|
||||
uint8_t previous_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN];
|
||||
#endif
|
||||
} TotpBtTypeCodeWorkerContext;
|
||||
|
||||
enum TotpBtTypeCodeWorkerEvents {
|
||||
|
37
applications/external/totp/workers/common.c
vendored
37
applications/external/totp/workers/common.c
vendored
@ -3,17 +3,15 @@
|
||||
#include <furi_hal.h>
|
||||
#include "../../services/convert/convert.h"
|
||||
|
||||
static const uint8_t hid_number_keys[10] = {
|
||||
HID_KEYBOARD_0,
|
||||
HID_KEYBOARD_1,
|
||||
HID_KEYBOARD_2,
|
||||
HID_KEYBOARD_3,
|
||||
HID_KEYBOARD_4,
|
||||
HID_KEYBOARD_5,
|
||||
HID_KEYBOARD_6,
|
||||
HID_KEYBOARD_7,
|
||||
HID_KEYBOARD_8,
|
||||
HID_KEYBOARD_9};
|
||||
static const uint8_t hid_number_keys[] = {
|
||||
HID_KEYBOARD_0, HID_KEYBOARD_1, HID_KEYBOARD_2, HID_KEYBOARD_3, HID_KEYBOARD_4,
|
||||
HID_KEYBOARD_5, HID_KEYBOARD_6, HID_KEYBOARD_7, HID_KEYBOARD_8, HID_KEYBOARD_9,
|
||||
HID_KEYBOARD_A, HID_KEYBOARD_B, HID_KEYBOARD_C, HID_KEYBOARD_D, HID_KEYBOARD_E,
|
||||
HID_KEYBOARD_F, HID_KEYBOARD_G, HID_KEYBOARD_H, HID_KEYBOARD_I, HID_KEYBOARD_J,
|
||||
HID_KEYBOARD_K, HID_KEYBOARD_L, HID_KEYBOARD_M, HID_KEYBOARD_N, HID_KEYBOARD_O,
|
||||
HID_KEYBOARD_P, HID_KEYBOARD_Q, HID_KEYBOARD_R, HID_KEYBOARD_S, HID_KEYBOARD_T,
|
||||
HID_KEYBOARD_U, HID_KEYBOARD_V, HID_KEYBOARD_W, HID_KEYBOARD_X, HID_KEYBOARD_Y,
|
||||
HID_KEYBOARD_Z};
|
||||
|
||||
static uint32_t get_keystroke_delay(TokenAutomationFeature features) {
|
||||
if(features & TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER) {
|
||||
@ -49,10 +47,18 @@ void totp_type_code_worker_execute_automation(
|
||||
TokenAutomationFeature features) {
|
||||
furi_delay_ms(500);
|
||||
uint8_t i = 0;
|
||||
totp_type_code_worker_press_key(
|
||||
HID_KEYBOARD_CAPS_LOCK, key_press_fn, key_release_fn, features);
|
||||
|
||||
while(i < string_length && string[i] != 0) {
|
||||
uint8_t digit = CONVERT_CHAR_TO_DIGIT(string[i]);
|
||||
if(digit > 9) break;
|
||||
uint8_t hid_kb_key = hid_number_keys[digit];
|
||||
uint8_t char_index = CONVERT_CHAR_TO_DIGIT(string[i]);
|
||||
if(char_index > 9) {
|
||||
char_index = string[i] - 0x41 + 10;
|
||||
}
|
||||
|
||||
if(char_index > 35) break;
|
||||
|
||||
uint8_t hid_kb_key = hid_number_keys[char_index];
|
||||
totp_type_code_worker_press_key(hid_kb_key, key_press_fn, key_release_fn, features);
|
||||
furi_delay_ms(get_keystroke_delay(features));
|
||||
i++;
|
||||
@ -68,4 +74,7 @@ void totp_type_code_worker_execute_automation(
|
||||
furi_delay_ms(get_keystroke_delay(features));
|
||||
totp_type_code_worker_press_key(HID_KEYBOARD_TAB, key_press_fn, key_release_fn, features);
|
||||
}
|
||||
|
||||
totp_type_code_worker_press_key(
|
||||
HID_KEYBOARD_CAPS_LOCK, key_press_fn, key_release_fn, features);
|
||||
}
|
@ -41,7 +41,7 @@ static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* contex
|
||||
}
|
||||
|
||||
static int32_t totp_type_code_worker_callback(void* context) {
|
||||
furi_assert(context);
|
||||
furi_check(context);
|
||||
FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
if(context_mutex == NULL) {
|
||||
return 251;
|
||||
@ -89,7 +89,7 @@ TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start(
|
||||
}
|
||||
|
||||
void totp_usb_type_code_worker_stop(TotpUsbTypeCodeWorkerContext* context) {
|
||||
furi_assert(context != NULL);
|
||||
furi_check(context != NULL);
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), TotpUsbTypeCodeWorkerEventStop);
|
||||
furi_thread_join(context->thread);
|
||||
furi_thread_free(context->thread);
|
||||
@ -101,7 +101,7 @@ void totp_usb_type_code_worker_notify(
|
||||
TotpUsbTypeCodeWorkerContext* context,
|
||||
TotpUsbTypeCodeWorkerEvent event,
|
||||
uint8_t flags) {
|
||||
furi_assert(context != NULL);
|
||||
furi_check(context != NULL);
|
||||
context->flags = flags;
|
||||
furi_thread_flags_set(furi_thread_get_id(context->thread), event);
|
||||
}
|
Loading…
Reference in New Issue
Block a user