From 35151c61579c117fcabc44a2bd0e27c91b7f5ce7 Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Wed, 26 Jan 2022 18:47:20 +0100 Subject: [PATCH] feat(legacy): Strict path validation for Stellar. --- legacy/firmware/fsm_msg_stellar.h | 25 +++++++++++++++++++++++++ legacy/firmware/stellar.c | 13 +++++++++++++ legacy/firmware/stellar.h | 2 ++ 3 files changed, 40 insertions(+) diff --git a/legacy/firmware/fsm_msg_stellar.h b/legacy/firmware/fsm_msg_stellar.h index 5eb4e41ac..44d920d87 100644 --- a/legacy/firmware/fsm_msg_stellar.h +++ b/legacy/firmware/fsm_msg_stellar.h @@ -17,6 +17,20 @@ * along with this library. If not, see . */ +static bool fsm_stellarCheckPath(uint32_t address_n_count, + const uint32_t *address_n) { + if (stellar_path_check(address_n_count, address_n)) { + return true; + } + + if (config_getSafetyCheckLevel() == SafetyCheckLevel_Strict) { + fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path")); + return false; + } + + return fsm_layoutPathWarning(); +} + void fsm_msgStellarGetAddress(const StellarGetAddress *msg) { RESP_INIT(StellarAddress); @@ -24,10 +38,16 @@ void fsm_msgStellarGetAddress(const StellarGetAddress *msg) { CHECK_PIN + if (!fsm_stellarCheckPath(msg->address_n_count, msg->address_n)) { + layoutHome(); + return; + } + const HDNode *node = stellar_deriveNode(msg->address_n, msg->address_n_count); if (!node) { fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to derive private key")); + layoutHome(); return; } @@ -55,6 +75,11 @@ void fsm_msgStellarSignTx(const StellarSignTx *msg) { CHECK_INITIALIZED CHECK_PIN + if (!fsm_stellarCheckPath(msg->address_n_count, msg->address_n)) { + layoutHome(); + return; + } + if (!stellar_signingInit(msg)) { fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to derive private key")); diff --git a/legacy/firmware/stellar.c b/legacy/firmware/stellar.c index 886a68d62..55dde2337 100644 --- a/legacy/firmware/stellar.c +++ b/legacy/firmware/stellar.c @@ -2013,3 +2013,16 @@ void stellar_layoutTransactionDialog(const char *line1, const char *line2, line1, line2, line3, line4, line5, stellar_activeTx.address_n, stellar_activeTx.address_n_count, str_warning, false); } + +bool stellar_path_check(uint32_t address_n_count, const uint32_t *address_n) { + // SEP-0005 for non-UTXO-based currencies, defined by Stellar: + // https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md + // m/44'/coin_type'/account' + bool valid = (address_n_count == 3); + valid = valid && (address_n[0] == (PATH_HARDENED | 44)); + valid = valid && (address_n[1] == (PATH_HARDENED | 148) || + address_n[1] == (PATH_HARDENED | 1)); + valid = valid && (address_n[2] & PATH_HARDENED); + valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT); + return valid; +} diff --git a/legacy/firmware/stellar.h b/legacy/firmware/stellar.h index 7ba4e8353..6e4163f87 100644 --- a/legacy/firmware/stellar.h +++ b/legacy/firmware/stellar.h @@ -117,4 +117,6 @@ bool stellar_validateAddress(const char *str_address); bool stellar_getAddressBytes(const char *str_address, uint8_t *out_bytes); uint16_t stellar_crc16(uint8_t *bytes, uint32_t length); +bool stellar_path_check(uint32_t address_n_count, const uint32_t *address_n); + #endif