mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 14:28:07 +00:00
feat(legacy): Strict path validation for NEM.
This commit is contained in:
parent
88efd74710
commit
abb5ab74e3
@ -17,6 +17,21 @@
|
|||||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static bool fsm_nemCheckPath(uint32_t address_n_count,
|
||||||
|
const uint32_t *address_n, uint8_t network) {
|
||||||
|
if (nem_path_check(address_n_count, address_n, network, true)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_getSafetyCheckLevel() == SafetyCheckLevel_Strict &&
|
||||||
|
!nem_path_check(address_n_count, address_n, network, false)) {
|
||||||
|
fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsm_layoutPathWarning();
|
||||||
|
}
|
||||||
|
|
||||||
void fsm_msgNEMGetAddress(NEMGetAddress *msg) {
|
void fsm_msgNEMGetAddress(NEMGetAddress *msg) {
|
||||||
if (!msg->has_network) {
|
if (!msg->has_network) {
|
||||||
msg->network = NEM_NETWORK_MAINNET;
|
msg->network = NEM_NETWORK_MAINNET;
|
||||||
@ -31,11 +46,19 @@ void fsm_msgNEMGetAddress(NEMGetAddress *msg) {
|
|||||||
|
|
||||||
RESP_INIT(NEMAddress);
|
RESP_INIT(NEMAddress);
|
||||||
|
|
||||||
|
if (!fsm_nemCheckPath(msg->address_n_count, msg->address_n, msg->network)) {
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HDNode *node = fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->address_n,
|
HDNode *node = fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->address_n,
|
||||||
msg->address_n_count, NULL);
|
msg->address_n_count, NULL);
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
|
||||||
if (!hdnode_get_nem_address(node, msg->network, resp->address)) return;
|
if (!hdnode_get_nem_address(node, msg->network, resp->address)) {
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg->has_show_display && msg->show_display) {
|
if (msg->has_show_display && msg->show_display) {
|
||||||
char desc[16];
|
char desc[16];
|
||||||
@ -116,6 +139,12 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) {
|
|||||||
|
|
||||||
RESP_INIT(NEMSignedTx);
|
RESP_INIT(NEMSignedTx);
|
||||||
|
|
||||||
|
if (!fsm_nemCheckPath(msg->transaction.address_n_count,
|
||||||
|
msg->transaction.address_n, msg->transaction.network)) {
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HDNode *node =
|
HDNode *node =
|
||||||
fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->transaction.address_n,
|
fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->transaction.address_n,
|
||||||
msg->transaction.address_n_count, NULL);
|
msg->transaction.address_n_count, NULL);
|
||||||
@ -317,6 +346,11 @@ void fsm_msgNEMDecryptMessage(NEMDecryptMessage *msg) {
|
|||||||
|
|
||||||
CHECK_PIN
|
CHECK_PIN
|
||||||
|
|
||||||
|
if (!fsm_nemCheckPath(msg->address_n_count, msg->address_n, msg->network)) {
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const HDNode *node = fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->address_n,
|
const HDNode *node = fsm_getDerivedNode(ED25519_KECCAK_NAME, msg->address_n,
|
||||||
msg->address_n_count, NULL);
|
msg->address_n_count, NULL);
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "nem2.h"
|
#include "nem2.h"
|
||||||
|
|
||||||
#include "aes/aes.h"
|
#include "aes/aes.h"
|
||||||
|
#include "crypto.h"
|
||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "layout2.h"
|
#include "layout2.h"
|
||||||
@ -741,3 +742,44 @@ bool nem_mosaicFormatLevy(const NEMMosaicDefinition *definition,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nem_path_check(uint32_t address_n_count, const uint32_t *address_n,
|
||||||
|
uint8_t network, bool check_coin_type) {
|
||||||
|
bool valid = (address_n_count >= 3);
|
||||||
|
valid = valid && (address_n[0] == (PATH_HARDENED | 44));
|
||||||
|
valid = valid && (address_n[1] == (PATH_HARDENED | 43) ||
|
||||||
|
address_n[1] == (PATH_HARDENED | 1));
|
||||||
|
valid = valid && (address_n[2] & PATH_HARDENED);
|
||||||
|
valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
|
||||||
|
|
||||||
|
if (address_n_count == 3) {
|
||||||
|
// 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'
|
||||||
|
// No further checks required.
|
||||||
|
} else if (address_n_count == 5) {
|
||||||
|
// NanoWallet compatibility path
|
||||||
|
// "m/44'/coin_type'/account'/0'/0'"
|
||||||
|
valid = valid && (address_n[3] == (PATH_HARDENED | 0));
|
||||||
|
valid = valid && (address_n[4] == (PATH_HARDENED | 0));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_coin_type) {
|
||||||
|
// Check that the appropriate coin_type is set for the given network.
|
||||||
|
switch (network) {
|
||||||
|
case NEM_NETWORK_MAINNET:
|
||||||
|
case NEM_NETWORK_MIJIN:
|
||||||
|
valid = valid && (address_n[1] == (PATH_HARDENED | 43));
|
||||||
|
break;
|
||||||
|
case NEM_NETWORK_TESTNET:
|
||||||
|
valid = valid && (address_n[1] == (PATH_HARDENED | 1));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
@ -100,6 +100,9 @@ bool nem_mosaicFormatLevy(const NEMMosaicDefinition *definition,
|
|||||||
uint64_t quantity, const bignum256 *multiplier,
|
uint64_t quantity, const bignum256 *multiplier,
|
||||||
uint8_t network, char *str_out, size_t size);
|
uint8_t network, char *str_out, size_t size);
|
||||||
|
|
||||||
|
bool nem_path_check(uint32_t address_n_count, const uint32_t *address_n,
|
||||||
|
uint8_t network, bool check_coin_type);
|
||||||
|
|
||||||
static inline void nem_mosaicFormatName(const char *namespace,
|
static inline void nem_mosaicFormatName(const char *namespace,
|
||||||
const char *mosaic, char *str_out,
|
const char *mosaic, char *str_out,
|
||||||
size_t size) {
|
size_t size) {
|
||||||
|
Loading…
Reference in New Issue
Block a user