add PUK entry

This commit is contained in:
Michele Balistreri 2023-11-02 14:56:27 +09:00
parent 9064c90b72
commit 3ed38cf4af
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
11 changed files with 98 additions and 17 deletions

View File

@ -19,7 +19,7 @@ void card_change_name() {
void card_change_pin() { void card_change_pin() {
SC_BUF(pin, KEYCARD_PIN_LEN); SC_BUF(pin, KEYCARD_PIN_LEN);
if (ui_read_pin(pin, PIN_NEW_CODE) != CORE_EVT_UI_OK) { if (ui_read_pin(pin, PIN_NEW_CODE, 1) != CORE_EVT_UI_OK) {
return; return;
} }
@ -34,7 +34,7 @@ void card_change_pin() {
void card_change_puk() { void card_change_puk() {
SC_BUF(puk, KEYCARD_PUK_LEN); SC_BUF(puk, KEYCARD_PUK_LEN);
if (ui_read_puk(puk, PUK_NEW_CODE) != CORE_EVT_UI_OK) { if (ui_read_puk(puk, PUK_NEW_CODE, 1) != CORE_EVT_UI_OK) {
return; return;
} }

View File

@ -28,7 +28,7 @@ static void keycard_random_puk(uint8_t puk[KEYCARD_PUK_LEN]) {
static app_err_t keycard_init_card(keycard_t* kc, uint8_t* sc_key, uint8_t* pin) { static app_err_t keycard_init_card(keycard_t* kc, uint8_t* sc_key, uint8_t* pin) {
uint8_t puk[KEYCARD_PUK_LEN]; uint8_t puk[KEYCARD_PUK_LEN];
if (ui_read_pin(pin, PIN_NEW_CODE) != CORE_EVT_UI_OK) { if (ui_read_pin(pin, PIN_NEW_CODE, 0) != CORE_EVT_UI_OK) {
return ERR_CANCEL; return ERR_CANCEL;
} }
@ -62,7 +62,7 @@ static app_err_t keycard_pair(keycard_t* kc, pairing_t* pairing, uint8_t* instan
return ERR_DATA; return ERR_DATA;
} }
ui_keyard_paired(); ui_keycard_paired();
return ERR_OK; return ERR_OK;
} }
@ -95,14 +95,14 @@ static app_err_t keycard_unblock(keycard_t* kc, uint8_t pukRetries) {
if (pukRetries) { if (pukRetries) {
if (ui_prompt_try_puk() != CORE_EVT_UI_OK) { if (ui_prompt_try_puk() != CORE_EVT_UI_OK) {
pukRetries = 0; pukRetries = 0;
} else if (ui_read_pin(pin, PIN_NEW_CODE) != CORE_EVT_UI_OK) { } else if (ui_read_pin(pin, PIN_NEW_CODE, 0) != CORE_EVT_UI_OK) {
return ERR_CANCEL; return ERR_CANCEL;
} }
} }
while(pukRetries) { while(pukRetries) {
uint8_t puk[KEYCARD_PUK_LEN]; uint8_t puk[KEYCARD_PUK_LEN];
if (ui_read_puk(puk, pukRetries) != CORE_EVT_UI_OK) { if (ui_read_puk(puk, pukRetries, 0) != CORE_EVT_UI_OK) {
return ERR_CANCEL; return ERR_CANCEL;
} }
@ -136,7 +136,7 @@ static app_err_t keycard_authenticate(keycard_t* kc, uint8_t* pin, uint8_t* cach
application_status_parse(APDU_RESP(&kc->apdu), &pinStatus); application_status_parse(APDU_RESP(&kc->apdu), &pinStatus);
while(pinStatus.pin_retries) { while(pinStatus.pin_retries) {
if (!(*cached_pin) && (ui_read_pin(pin, pinStatus.pin_retries) != CORE_EVT_UI_OK)) { if (!(*cached_pin) && (ui_read_pin(pin, pinStatus.pin_retries, 0) != CORE_EVT_UI_OK)) {
return ERR_CANCEL; return ERR_CANCEL;
} }

View File

@ -81,6 +81,9 @@ void ui_task_entry(void* pvParameters) {
case UI_CMD_INPUT_PIN: case UI_CMD_INPUT_PIN:
g_ui_cmd.result = input_pin(); g_ui_cmd.result = input_pin();
break; break;
case UI_CMD_INPUT_PUK:
g_ui_cmd.result = input_puk();
break;
case UI_CMD_INPUT_STRING: case UI_CMD_INPUT_STRING:
g_ui_cmd.result = input_string(); g_ui_cmd.result = input_string();
break; break;

View File

@ -47,6 +47,12 @@ const char *const i18n_english_strings[] = {
"Repeat the PIN", "Repeat the PIN",
"PINs don't match", "PINs don't match",
// PUK input
"Insert your PUK",
"Choose a new PUK",
"Card blocked",
"The card is blocked. If you have setup a PUK press OK to insert it, otherwise press Cancel to factory reset the card.",
// Pairing input // Pairing input
"Insert your pairing password", "Insert your pairing password",
"Choose your pairing password", "Choose your pairing password",

View File

@ -50,6 +50,12 @@ typedef enum {
PIN_LABEL_REPEAT, PIN_LABEL_REPEAT,
PIN_LABEL_MISMATCH, PIN_LABEL_MISMATCH,
// PUK input
PUK_INPUT_TITLE,
PUK_CREATE_TITLE,
PUK_PROMPT_TITLE,
PUK_PROMPT,
// Pairing input // Pairing input
PAIRING_INPUT_TITLE, PAIRING_INPUT_TITLE,
PAIRING_CREATE_TITLE, PAIRING_CREATE_TITLE,

View File

@ -12,6 +12,7 @@
#include "ui/ui_internal.h" #include "ui/ui_internal.h"
#define PIN_LEN 6 #define PIN_LEN 6
#define PUK_LEN 12
#define DIG_INV ' ' #define DIG_INV ' '
#define KEY_BACKSPACE 0x08 #define KEY_BACKSPACE 0x08
@ -90,6 +91,8 @@ app_err_t input_new_pin() {
if (key == KEYPAD_KEY_BACK) { if (key == KEYPAD_KEY_BACK) {
if (position > 0) { if (position > 0) {
position--; position--;
} else if (g_ui_cmd.params.input_pin.dismissable) {
return ERR_CANCEL;
} }
} else if (key == KEYPAD_KEY_CONFIRM) { } else if (key == KEYPAD_KEY_CONFIRM) {
if ((position == (PIN_LEN * 2)) && matches) { if ((position == (PIN_LEN * 2)) && matches) {
@ -145,6 +148,8 @@ app_err_t input_pin() {
if (key == KEYPAD_KEY_BACK) { if (key == KEYPAD_KEY_BACK) {
if (position > 0) { if (position > 0) {
position--; position--;
} else if (g_ui_cmd.params.input_pin.dismissable) {
return ERR_CANCEL;
} }
} else if (key == KEYPAD_KEY_CONFIRM) { } else if (key == KEYPAD_KEY_CONFIRM) {
if (position == PIN_LEN) { if (position == PIN_LEN) {
@ -159,6 +164,53 @@ app_err_t input_pin() {
} }
} }
app_err_t input_puk() {
dialog_footer(TH_TITLE_HEIGHT);
if (g_ui_cmd.params.input_pin.retries == PUK_NEW_CODE) {
dialog_title(LSTR(PUK_CREATE_TITLE));
} else {
dialog_title(LSTR(PUK_INPUT_TITLE));
screen_text_ctx_t ctx = {
.bg = TH_COLOR_TEXT_BG,
.fg = TH_COLOR_TEXT_FG,
.font = TH_FONT_TEXT,
.x = TH_LABEL_LEFT_MARGIN,
.y = TH_TITLE_HEIGHT + (TH_PIN_FIELD_HEIGHT * 3) + (TH_PIN_FIELD_VERTICAL_MARGIN * 2) + (TH_PUK_FIELD_VERTICAL_MARGIN * 4)
};
screen_draw_string(&ctx, LSTR(PIN_LABEL_REMAINING_ATTEMPTS));
screen_draw_char(&ctx, (g_ui_cmd.params.input_pin.retries + '0'));
}
char* out = (char *) g_ui_cmd.params.input_pin.out;
uint8_t position = 0;
while(1) {
input_render_secret(TH_TITLE_HEIGHT + TH_PIN_FIELD_VERTICAL_MARGIN, 4, position);
input_render_secret((TH_TITLE_HEIGHT + TH_PIN_FIELD_VERTICAL_MARGIN) + (TH_PIN_FIELD_HEIGHT + TH_PUK_FIELD_VERTICAL_MARGIN) , 4, position - 4);
input_render_secret((TH_TITLE_HEIGHT + TH_PIN_FIELD_VERTICAL_MARGIN) + ((TH_PIN_FIELD_HEIGHT + TH_PUK_FIELD_VERTICAL_MARGIN) * 2), 4, position - 8);
keypad_key_t key = ui_wait_keypress(portMAX_DELAY);
if (key == KEYPAD_KEY_BACK) {
if (position > 0) {
position--;
} else if (g_ui_cmd.params.input_pin.retries == PUK_NEW_CODE) {
return ERR_CANCEL;
}
} else if (key == KEYPAD_KEY_CONFIRM) {
if (position == PUK_LEN) {
return ERR_OK;
}
} else if (position < PUK_LEN) {
char digit = KEYPAD_TO_DIGIT[key];
if (digit != DIG_INV) {
out[position++] = digit;
}
}
}
}
static inline void input_keyboard_render_key(char c, uint16_t x, uint16_t y, bool selected) { static inline void input_keyboard_render_key(char c, uint16_t x, uint16_t y, bool selected) {
screen_area_t key_area = { .x = x, .y = y, .width = TH_KEYBOARD_KEY_SIZE, .height = TH_KEYBOARD_KEY_SIZE }; screen_area_t key_area = { .x = x, .y = y, .width = TH_KEYBOARD_KEY_SIZE, .height = TH_KEYBOARD_KEY_SIZE };
screen_text_ctx_t ctx = { .font = TH_FONT_TEXT, .fg = TH_COLOR_TEXT_FG, .y = y }; screen_text_ctx_t ctx = { .font = TH_FONT_TEXT, .fg = TH_COLOR_TEXT_FG, .y = y };

View File

@ -5,6 +5,7 @@
#include "error.h" #include "error.h"
app_err_t input_pin(); app_err_t input_pin();
app_err_t input_puk();
app_err_t input_mnemonic(); app_err_t input_mnemonic();
app_err_t input_backup_mnemonic(); app_err_t input_backup_mnemonic();
app_err_t input_string(); app_err_t input_string();

View File

@ -66,6 +66,7 @@
#define TH_PIN_FIELD_WIDTH 30 #define TH_PIN_FIELD_WIDTH 30
#define TH_PIN_FIELD_VERTICAL_MARGIN 16 #define TH_PIN_FIELD_VERTICAL_MARGIN 16
#define TH_PIN_FIELD_DIGIT_MARGIN TH_DEF_LEFT_MARGIN #define TH_PIN_FIELD_DIGIT_MARGIN TH_DEF_LEFT_MARGIN
#define TH_PUK_FIELD_VERTICAL_MARGIN 4
#define TH_KEYBOARD_KEY_SIZE 32 #define TH_KEYBOARD_KEY_SIZE 32
#define TH_KEYBOARD_KEY_BG SCREEN_RGB(37, 41, 56) #define TH_KEYBOARD_KEY_BG SCREEN_RGB(37, 41, 56)

View File

@ -83,7 +83,7 @@ void ui_keycard_no_keys() {
void ui_keycard_ready() { void ui_keycard_ready() {
} }
void ui_keyard_paired() { void ui_keycard_paired() {
} }
void ui_keycard_already_paired() { void ui_keycard_already_paired() {
@ -114,27 +114,37 @@ void ui_keycard_wrong_puk() {
} }
core_evt_t ui_prompt_try_puk() { core_evt_t ui_prompt_try_puk() {
return CORE_EVT_UI_OK; return ui_info(LSTR(PUK_PROMPT_TITLE), LSTR(PUK_PROMPT), 1);
} }
core_evt_t ui_confirm_factory_reset() { core_evt_t ui_confirm_factory_reset() {
return ui_info(LSTR(FACTORY_RESET_TITLE), LSTR(FACTORY_RESET_WARNING), 1); return ui_info(LSTR(FACTORY_RESET_TITLE), LSTR(FACTORY_RESET_WARNING), 1);
} }
core_evt_t ui_read_pin(uint8_t* out, int8_t retries) { core_evt_t ui_read_pin(uint8_t* out, int8_t retries, uint8_t dismissable) {
g_ui_cmd.type = UI_CMD_INPUT_PIN; g_ui_cmd.type = UI_CMD_INPUT_PIN;
g_ui_cmd.params.input_pin.dismissable = dismissable;
g_ui_cmd.params.input_pin.retries = retries; g_ui_cmd.params.input_pin.retries = retries;
g_ui_cmd.params.input_pin.out = out; g_ui_cmd.params.input_pin.out = out;
return ui_signal_wait(0); return ui_signal_wait(0);
} }
core_evt_t ui_read_puk(uint8_t* out, int8_t retries) { core_evt_t ui_read_puk(uint8_t* out, int8_t retries, uint8_t dismissable) {
return CORE_EVT_UI_CANCELLED; g_ui_cmd.type = UI_CMD_INPUT_PUK;
g_ui_cmd.params.input_pin.dismissable = dismissable;
g_ui_cmd.params.input_pin.retries = retries;
g_ui_cmd.params.input_pin.out = out;
return ui_signal_wait(0);
} }
core_evt_t ui_read_pairing(uint8_t* pairing, uint8_t *len) { core_evt_t ui_read_pairing(uint8_t* pairing, uint8_t *len) {
return ui_read_string(LSTR(PAIRING_INPUT_TITLE), (char*) pairing, len); while(ui_read_string(LSTR(PAIRING_INPUT_TITLE), (char*) pairing, len) != CORE_EVT_UI_OK) {
continue;
}
return CORE_EVT_UI_OK;
} }
core_evt_t ui_read_string(const char* title, char* out, uint8_t* len) { core_evt_t ui_read_string(const char* title, char* out, uint8_t* len) {

View File

@ -34,7 +34,7 @@ void ui_keycard_not_initialized();
void ui_keycard_init_failed(); void ui_keycard_init_failed();
void ui_keycard_no_keys(); void ui_keycard_no_keys();
void ui_keycard_ready(); void ui_keycard_ready();
void ui_keyard_paired(); void ui_keycard_paired();
void ui_keycard_already_paired(); void ui_keycard_already_paired();
void ui_keycard_pairing_failed(); void ui_keycard_pairing_failed();
void ui_keycard_flash_failed(); void ui_keycard_flash_failed();
@ -48,8 +48,8 @@ void ui_seed_loaded();
core_evt_t ui_prompt_try_puk(); core_evt_t ui_prompt_try_puk();
core_evt_t ui_confirm_factory_reset(); core_evt_t ui_confirm_factory_reset();
core_evt_t ui_read_pin(uint8_t* out, int8_t retries); core_evt_t ui_read_pin(uint8_t* out, int8_t retries, uint8_t dismissable);
core_evt_t ui_read_puk(uint8_t* out, int8_t retries); core_evt_t ui_read_puk(uint8_t* out, int8_t retries, uint8_t dismissable);
core_evt_t ui_read_pairing(uint8_t* pairing, uint8_t* len); core_evt_t ui_read_pairing(uint8_t* pairing, uint8_t* len);
core_evt_t ui_read_string(const char* title, char* out, uint8_t* len); core_evt_t ui_read_string(const char* title, char* out, uint8_t* len);

View File

@ -28,6 +28,7 @@ enum cmd_type {
UI_CMD_DISPLAY_QR, UI_CMD_DISPLAY_QR,
UI_CMD_QRSCAN, UI_CMD_QRSCAN,
UI_CMD_INPUT_PIN, UI_CMD_INPUT_PIN,
UI_CMD_INPUT_PUK,
UI_CMD_INPUT_STRING, UI_CMD_INPUT_STRING,
UI_CMD_INPUT_MNEMO, UI_CMD_INPUT_MNEMO,
UI_CMD_BACKUP_MNEMO, UI_CMD_BACKUP_MNEMO,
@ -69,8 +70,9 @@ struct cmd_qrscan {
}; };
struct cmd_input_pin { struct cmd_input_pin {
int8_t retries;
uint8_t* out; uint8_t* out;
int8_t retries;
uint8_t dismissable;
}; };
struct cmd_input_string { struct cmd_input_string {