diff --git a/legacy/firmware/fsm_msg_stellar.h b/legacy/firmware/fsm_msg_stellar.h index 5eb4e41ac3..44d920d872 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 886a68d624..55dde2337a 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 7ba4e8353f..6e4163f87e 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