From c60305d8f05f0689397cf21052d9c8f5e1506f5e Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Sun, 7 Nov 2021 21:02:49 +0100 Subject: [PATCH] feat(legacy): Implement pagination in SignMessage and VerifyMessage. --- legacy/firmware/.changelog.d/1586.added.2 | 1 + legacy/firmware/fsm.c | 43 +++++++++++++++++++++++ legacy/firmware/fsm.h | 3 ++ legacy/firmware/fsm_msg_coin.h | 8 ++--- legacy/firmware/fsm_msg_ethereum.h | 8 ++--- legacy/firmware/layout2.c | 32 +---------------- legacy/firmware/layout2.h | 4 +-- 7 files changed, 58 insertions(+), 41 deletions(-) create mode 100644 legacy/firmware/.changelog.d/1586.added.2 diff --git a/legacy/firmware/.changelog.d/1586.added.2 b/legacy/firmware/.changelog.d/1586.added.2 new file mode 100644 index 0000000000..5ddfd8e9ef --- /dev/null +++ b/legacy/firmware/.changelog.d/1586.added.2 @@ -0,0 +1 @@ +Implement pagination in SignMessage and VerifyMessage. diff --git a/legacy/firmware/fsm.c b/legacy/firmware/fsm.c index aa6d1cb302..2d8448a956 100644 --- a/legacy/firmware/fsm.c +++ b/legacy/firmware/fsm.c @@ -304,6 +304,49 @@ static bool fsm_layoutAddress(const char *address, const char *desc, } } +static bool fsm_layoutPaginated(const char *description, const uint8_t *msg, + uint32_t len, bool is_ascii) { + const char **str = NULL; + const uint32_t row_len = is_ascii ? 13 : 8; + do { + const uint32_t show_len = MIN(len, row_len * 4); + if (is_ascii) { + str = split_message(msg, show_len, row_len); + } else { + str = split_message_hex(msg, show_len); + } + + msg += show_len; + len -= show_len; + + const char *label = len > 0 ? _("Next") : _("Confirm"); + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), label, description, + str[0], str[1], str[2], str[3], NULL, NULL); + + if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + return false; + } + } while (len > 0); + + return true; +} + +bool fsm_layoutSignMessage(const uint8_t *msg, uint32_t len) { + if (is_valid_ascii(msg, len)) { + return fsm_layoutPaginated(_("Sign message?"), msg, len, true); + } else { + return fsm_layoutPaginated(_("Sign binary message?"), msg, len, false); + } +} + +bool fsm_layoutVerifyMessage(const uint8_t *msg, uint32_t len) { + if (is_valid_ascii(msg, len)) { + return fsm_layoutPaginated(_("Verified message?"), msg, len, true); + } else { + return fsm_layoutPaginated(_("Verified binary message?"), msg, len, false); + } +} + void fsm_msgRebootToBootloader(void) { layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _("Do you want to"), _("restart device in"), diff --git a/legacy/firmware/fsm.h b/legacy/firmware/fsm.h index bffb24ad8f..57a5e7ecee 100644 --- a/legacy/firmware/fsm.h +++ b/legacy/firmware/fsm.h @@ -135,4 +135,7 @@ void fsm_msgStellarBumpSequenceOp(const StellarBumpSequenceOp *msg); void fsm_msgRebootToBootloader(void); +bool fsm_layoutSignMessage(const uint8_t *msg, uint32_t len); +bool fsm_layoutVerifyMessage(const uint8_t *msg, uint32_t len); + #endif diff --git a/legacy/firmware/fsm_msg_coin.h b/legacy/firmware/fsm_msg_coin.h index 711d22e369..af03a5066f 100644 --- a/legacy/firmware/fsm_msg_coin.h +++ b/legacy/firmware/fsm_msg_coin.h @@ -286,8 +286,7 @@ void fsm_msgSignMessage(const SignMessage *msg) { return; } - layoutSignMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + if (!fsm_layoutSignMessage(msg->message.bytes, msg->message.size)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); layoutHome(); return; @@ -319,12 +318,13 @@ void fsm_msgVerifyMessage(const VerifyMessage *msg) { layoutHome(); return; } - layoutVerifyMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + + if (!fsm_layoutVerifyMessage(msg->message.bytes, msg->message.size)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); layoutHome(); return; } + fsm_sendSuccess(_("Message verified")); } else { fsm_sendFailure(FailureType_Failure_DataError, _("Invalid signature")); diff --git a/legacy/firmware/fsm_msg_ethereum.h b/legacy/firmware/fsm_msg_ethereum.h index e2f30eaba0..e95637de82 100644 --- a/legacy/firmware/fsm_msg_ethereum.h +++ b/legacy/firmware/fsm_msg_ethereum.h @@ -173,8 +173,7 @@ void fsm_msgEthereumSignMessage(const EthereumSignMessage *msg) { return; } - layoutSignMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + if (!fsm_layoutSignMessage(msg->message.bytes, msg->message.size)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); layoutHome(); return; @@ -202,12 +201,13 @@ void fsm_msgEthereumVerifyMessage(const EthereumVerifyMessage *msg) { layoutHome(); return; } - layoutVerifyMessage(msg->message.bytes, msg->message.size); - if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { + + if (!fsm_layoutVerifyMessage(msg->message.bytes, msg->message.size)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); layoutHome(); return; } + fsm_sendSuccess(_("Message verified")); layoutHome(); diff --git a/legacy/firmware/layout2.c b/legacy/firmware/layout2.c index 708fd59cdc..48b532c150 100644 --- a/legacy/firmware/layout2.c +++ b/legacy/firmware/layout2.c @@ -445,7 +445,7 @@ void layoutConfirmOmni(const uint8_t *data, uint32_t size) { NULL); } -static bool is_valid_ascii(const uint8_t *data, uint32_t size) { +bool is_valid_ascii(const uint8_t *data, uint32_t size) { for (uint32_t i = 0; i < size; i++) { if (data[i] < ' ' || data[i] > '~') { return false; @@ -603,36 +603,6 @@ void layoutConfirmNondefaultLockTime(uint32_t lock_time, } } -void layoutSignMessage(const uint8_t *msg, uint32_t len) { - const char **str = NULL; - if (!is_valid_ascii(msg, len)) { - str = split_message_hex(msg, len); - layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), - _("Sign binary message?"), str[0], str[1], str[2], str[3], - NULL, NULL); - } else { - str = split_message(msg, len, 20); - layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), - _("Sign message?"), str[0], str[1], str[2], str[3], NULL, - NULL); - } -} - -void layoutVerifyMessage(const uint8_t *msg, uint32_t len) { - const char **str = NULL; - if (!is_valid_ascii(msg, len)) { - str = split_message_hex(msg, len); - layoutDialogSwipe(&bmp_icon_info, _("Cancel"), _("Confirm"), - _("Verified binary message"), str[0], str[1], str[2], - str[3], NULL, NULL); - } else { - str = split_message(msg, len, 20); - layoutDialogSwipe(&bmp_icon_info, _("Cancel"), _("Confirm"), - _("Verified message"), str[0], str[1], str[2], str[3], - NULL, NULL); - } -} - void layoutVerifyAddress(const CoinInfo *coin, const char *address) { render_address_dialog(coin, address, _("Confirm address?"), _("Message signed by:"), 0); diff --git a/legacy/firmware/layout2.h b/legacy/firmware/layout2.h index 52427b7647..62d2c30464 100644 --- a/legacy/firmware/layout2.h +++ b/legacy/firmware/layout2.h @@ -65,9 +65,7 @@ void layoutFeeOverThreshold(const CoinInfo *coin, AmountUnit amount_unit, void layoutChangeCountOverThreshold(uint32_t change_count); void layoutConfirmNondefaultLockTime(uint32_t lock_time, bool lock_time_disabled); -void layoutSignMessage(const uint8_t *msg, uint32_t len); void layoutVerifyAddress(const CoinInfo *coin, const char *address); -void layoutVerifyMessage(const uint8_t *msg, uint32_t len); void layoutCipherKeyValue(bool encrypt, const char *key); void layoutEncryptMessage(const uint8_t *msg, uint32_t len, bool signing); void layoutDecryptMessage(const uint8_t *msg, uint32_t len, @@ -110,4 +108,6 @@ void layoutConfirmSafetyChecks(SafetyCheckLevel safety_checks_level); const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen); const char **split_message_hex(const uint8_t *msg, uint32_t len); +bool is_valid_ascii(const uint8_t *data, uint32_t size); + #endif