diff --git a/firmware/coins.c b/firmware/coins.c index 5c862f80a2..e6056da420 100644 --- a/firmware/coins.c +++ b/firmware/coins.c @@ -20,6 +20,8 @@ #include #include "coins.h" #include "address.h" +#include "ecdsa.h" +#include "base58.h" // filled CoinType Protobuf structure defined in https://github.com/trezor/trezor-common/blob/master/protob/types.proto#L133 // address types > 0xFF represent a two-byte prefix in big-endian order @@ -69,21 +71,32 @@ const CoinType *coinByAddressType(uint32_t address_type) return 0; } -bool coinExtractAddressType(const CoinType *coin, const uint8_t *addr, uint32_t *address_type) +bool coinExtractAddressType(const CoinType *coin, const char *addr, uint32_t *address_type) { - if (coin->has_address_type && address_check_prefix(addr, coin->address_type)) { + if (!addr) return false; + uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; + int len = base58_decode_check(addr, addr_raw, MAX_ADDR_RAW_SIZE); + if (len >= 21) { + return coinExtractAddressTypeRaw(coin, addr_raw, address_type); + } + return false; +} + +bool coinExtractAddressTypeRaw(const CoinType *coin, const uint8_t *addr_raw, uint32_t *address_type) +{ + if (coin->has_address_type && address_check_prefix(addr_raw, coin->address_type)) { *address_type = coin->address_type; return true; } - if (coin->has_address_type_p2sh && address_check_prefix(addr, coin->address_type_p2sh)) { + if (coin->has_address_type_p2sh && address_check_prefix(addr_raw, coin->address_type_p2sh)) { *address_type = coin->address_type_p2sh; return true; } - if (coin->has_address_type_p2wpkh && address_check_prefix(addr, coin->address_type_p2wpkh)) { + if (coin->has_address_type_p2wpkh && address_check_prefix(addr_raw, coin->address_type_p2wpkh)) { *address_type = coin->address_type_p2wpkh; return true; } - if (coin->has_address_type_p2wsh && address_check_prefix(addr, coin->address_type_p2wsh)) { + if (coin->has_address_type_p2wsh && address_check_prefix(addr_raw, coin->address_type_p2wsh)) { *address_type = coin->address_type_p2wsh; return true; } diff --git a/firmware/coins.h b/firmware/coins.h index 69cb002fee..46a70a7720 100644 --- a/firmware/coins.h +++ b/firmware/coins.h @@ -29,6 +29,7 @@ extern const CoinType coins[COINS_COUNT]; const CoinType *coinByShortcut(const char *shortcut); const CoinType *coinByName(const char *name); const CoinType *coinByAddressType(uint32_t address_type); -bool coinExtractAddressType(const CoinType *coin, const uint8_t *addr, uint32_t *address_type); +bool coinExtractAddressType(const CoinType *coin, const char *addr, uint32_t *address_type); +bool coinExtractAddressTypeRaw(const CoinType *coin, const uint8_t *addr_raw, uint32_t *address_type); #endif diff --git a/firmware/fsm.c b/firmware/fsm.c index b352392cca..04225a2775 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -754,13 +754,13 @@ void fsm_msgVerifyMessage(VerifyMessage *msg) } const CoinType *coin = fsm_getCoin(msg->coin_name); if (!coin) return; - layoutProgressSwipe("Verifying", 0); uint8_t addr_raw[MAX_ADDR_RAW_SIZE]; uint32_t address_type; - if (!coinExtractAddressType(coin, (const uint8_t *)msg->address, &address_type) || !ecdsa_address_decode(msg->address, address_type, addr_raw)) { + if (!coinExtractAddressType(coin, msg->address, &address_type) || !ecdsa_address_decode(msg->address, address_type, addr_raw)) { fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid address"); return; } + layoutProgressSwipe("Verifying", 0); if (msg->signature.size == 65 && cryptoMessageVerify(coin, msg->message.bytes, msg->message.size, address_type, addr_raw, msg->signature.bytes) == 0) { layoutVerifyAddress(msg->address); if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {