2022-10-12 02:01:37 +00:00
|
|
|
#include "totp_scene_authenticate.h"
|
|
|
|
#include <dialogs/dialogs.h>
|
|
|
|
#include "../../types/common.h"
|
|
|
|
#include "../../services/ui/icons.h"
|
|
|
|
#include "../../services/ui/constants.h"
|
|
|
|
#include "../../services/config/config.h"
|
|
|
|
#include "../scene_director.h"
|
|
|
|
#include "../totp_scenes_enum.h"
|
2022-10-17 18:22:34 +00:00
|
|
|
#include "../../services/crypto/crypto.h"
|
2022-10-12 02:01:37 +00:00
|
|
|
|
|
|
|
#define MAX_CODE_LENGTH TOTP_IV_SIZE
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t code_input[MAX_CODE_LENGTH];
|
|
|
|
uint8_t code_length;
|
|
|
|
} 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) {
|
|
|
|
SceneState* scene_state = malloc(sizeof(SceneState));
|
|
|
|
scene_state->code_length = 0;
|
|
|
|
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
|
|
|
|
plugin_state->current_scene_state = scene_state;
|
2022-10-28 15:34:35 +00:00
|
|
|
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
|
2022-10-12 02:01:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state) {
|
2022-10-28 15:34:35 +00:00
|
|
|
const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
2022-10-12 02:01:37 +00:00
|
|
|
|
|
|
|
int v_shift = 0;
|
2022-10-13 14:00:20 +00:00
|
|
|
if(scene_state->code_length > 0) {
|
2022-10-12 02:01:37 +00:00
|
|
|
v_shift = -10;
|
|
|
|
}
|
|
|
|
|
2022-10-13 14:00:20 +00:00
|
|
|
if(plugin_state->crypto_verify_data == NULL) {
|
|
|
|
canvas_draw_str_aligned(
|
|
|
|
canvas,
|
|
|
|
SCREEN_WIDTH_CENTER,
|
|
|
|
SCREEN_HEIGHT_CENTER - 10 + v_shift,
|
|
|
|
AlignCenter,
|
|
|
|
AlignCenter,
|
|
|
|
"Use arrow keys");
|
|
|
|
canvas_draw_str_aligned(
|
|
|
|
canvas,
|
|
|
|
SCREEN_WIDTH_CENTER,
|
|
|
|
SCREEN_HEIGHT_CENTER + 5 + v_shift,
|
|
|
|
AlignCenter,
|
|
|
|
AlignCenter,
|
|
|
|
"to setup new PIN");
|
2022-10-12 02:01:37 +00:00
|
|
|
} else {
|
2022-10-13 14:00:20 +00:00
|
|
|
canvas_draw_str_aligned(
|
|
|
|
canvas,
|
|
|
|
SCREEN_WIDTH_CENTER,
|
|
|
|
SCREEN_HEIGHT_CENTER + v_shift,
|
|
|
|
AlignCenter,
|
|
|
|
AlignCenter,
|
|
|
|
"Use arrow keys to enter PIN");
|
2022-10-12 02:01:37 +00:00
|
|
|
}
|
|
|
|
const uint8_t PIN_ASTERISK_RADIUS = 3;
|
|
|
|
const uint8_t PIN_ASTERISK_STEP = (PIN_ASTERISK_RADIUS << 1) + 2;
|
2022-10-13 14:00:20 +00:00
|
|
|
if(scene_state->code_length > 0) {
|
2022-10-12 02:01:37 +00:00
|
|
|
uint8_t left_start_x = (scene_state->code_length - 1) * PIN_ASTERISK_STEP >> 1;
|
2022-10-13 14:00:20 +00:00
|
|
|
for(uint8_t i = 0; i < scene_state->code_length; i++) {
|
2022-10-12 02:01:37 +00:00
|
|
|
canvas_draw_disc(
|
2022-10-13 14:00:20 +00:00
|
|
|
canvas,
|
|
|
|
SCREEN_WIDTH_CENTER - left_start_x + i * PIN_ASTERISK_STEP,
|
|
|
|
SCREEN_HEIGHT_CENTER + 10,
|
2022-10-12 02:01:37 +00:00
|
|
|
PIN_ASTERISK_RADIUS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-28 16:18:42 +00:00
|
|
|
bool totp_scene_authenticate_handle_event(
|
|
|
|
const PluginEvent* const event,
|
|
|
|
PluginState* plugin_state) {
|
2022-10-12 02:01:37 +00:00
|
|
|
if(event->type == EventTypeKey) {
|
2022-10-13 14:00:20 +00:00
|
|
|
if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) {
|
2022-10-12 02:01:37 +00:00
|
|
|
return false;
|
|
|
|
} else if(event->input.type == InputTypePress) {
|
2022-10-13 14:00:20 +00:00
|
|
|
SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
|
2022-10-12 02:01:37 +00:00
|
|
|
|
|
|
|
const uint8_t ARROW_UP_CODE = 2;
|
|
|
|
const uint8_t ARROW_RIGHT_CODE = 8;
|
|
|
|
const uint8_t ARROW_DOWN_CODE = 11;
|
|
|
|
const uint8_t ARROW_LEFT_CODE = 5;
|
|
|
|
|
|
|
|
switch(event->input.key) {
|
2022-10-13 14:00:20 +00:00
|
|
|
case InputKeyUp:
|
|
|
|
if(scene_state->code_length < MAX_CODE_LENGTH) {
|
|
|
|
scene_state->code_input[scene_state->code_length] = ARROW_UP_CODE;
|
|
|
|
scene_state->code_length++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case InputKeyDown:
|
|
|
|
if(scene_state->code_length < MAX_CODE_LENGTH) {
|
|
|
|
scene_state->code_input[scene_state->code_length] = ARROW_DOWN_CODE;
|
|
|
|
scene_state->code_length++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case InputKeyRight:
|
|
|
|
if(scene_state->code_length < MAX_CODE_LENGTH) {
|
|
|
|
scene_state->code_input[scene_state->code_length] = ARROW_RIGHT_CODE;
|
|
|
|
scene_state->code_length++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case InputKeyLeft:
|
|
|
|
if(scene_state->code_length < MAX_CODE_LENGTH) {
|
|
|
|
scene_state->code_input[scene_state->code_length] = ARROW_LEFT_CODE;
|
|
|
|
scene_state->code_length++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case InputKeyOk:
|
2022-10-17 18:22:34 +00:00
|
|
|
totp_crypto_seed_iv(
|
|
|
|
plugin_state, &scene_state->code_input[0], scene_state->code_length);
|
2022-10-13 14:00:20 +00:00
|
|
|
|
2022-10-17 18:22:34 +00:00
|
|
|
if(totp_crypto_verify_key(plugin_state)) {
|
2022-10-13 14:00:20 +00:00
|
|
|
FURI_LOG_D(LOGGING_TAG, "PIN is valid");
|
|
|
|
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
|
|
|
|
} else {
|
|
|
|
FURI_LOG_D(LOGGING_TAG, "PIN is NOT valid");
|
|
|
|
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
|
|
|
|
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
|
|
|
|
scene_state->code_length = 0;
|
|
|
|
|
|
|
|
DialogMessage* message = dialog_message_alloc();
|
|
|
|
dialog_message_set_buttons(message, "Try again", NULL, NULL);
|
|
|
|
dialog_message_set_header(
|
|
|
|
message,
|
|
|
|
"You entered\ninvalid PIN",
|
|
|
|
SCREEN_WIDTH_CENTER - 25,
|
|
|
|
SCREEN_HEIGHT_CENTER - 5,
|
|
|
|
AlignCenter,
|
|
|
|
AlignCenter);
|
|
|
|
dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17);
|
|
|
|
dialog_message_show(plugin_state->dialogs, message);
|
|
|
|
dialog_message_free(message);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case InputKeyBack:
|
|
|
|
if(scene_state->code_length > 0) {
|
|
|
|
scene_state->code_input[scene_state->code_length - 1] = 0;
|
|
|
|
scene_state->code_length--;
|
|
|
|
}
|
|
|
|
break;
|
2022-10-12 02:01:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void totp_scene_authenticate_deactivate(PluginState* plugin_state) {
|
2022-10-13 14:00:20 +00:00
|
|
|
if(plugin_state->current_scene_state == NULL) return;
|
2022-10-12 02:01:37 +00:00
|
|
|
free(plugin_state->current_scene_state);
|
|
|
|
plugin_state->current_scene_state = NULL;
|
|
|
|
}
|
|
|
|
|
2022-10-28 15:34:35 +00:00
|
|
|
void totp_scene_authenticate_free(const PluginState* plugin_state) {
|
2022-10-12 02:01:37 +00:00
|
|
|
UNUSED(plugin_state);
|
|
|
|
}
|