mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-23 06:48:16 +00:00
wallet/signing: restrict segwit change output
This commit is contained in:
parent
8b85078730
commit
69d030a8fa
@ -59,6 +59,7 @@ async def check_tx_fee(tx: SignTx, root):
|
|||||||
tx_req.details = TxRequestDetailsType()
|
tx_req.details = TxRequestDetailsType()
|
||||||
|
|
||||||
total_in = 0 # sum of input amounts
|
total_in = 0 # sum of input amounts
|
||||||
|
segwit_in = 0 # sum of segwit input amounts
|
||||||
total_out = 0 # sum of output amounts
|
total_out = 0 # sum of output amounts
|
||||||
change_out = 0 # change output amount
|
change_out = 0 # change output amount
|
||||||
wallet_path = [] # common prefix of input paths
|
wallet_path = [] # common prefix of input paths
|
||||||
@ -82,6 +83,7 @@ async def check_tx_fee(tx: SignTx, root):
|
|||||||
raise SigningError(FailureType.DataError,
|
raise SigningError(FailureType.DataError,
|
||||||
'Segwit input without amount')
|
'Segwit input without amount')
|
||||||
segwit[i] = True
|
segwit[i] = True
|
||||||
|
segwit_in += txi.amount
|
||||||
total_in += txi.amount
|
total_in += txi.amount
|
||||||
elif txi.script_type == InputScriptType.SPENDADDRESS:
|
elif txi.script_type == InputScriptType.SPENDADDRESS:
|
||||||
segwit[i] = False
|
segwit[i] = False
|
||||||
@ -97,7 +99,7 @@ async def check_tx_fee(tx: SignTx, root):
|
|||||||
txo_bin.amount = txo.amount
|
txo_bin.amount = txo.amount
|
||||||
txo_bin.script_pubkey = output_derive_script(txo, coin, root)
|
txo_bin.script_pubkey = output_derive_script(txo, coin, root)
|
||||||
weight.add_output(txo_bin.script_pubkey)
|
weight.add_output(txo_bin.script_pubkey)
|
||||||
if output_is_change(txo, wallet_path):
|
if output_is_change(txo, wallet_path, segwit_in):
|
||||||
if change_out != 0:
|
if change_out != 0:
|
||||||
raise SigningError(FailureType.ProcessError,
|
raise SigningError(FailureType.ProcessError,
|
||||||
'Only one change output is valid')
|
'Only one change output is valid')
|
||||||
@ -396,8 +398,15 @@ def get_address_for_change(o: TxOutputType, coin: CoinType, root):
|
|||||||
return get_address(input_script_type, coin, node_derive(root, o.address_n))
|
return get_address(input_script_type, coin, node_derive(root, o.address_n))
|
||||||
|
|
||||||
|
|
||||||
def output_is_change(o: TxOutputType, wallet_path: list) -> bool:
|
def output_is_change(o: TxOutputType, wallet_path: list, segwit_in: int) -> bool:
|
||||||
address_n = o.address_n
|
address_n = o.address_n
|
||||||
|
is_segwit = (o.script_type == OutputScriptType.PAYTOWITNESS or
|
||||||
|
o.script_type == OutputScriptType.PAYTOP2SHWITNESS)
|
||||||
|
if is_segwit and o.amount > segwit_in:
|
||||||
|
# if the output is segwit, make sure it doesn't spend more than what the
|
||||||
|
# segwit inputs paid. this is to prevent user being tricked into
|
||||||
|
# creating ANYONECANSPEND outputs before full segwit activation.
|
||||||
|
return False
|
||||||
return (address_n is not None and wallet_path is not None
|
return (address_n is not None and wallet_path is not None
|
||||||
and wallet_path == address_n[:-_BIP32_WALLET_DEPTH]
|
and wallet_path == address_n[:-_BIP32_WALLET_DEPTH]
|
||||||
and address_n[-2] == _BIP32_CHANGE_CHAIN
|
and address_n[-2] == _BIP32_CHANGE_CHAIN
|
||||||
|
Loading…
Reference in New Issue
Block a user