1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-26 03:59:08 +00:00

sign_tx: require confirmation of inputs from other chains

This commit is contained in:
Jan Pochyla 2018-06-21 13:59:49 +02:00
parent fd35b4c5c9
commit 51df249949
4 changed files with 35 additions and 2 deletions

View File

@ -3,7 +3,7 @@ from trezor.messages.wire_types import TxAck
from trezor.messages.TxRequest import TxRequest from trezor.messages.TxRequest import TxRequest
from trezor.messages.RequestType import TXFINISHED from trezor.messages.RequestType import TXFINISHED
from apps.common import seed from apps.common import seed
from apps.wallet.sign_tx.helpers import UiConfirmOutput, UiConfirmTotal, UiConfirmFeeOverThreshold from apps.wallet.sign_tx.helpers import UiConfirmOutput, UiConfirmTotal, UiConfirmFeeOverThreshold, UiConfirmForeignAddress
@ui.layout @ui.layout
@ -41,6 +41,8 @@ async def sign_tx(ctx, msg):
elif isinstance(req, UiConfirmFeeOverThreshold): elif isinstance(req, UiConfirmFeeOverThreshold):
res = await layout.confirm_feeoverthreshold(ctx, req.fee, req.coin) res = await layout.confirm_feeoverthreshold(ctx, req.fee, req.coin)
progress.report_init() progress.report_init()
elif isinstance(req, UiConfirmForeignAddress):
res = await layout.confirm_foreign_address(ctx, req.address_n, req.coin)
else: else:
raise TypeError('Invalid signing instruction') raise TypeError('Invalid signing instruction')
return req return req

View File

@ -35,6 +35,13 @@ class UiConfirmFeeOverThreshold:
self.coin = coin self.coin = coin
class UiConfirmForeignAddress:
def __init__(self, address_n: list, coin: CoinInfo):
self.address_n = address_n
self.coin = coin
def confirm_output(output: TxOutputType, coin: CoinInfo): def confirm_output(output: TxOutputType, coin: CoinInfo):
return (yield UiConfirmOutput(output, coin)) return (yield UiConfirmOutput(output, coin))
@ -47,6 +54,10 @@ def confirm_feeoverthreshold(fee: int, coin: CoinInfo):
return (yield UiConfirmFeeOverThreshold(fee, coin)) return (yield UiConfirmFeeOverThreshold(fee, coin))
def confirm_foreign_address(address_n: list, coin: CoinInfo):
return (yield UiConfirmForeignAddress(address_n, coin))
def request_tx_meta(tx_req: TxRequest, tx_hash: bytes=None): def request_tx_meta(tx_req: TxRequest, tx_hash: bytes=None):
tx_req.request_type = TXMETA tx_req.request_type = TXMETA
tx_req.details.tx_hash = tx_hash tx_req.details.tx_hash = tx_hash

View File

@ -4,6 +4,7 @@ from trezor.utils import chunks, format_amount
from trezor.ui.text import Text from trezor.ui.text import Text
from trezor.messages import ButtonRequestType from trezor.messages import ButtonRequestType
from trezor.messages import OutputScriptType from trezor.messages import OutputScriptType
from apps.common import coins
from apps.common.confirm import confirm from apps.common.confirm import confirm
from apps.common.confirm import hold_to_confirm from apps.common.confirm import hold_to_confirm
@ -53,3 +54,12 @@ async def confirm_feeoverthreshold(ctx, fee, coin):
'Continue?', icon_color=ui.GREEN) 'Continue?', icon_color=ui.GREEN)
return await confirm(ctx, content, ButtonRequestType.FeeOverThreshold) return await confirm(ctx, content, ButtonRequestType.FeeOverThreshold)
async def confirm_foreign_address(ctx, address_n, coin):
content = Text('Confirm sending', ui.ICON_SEND,
'Trying to spend',
'coins from another chain.',
'Continue?', icon_color=ui.RED)
return await confirm(ctx, content, ButtonRequestType.SignTx)

View File

@ -86,6 +86,9 @@ async def check_tx_fee(tx: SignTx, root: bip32.HDNode):
hash143.add_prevouts(txi) # all inputs are included (non-segwit as well) hash143.add_prevouts(txi) # all inputs are included (non-segwit as well)
hash143.add_sequence(txi) hash143.add_sequence(txi)
if not address_n_matches_coin(txi.address_n, coin):
await confirm_foreign_address(txi.address_n, coin)
if txi.multisig: if txi.multisig:
multifp.add(txi.multisig) multifp.add(txi.multisig)
@ -607,12 +610,19 @@ def input_check_wallet_path(txi: TxInputType, wallet_path: list) -> list:
'Transaction has changed during signing') 'Transaction has changed during signing')
def node_derive(root: bip32.HDNode, address_n: list): def node_derive(root: bip32.HDNode, address_n: list) -> bip32.HDNode:
node = root.clone() node = root.clone()
node.derive_path(address_n) node.derive_path(address_n)
return node return node
def address_n_matches_coin(address_n: list, coin: CoinInfo) -> bool:
bip44 = const(44 | 0x80000000)
if len(address_n) < 2 or address_n[0] != bip44 or address_n[1] == coin.slip44 | 0x80000000:
return True # path is not BIP44 or matches the coin
return False # path is BIP44 and does not match the coin
def ecdsa_sign(node: bip32.HDNode, digest: bytes) -> bytes: def ecdsa_sign(node: bip32.HDNode, digest: bytes) -> bytes:
sig = secp256k1.sign(node.private_key(), digest) sig = secp256k1.sign(node.private_key(), digest)
sigder = der.encode_seq((sig[1:33], sig[33:65])) sigder = der.encode_seq((sig[1:33], sig[33:65]))