diff --git a/firmware/fsm.c b/firmware/fsm.c index ca3c997cdc..4740c93d92 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -31,6 +31,8 @@ #include "protect.h" #include "pinmatrix.h" #include "layout2.h" +#include "address.h" +#include "base58.h" #include "ecdsa.h" #include "reset.h" #include "recovery.h" @@ -608,6 +610,7 @@ void fsm_msgGetAddress(GetAddress *msg) HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n, msg->address_n_count); if (!node) return; hdnode_fill_public_key(node); + int is_segwit = 0; if (msg->has_multisig) { layoutProgressSwipe("Preparing", 0); @@ -625,11 +628,52 @@ void fsm_msgGetAddress(GetAddress *msg) ripemd160(buf, 32, buf + 1); buf[0] = coin->address_type_p2sh; // multisig cointype base58_encode_check(buf, 21, resp->address, sizeof(resp->address)); + } else if (msg->has_script_type + && msg->script_type == InputScriptType_SPENDWITNESS + && coin->has_address_type_p2wpkh) { + uint8_t raw[22+4]; + int prelen = address_prefix_bytes_len(coin->address_type_p2wpkh); + address_write_prefix_bytes(coin->address_type_p2wpkh, raw); + raw[prelen] = 0; // version byte + raw[prelen + 1] = 0; // always 0, see bip-142 + ecdsa_get_pubkeyhash(node->public_key, raw + prelen + 2); + if (!base58_encode_check(raw, prelen + 22, resp->address, sizeof(resp->address))) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, "Can't encode address"); + layoutHome(); + return; + } + is_segwit = 1; + } else if (msg->has_script_type + && msg->script_type == InputScriptType_SPENDP2SHWITNESS + && coin->has_address_type_p2sh) { + uint8_t script[22]; + uint8_t digest[32]; + int prelen = address_prefix_bytes_len(coin->address_type_p2sh); + script[0] = 0; // version byte + script[1] = 20; // push 20 bytes + ecdsa_get_pubkeyhash(node->public_key, script + 2); + sha256_Raw(script, 22, digest); + ripemd160(digest, 32, digest + prelen); + address_write_prefix_bytes(coin->address_type_p2sh, digest); + if (!base58_encode_check(digest, 21, resp->address, sizeof(resp->address))) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, "Can't encode address"); + layoutHome(); + return; + } + is_segwit = 1; } else { ecdsa_get_address(node->public_key, coin->address_type, resp->address, sizeof(resp->address)); } if (msg->has_show_display && msg->show_display) { + if (is_segwit) { + layoutSegwitWarning(); + if (!protectButton(ButtonRequestType_ButtonRequest_Address, true)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, "Show address cancelled"); + layoutHome(); + return; + } + } char desc[16]; if (msg->has_multisig) { strlcpy(desc, "Msig __ of __:", sizeof(desc)); diff --git a/firmware/layout2.c b/firmware/layout2.c index e7d49262ab..6a7612062b 100644 --- a/firmware/layout2.c +++ b/firmware/layout2.c @@ -391,3 +391,18 @@ void layoutU2FDialog(const char *verb, const char *appname, const BITMAP *appico } layoutDialog(appicon, NULL, verb, NULL, verb, "U2F security key?", NULL, appname, NULL, NULL); } + +void layoutSegwitWarning() +{ + layoutDialogSwipe(&bmp_icon_info, + "Cancel", + "Understood", + NULL, + "The following address", + "is for SegWit soft fork.", + NULL, + "It is unsafe to use", + "until segwit activates.", + NULL + ); +} diff --git a/firmware/layout2.h b/firmware/layout2.h index 458fa55fda..95633fa722 100644 --- a/firmware/layout2.h +++ b/firmware/layout2.h @@ -45,5 +45,6 @@ void layoutPublicKey(const uint8_t *pubkey); void layoutSignIdentity(const IdentityType *identity, const char *challenge); void layoutDecryptIdentity(const IdentityType *identity); void layoutU2FDialog(const char *verb, const char *appname, const BITMAP *appicon); +void layoutSegwitWarning(void); #endif diff --git a/firmware/protob/messages.options b/firmware/protob/messages.options index 9164ce6dba..66c8456bd4 100644 --- a/firmware/protob/messages.options +++ b/firmware/protob/messages.options @@ -32,7 +32,7 @@ PublicKey.xpub max_size:113 GetAddress.address_n max_count:8 GetAddress.coin_name max_size:17 -Address.address max_size:41 +Address.address max_size:60 EthereumGetAddress.address_n max_count:8 EthereumAddress.address max_size:20