diff --git a/app/common.h b/app/common.h index e15c77a..f017b10 100644 --- a/app/common.h +++ b/app/common.h @@ -15,6 +15,11 @@ #include #include "hal.h" +typedef struct { + uint8_t* data; + size_t len; +} data_t; + #define APP_ALIGNED(x, a) x __attribute__((aligned(a))) #define APP_SECTION(x, s) x __attribute__((section(s))) #define APP_ALWAYS_INLINE inline __attribute__((always_inline)) diff --git a/app/core/updater.c b/app/core/updater.c new file mode 100644 index 0000000..0a10c5b --- /dev/null +++ b/app/core/updater.c @@ -0,0 +1,30 @@ +#include "common.h" +#include "updater.h" +#include "ethereum/eth_db.h" +#include "keycard/keycard.h" +#include "ui/ui.h" +#include "ur/ur.h" + +app_err_t updater_verify_data(data_t* data) { + //TODO: verify signature + sanity check + return ERR_OK; +} + +void updater_database_run() { + data_t data; + + if (ui_qrscan(FS_DATA, &data) != CORE_EVT_UI_OK) { + return; + } + + if (updater_verify_data(&data) != ERR_OK) { + ui_info(INFO_ERROR_TITLE, LSTR(INFO_DB_UPDATE_INVALID), 1); + return; + } + + if (eth_db_update((fs_entry_t *) data.data, data.len) != ERR_OK) { + ui_info(INFO_ERROR_TITLE, LSTR(INFO_DB_UPDATE_ERROR), 1); + } else { + ui_info(INFO_SUCCESS_TITLE, LSTR(INFO_DB_UPDATE_OK), 1); + } +} diff --git a/app/core/updater.h b/app/core/updater.h new file mode 100644 index 0000000..1de1a1f --- /dev/null +++ b/app/core/updater.h @@ -0,0 +1,6 @@ +#ifndef _UPDATER_H_ +#define _UPDATER_H_ + +void updater_database_run(); + +#endif diff --git a/app/ethereum/eth_db.c b/app/ethereum/eth_db.c index beafcec..7459db8 100644 --- a/app/ethereum/eth_db.c +++ b/app/ethereum/eth_db.c @@ -51,6 +51,10 @@ fs_action_t _eth_db_match_erc20(void* ctx, fs_entry_t* entry) { return FS_REJECT; } +fs_action_t _eth_db_match_all(void* ctx, fs_entry_t* entry) { + return ((entry->magic == FS_PAIRING_CHAIN) || (entry->magic == FS_PAIRING_ERC20)) ? FS_REJECT : FS_ACCEPT; +} + app_err_t eth_db_lookup_chain(chain_desc_t* chain) { struct chain_raw_desc* chain_data = (struct chain_raw_desc*) fs_find(_eth_db_match_chain, chain); @@ -78,3 +82,13 @@ app_err_t eth_db_lookup_erc20(erc20_desc_t* erc20) { return ERR_OK; } + +app_err_t eth_db_update(fs_entry_t* entries, size_t len) { + app_err_t err = fs_erase_all(_eth_db_match_all, NULL); + + if (err != ERR_OK) { + return err; + } + + return fs_write(entries, len); +} diff --git a/app/ethereum/eth_db.h b/app/ethereum/eth_db.h index e73d62e..7910223 100644 --- a/app/ethereum/eth_db.h +++ b/app/ethereum/eth_db.h @@ -20,5 +20,6 @@ typedef struct { app_err_t eth_db_lookup_chain(chain_desc_t* chain); app_err_t eth_db_lookup_erc20(erc20_desc_t* erc20); +app_err_t eth_db_update(fs_entry_t* entries, size_t len); #endif diff --git a/app/qrcode/qrscan.c b/app/qrcode/qrscan.c index cb83f18..d4bf884 100644 --- a/app/qrcode/qrscan.c +++ b/app/qrcode/qrscan.c @@ -39,6 +39,12 @@ app_err_t qrscan_deserialize(ur_t* ur) { case ETH_SIGN_REQUEST: err = cbor_decode_eth_sign_request(ur->data, ur->data_len, g_ui_cmd.params.qrscan.out, NULL) == ZCBOR_SUCCESS ? ERR_OK : ERR_DATA; break; + case FS_DATA: + data_t* data = g_ui_cmd.params.qrscan.out; + data->data = ur->data; + data->len = ur->data_len; + err = ERR_OK; + break; default: err = ERR_DATA; break; diff --git a/app/tasks/core_task.c b/app/tasks/core_task.c index fc9dbc0..ccdbb8f 100644 --- a/app/tasks/core_task.c +++ b/app/tasks/core_task.c @@ -1,4 +1,5 @@ #include "core/core.h" +#include "core/updater.h" #include "keycard/keycard.h" static inline void core_action_run(i18n_str_id_t menu) { @@ -9,6 +10,9 @@ static inline void core_action_run(i18n_str_id_t menu) { case MENU_DISPLAY_PUBLIC: core_display_public(); break; + case MENU_DB_UPDATE: + updater_database_run(); + break; default: //unhandled commands break; diff --git a/app/ui/english.c b/app/ui/english.c index d7a6d47..0c1ef1a 100644 --- a/app/ui/english.c +++ b/app/ui/english.c @@ -47,10 +47,14 @@ const char *const i18n_english_strings[] = { // Info messages "Error", + "Success", "Communication with the card lost.\n\nPlease remove it and insert it again", "The inserted card does not appear to be a Keycard. Please replace it with a Keycard", "Initialize your Keycard", "We will now proceed initializing your Keycard.\n\nYou will be required to choose a PIN for your card.\n\nPress OK to continue.", + "The database update was successful.", + "The new database data seems to be invalid.\n Check that you are using the correct site and try again.", + "Internal error while writing the new data, please try again.", // Mnemonic input "Seed loading", diff --git a/app/ui/i18n.h b/app/ui/i18n.h index 6d8c591..4d15ab6 100644 --- a/app/ui/i18n.h +++ b/app/ui/i18n.h @@ -23,7 +23,7 @@ typedef enum { MENU_INFO, MENU_VERIFY_FW, MENU_FW_UPGRADE, - MENU_DB_UPGRADE, + MENU_DB_UPDATE, MENU_BRIGHTNESS, MENU_SET_LANG, @@ -50,10 +50,14 @@ typedef enum { // Info messages INFO_ERROR_TITLE, + INFO_SUCCESS_TITLE, INFO_CARD_ERROR_MSG, INFO_NOT_KEYCARD, INFO_NEW_CARD_TITLE, INFO_NEW_CARD, + INFO_DB_UPDATE_OK, + INFO_DB_UPDATE_INVALID, + INFO_DB_UPDATE_ERROR, // Mnemonic input MNEMO_TITLE, diff --git a/app/ui/menu.c b/app/ui/menu.c index f385304..f851aef 100644 --- a/app/ui/menu.c +++ b/app/ui/menu.c @@ -23,7 +23,7 @@ const menu_t menu_settings = { {MENU_INFO, NULL}, {MENU_VERIFY_FW, NULL}, {MENU_FW_UPGRADE, NULL}, - {MENU_DB_UPGRADE, NULL}, + {MENU_DB_UPDATE, NULL}, {MENU_BRIGHTNESS, NULL}, {MENU_SET_LANG, NULL}, } diff --git a/app/ui/ui.c b/app/ui/ui.c index ca834cd..681f6d6 100644 --- a/app/ui/ui.c +++ b/app/ui/ui.c @@ -45,6 +45,14 @@ core_evt_t ui_display_qr(const uint8_t* data, uint32_t len, ur_type_t type) { return ui_signal_wait(0); } +core_evt_t ui_info(i18n_str_id_t title, const char* msg, uint8_t dismissable) { + g_ui_cmd.type = UI_CMD_INFO; + g_ui_cmd.params.info.dismissable = 0; + g_ui_cmd.params.info.title = title; + g_ui_cmd.params.info.msg = msg; + return ui_signal_wait(0); +} + void ui_card_inserted() { } @@ -53,30 +61,18 @@ void ui_card_removed() { } void ui_card_transport_error() { - g_ui_cmd.type = UI_CMD_INFO; - g_ui_cmd.params.info.dismissable = 0; - g_ui_cmd.params.info.title = INFO_ERROR_TITLE; - g_ui_cmd.params.info.msg = LSTR(INFO_CARD_ERROR_MSG); - ui_signal_wait(0); + ui_info(INFO_ERROR_TITLE, LSTR(INFO_CARD_ERROR_MSG), 0); } void ui_card_accepted() { } void ui_keycard_wrong_card() { - g_ui_cmd.type = UI_CMD_INFO; - g_ui_cmd.params.info.dismissable = 0; - g_ui_cmd.params.info.title = INFO_ERROR_TITLE; - g_ui_cmd.params.info.msg = LSTR(INFO_NOT_KEYCARD); - ui_signal_wait(0); + ui_info(INFO_ERROR_TITLE, LSTR(INFO_NOT_KEYCARD), 0); } void ui_keycard_not_initialized() { - g_ui_cmd.type = UI_CMD_INFO; - g_ui_cmd.params.info.dismissable = 1; - g_ui_cmd.params.info.title = INFO_NEW_CARD_TITLE; - g_ui_cmd.params.info.msg = LSTR(INFO_NEW_CARD); - ui_signal_wait(0); + ui_info(INFO_NEW_CARD_TITLE, LSTR(INFO_NEW_CARD), 1); } void ui_keycard_init_failed() { diff --git a/app/ui/ui.h b/app/ui/ui.h index 332aea3..008fd18 100644 --- a/app/ui/ui.h +++ b/app/ui/ui.h @@ -21,6 +21,7 @@ core_evt_t ui_menu(const char* title, const menu_t* menu, i18n_str_id_t* selecte core_evt_t ui_display_tx(const txContent_t* tx); core_evt_t ui_display_msg(const uint8_t* msg, uint32_t len); core_evt_t ui_display_qr(const uint8_t* data, uint32_t len, ur_type_t type); +core_evt_t ui_info(i18n_str_id_t title, const char* msg, uint8_t dismissable); void ui_card_inserted(); void ui_card_removed();