Merge branch 'release/21.12'

Conflicts:
	tests/device_tests/test_msg_signtx_invalid_path.py
	tests/ui_tests/fixtures.json
pull/1994/head
Martin Milata 2 years ago
commit ff5f965c44

@ -1 +0,0 @@
Cardano root is derived together with the normal master secret.

@ -1 +0,0 @@
Session must be configured with Initialize(derive_cardano=True), otherwise Cardano functions will fail.

@ -1 +0,0 @@
Support no_script_type option in SignMessage.

@ -1 +0,0 @@
Show address confirmation in SignMessage.

@ -1 +0,0 @@
Remove altcoin message definitions from bitcoin-only build.

@ -1 +0,0 @@
Update QR-code-generator library version.

@ -1 +0,0 @@
Avoid accidental build with broken stack protector

@ -1 +0,0 @@
Support sending to Taproot addresses.

@ -1 +0,0 @@
Support spending from Taproot UTXOs.

@ -1 +0,0 @@
Support replacement transactions with Taproot inputs in Bitcoin.

@ -1 +0,0 @@
Support pre-signed external Taproot inputs in Bitcoin.

@ -1 +0,0 @@
Support GetAddress for Taproot addresses.

@ -1 +0,0 @@
Show warning dialog in SignMessage if a non-standard path is used.

@ -1 +0,0 @@
Disable previous transaction streaming in Bitcoin if all internal inputs are Taproot.

@ -1 +0,0 @@
Support of BIP-340 Schnorr signatures (using secp256k1-zkp).

@ -1 +0,0 @@
Faster ECDSA signing and verification (using secp256k1-zkp).

@ -1 +0,0 @@
Support for Taproot descriptors

@ -1 +0,0 @@
Type-checking enabled for apps.stellar

@ -1 +0,0 @@
Most Stellar fields are now required on protobuf level

@ -1 +0,0 @@
Timebounds must be set for a Stellar transaction

@ -1 +0,0 @@
Ethereum: support 64-bit chain IDs

@ -1 +0,0 @@
Support for Cardano multi-sig transactions, token minting, script addresses, multi-sig keys, minting keys and native script verification

@ -1 +0,0 @@
For compatibility with other Cardano implementations, it is now possible to specify which Cardano derivation type is used.

@ -1 +0,0 @@
Cardano derivation type must be specified for all Cardano functions.

@ -1 +0,0 @@
Updated micropython to version 1.17.

@ -1 +0,0 @@
Full type-checking for Ethereum app

@ -1 +0,0 @@
Ethereum non-EIP-155 cross-chain signing is no longer supported.

@ -1 +0,0 @@
Errors from protobuf decoding are now more expressive.

@ -1 +0,0 @@
Ethereum: make it optional to view the entire data field when signing transaction.

@ -1 +0,0 @@
Ethereum - support for EIP712 - signing typed data

@ -1 +0,0 @@
Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp.

@ -1 +0,0 @@
Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp, StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp and StellarCreatePassiveOfferOp to StellarCreatePassiveSellOfferOp.

@ -1 +0,0 @@
Add script_pubkey field to TxInput message.

@ -1 +0,0 @@
Remove BELL, ZNY support.

@ -1 +0,0 @@
Convert timestamps to human-readable dates and times.

@ -4,6 +4,57 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 2.4.3 [8th December 2021]
### Added
- Convert timestamps to human-readable dates and times. [#741]
- Support no_script_type option in SignMessage. [#1586]
- Show address confirmation in SignMessage. [#1586]
- Support pre-signed external Taproot inputs in Bitcoin. [#1656]
- Show warning dialog in SignMessage if a non-standard path is used. [#1656]
- Support spending from Taproot UTXOs. [#1656]
- Support GetAddress for Taproot addresses. [#1656]
- Support sending to Taproot addresses. [#1656]
- Support replacement transactions with Taproot inputs in Bitcoin. [#1656]
- Support of BIP-340 Schnorr signatures (using secp256k1-zkp). [#1678]
- Support for Taproot descriptors. [#1710]
- Ethereum: support 64-bit chain IDs. [#1771]
- Support for Cardano multi-sig transactions, token minting, script addresses, multi-sig keys, minting keys and native script verification. [#1772]
- For compatibility with other Cardano implementations, it is now possible to specify which Cardano derivation type is used. [#1783]
- Full type-checking for Ethereum app. [#1794]
- Ethereum - support for EIP712 - signing typed data. [#1835]
- Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp. [#1838]
- Add script_pubkey field to TxInput message. [#1857]
### Changed
- Cardano root is derived together with the normal master secret. [#1231]
- Update QR-code-generator library version. [#1639]
- Faster ECDSA signing and verification (using secp256k1-zkp). [#1678]
- Most Stellar fields are now required on protobuf level. [#1755]
- Type-checking enabled for apps.stellar. [#1755]
- Updated micropython to version 1.17. [#1789]
- Errors from protobuf decoding are now more expressive. [#1811]
### Removed
- Disable previous transaction streaming in Bitcoin if all internal inputs are Taproot. [#1656]
- Remove BELL, ZNY support. [#1872]
### Fixed
- Remove altcoin message definitions from bitcoin-only build. [#1633]
- Ethereum: make it optional to view the entire data field when signing transaction. [#1819]
### Security
- Ensure that the user is always warned about non-standard paths.
- Avoid accidental build with broken stack protector. [#1642]
### Incompatible changes
- Session must be configured with Initialize(derive_cardano=True), otherwise Cardano functions will fail. [#1231]
- Timebounds must be set for a Stellar transaction. [#1755]
- Cardano derivation type must be specified for all Cardano functions. [#1783]
- Ethereum non-EIP-155 cross-chain signing is no longer supported. [#1794]
- Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp, StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp and StellarCreatePassiveOfferOp to StellarCreatePassiveSellOfferOp. [#1838]
## 2.4.2 [16th September 2021]
### Added
@ -395,6 +446,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
[#24]: https://github.com/trezor/trezor-firmware/issues/24
[#379]: https://github.com/trezor/trezor-firmware/issues/379
[#741]: https://github.com/trezor/trezor-firmware/issues/741
[#800]: https://github.com/trezor/trezor-firmware/issues/800
[#948]: https://github.com/trezor/trezor-firmware/issues/948
[#958]: https://github.com/trezor/trezor-firmware/issues/958
@ -427,6 +479,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
[#1190]: https://github.com/trezor/trezor-firmware/issues/1190
[#1193]: https://github.com/trezor/trezor-firmware/issues/1193
[#1206]: https://github.com/trezor/trezor-firmware/issues/1206
[#1231]: https://github.com/trezor/trezor-firmware/issues/1231
[#1246]: https://github.com/trezor/trezor-firmware/issues/1246
[#1249]: https://github.com/trezor/trezor-firmware/issues/1249
[#1271]: https://github.com/trezor/trezor-firmware/issues/1271
@ -456,20 +509,39 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
[#1557]: https://github.com/trezor/trezor-firmware/issues/1557
[#1565]: https://github.com/trezor/trezor-firmware/issues/1565
[#1581]: https://github.com/trezor/trezor-firmware/issues/1581
[#1586]: https://github.com/trezor/trezor-firmware/issues/1586
[#1604]: https://github.com/trezor/trezor-firmware/issues/1604
[#1606]: https://github.com/trezor/trezor-firmware/issues/1606
[#1620]: https://github.com/trezor/trezor-firmware/issues/1620
[#1633]: https://github.com/trezor/trezor-firmware/issues/1633
[#1639]: https://github.com/trezor/trezor-firmware/issues/1639
[#1642]: https://github.com/trezor/trezor-firmware/issues/1642
[#1647]: https://github.com/trezor/trezor-firmware/issues/1647
[#1650]: https://github.com/trezor/trezor-firmware/issues/1650
[#1656]: https://github.com/trezor/trezor-firmware/issues/1656
[#1658]: https://github.com/trezor/trezor-firmware/issues/1658
[#1659]: https://github.com/trezor/trezor-firmware/issues/1659
[#1671]: https://github.com/trezor/trezor-firmware/issues/1671
[#1672]: https://github.com/trezor/trezor-firmware/issues/1672
[#1678]: https://github.com/trezor/trezor-firmware/issues/1678
[#1683]: https://github.com/trezor/trezor-firmware/issues/1683
[#1704]: https://github.com/trezor/trezor-firmware/issues/1704
[#1705]: https://github.com/trezor/trezor-firmware/issues/1705
[#1707]: https://github.com/trezor/trezor-firmware/issues/1707
[#1708]: https://github.com/trezor/trezor-firmware/issues/1708
[#1710]: https://github.com/trezor/trezor-firmware/issues/1710
[#1744]: https://github.com/trezor/trezor-firmware/issues/1744
[#1755]: https://github.com/trezor/trezor-firmware/issues/1755
[#1765]: https://github.com/trezor/trezor-firmware/issues/1765
[#1767]: https://github.com/trezor/trezor-firmware/issues/1767
[#1771]: https://github.com/trezor/trezor-firmware/issues/1771
[#1772]: https://github.com/trezor/trezor-firmware/issues/1772
[#1783]: https://github.com/trezor/trezor-firmware/issues/1783
[#1789]: https://github.com/trezor/trezor-firmware/issues/1789
[#1794]: https://github.com/trezor/trezor-firmware/issues/1794
[#1811]: https://github.com/trezor/trezor-firmware/issues/1811
[#1819]: https://github.com/trezor/trezor-firmware/issues/1819
[#1835]: https://github.com/trezor/trezor-firmware/issues/1835
[#1838]: https://github.com/trezor/trezor-firmware/issues/1838
[#1857]: https://github.com/trezor/trezor-firmware/issues/1857
[#1872]: https://github.com/trezor/trezor-firmware/issues/1872

@ -5,8 +5,8 @@ from trezor.enums import OutputScriptType
from apps.common import safety_checks
from .. import keychain
from ..authorization import FEE_PER_ANONYMITY_DECIMALS
from ..keychain import validate_path_against_script_type
from . import helpers, tx_weight
from .tx_info import OriginalTxInfo, TxInfo
@ -55,6 +55,9 @@ class Approver:
if txi.orig_hash:
self.orig_total_in += txi.amount
async def check_internal_input(self, txi: TxInput) -> None:
pass
def add_external_input(self, txi: TxInput) -> None:
self.weight.add_input(txi)
self.total_in += txi.amount
@ -102,11 +105,22 @@ class BasicApprover(Approver):
self.change_count = 0 # the number of change-outputs
async def add_internal_input(self, txi: TxInput) -> None:
if not keychain.validate_path_against_script_type(self.coin, txi):
if not validate_path_against_script_type(self.coin, txi):
await helpers.confirm_foreign_address(txi.address_n)
await super().add_internal_input(txi)
async def check_internal_input(self, txi: TxInput) -> None:
if not validate_path_against_script_type(self.coin, txi):
# The following can be removed once we start validating script_pubkey in step3_verify_inputs().
if self.orig_total_in:
# Replacement transaction.
# This mitigates a cross-coin spending attack when safety checks are disabled.
raise wire.ProcessError(
"Non-standard paths not allowed in replacement transactions."
)
await helpers.confirm_foreign_address(txi.address_n)
def add_change_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
super().add_change_output(txo, script_pubkey)
self.change_count += 1
@ -293,6 +307,11 @@ class CoinJoinApprover(Approver):
await super().add_internal_input(txi)
async def check_internal_input(self, txi: TxInput) -> None:
# The following can be removed once we start validating script_pubkey in step3_verify_inputs().
if not self.authorization.check_sign_tx_input(txi, self.coin):
raise wire.ProcessError("Unauthorized path")
def add_change_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
super().add_change_output(txo, script_pubkey)
self._add_output(txo, script_pubkey)

@ -519,8 +519,9 @@ class Bitcoin:
self.write_tx_input_derived(self.serialized_tx, txi, key_sign_pub, b"")
def sign_bip143_input(self, i: int, txi: TxInput) -> tuple[bytes, bytes]:
self.tx_info.check_input(txi)
if self.taproot_only:
# Prevents an attacker from bypassing prev tx checking by providing a different
# script type than the one that was provided during the confirmation phase.
raise wire.ProcessError("Transaction has changed during signing")
node = self.keychain.derive(txi.address_n)
@ -547,7 +548,6 @@ class Bitcoin:
return public_key, signature
def sign_taproot_input(self, i: int, txi: TxInput) -> bytes:
self.tx_info.check_input(txi)
sigmsg_digest = self.tx_info.sig_hasher.hash341(
i,
self.tx_info.tx,
@ -560,6 +560,8 @@ class Bitcoin:
async def sign_segwit_input(self, i: int) -> None:
# STAGE_REQUEST_SEGWIT_WITNESS in legacy
txi = await helpers.request_tx_input(self.tx_req, i, self.coin)
self.tx_info.check_input(txi)
await self.approver.check_internal_input(txi)
if txi.script_type not in common.SEGWIT_INPUT_SCRIPT_TYPES:
raise wire.ProcessError("Transaction has changed during signing")
@ -662,6 +664,8 @@ class Bitcoin:
async def sign_nonsegwit_input(self, i: int) -> None:
if self.taproot_only:
# Prevents an attacker from bypassing prev tx checking by providing a different
# script type than the one that was provided during the confirmation phase.
raise wire.ProcessError("Transaction has changed during signing")
tx_digest, txi, node = await self.get_legacy_tx_digest(i, self.tx_info)

@ -16,6 +16,8 @@ if False:
class Bitcoinlike(Bitcoin):
async def sign_nonsegwit_bip143_input(self, i_sign: int) -> None:
txi = await helpers.request_tx_input(self.tx_req, i_sign, self.coin)
self.tx_info.check_input(txi)
await self.approver.check_internal_input(txi)
if txi.script_type not in NONSEGWIT_INPUT_SCRIPT_TYPES:
raise wire.ProcessError("Transaction has changed during signing")

@ -150,6 +150,9 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
)),
TxAckInput(tx=TxAckInputWrapper(input=inp1)),
helpers.UiConfirmForeignAddress(address_n=inp1.address_n),
True,
TxRequest(request_type=TXFINISHED, details=TxRequestDetailsType(), serialized=TxRequestSerializedType(
serialized_tx=unhexlify('02483045022100a7ca8f097525f9044e64376dc0a0f5d4aeb8d15d66808ba97979a0475b06b66502200597c8ebcef63e047f9aeef1a8001d3560470cf896c12f6990eec4faec599b950121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000'),
signature_index=0,
@ -278,6 +281,9 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
)),
TxAckInput(tx=TxAckInputWrapper(input=inp1)),
helpers.UiConfirmForeignAddress(address_n=inp1.address_n),
True,
TxRequest(request_type=TXFINISHED, details=TxRequestDetailsType(), serialized=TxRequestSerializedType(
serialized_tx=unhexlify('02483045022100a7ca8f097525f9044e64376dc0a0f5d4aeb8d15d66808ba97979a0475b06b66502200597c8ebcef63e047f9aeef1a8001d3560470cf896c12f6990eec4faec599b950121033add1f0e8e3c3136f7428dd4a4de1057380bd311f5b0856e2269170b4ffa65bf00000000'),
signature_index=0,

@ -1 +0,0 @@
Support no_script_type option in SignMessage.

@ -1 +0,0 @@
Show address confirmation in SignMessage.

@ -1 +0,0 @@
Implement pagination in SignMessage and VerifyMessage.

@ -1 +0,0 @@
Remove rest of altcoin logic from bitcoin-only build.

@ -1 +0,0 @@
Update QR-code-generator library version.

@ -1 +0,0 @@
Avoid accidental build with broken stack protector

@ -1 +0,0 @@
Support sending to Taproot addresses.

@ -1 +0,0 @@
Support GetAddress for Taproot addresses.

@ -1 +0,0 @@
Support spending from Taproot UTXOs.

@ -1 +0,0 @@
Disable previous transaction streaming in Bitcoin if all internal inputs are Taproot.

@ -1 +0,0 @@
Show warning dialog in SignMessage if a non-standard path is used.

@ -1 +0,0 @@
Support for Taproot descriptors

@ -1 +0,0 @@
Timebounds must be set for a Stellar transaction

@ -1 +0,0 @@
Ethereum: support 64-bit chain IDs

@ -1 +0,0 @@
Ethereum non-EIP-155 cross-chain signing is no longer supported.

@ -1 +0,0 @@
Support for Ethereum EIP-1559 transactions.

@ -1 +0,0 @@
Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp.

@ -1 +0,0 @@
Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp, StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp and StellarCreatePassiveOfferOp to StellarCreatePassiveSellOfferOp.

@ -1 +0,0 @@
Fix incorrect compile-time check of maximum protobuf message size.

@ -1 +0,0 @@
Add script_pubkey field to TxInput message.

@ -1 +0,0 @@
Remove BELL, ZNY support.

@ -1 +0,0 @@
Support of BIP-340 Schnorr signatures (using secp256k1-zkp).

@ -1 +0,0 @@
Faster ECDSA signing and verification (using secp256k1-zkp).

@ -4,6 +4,45 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 1.10.4 [8th December 2021]
### Added
- Support no_script_type option in SignMessage. [#1586]
- Implement pagination in SignMessage and VerifyMessage. [#1586]
- Show address confirmation in SignMessage. [#1586]
- Support GetAddress for Taproot addresses. [#1656]
- Support sending to Taproot addresses. [#1656]
- Support spending from Taproot UTXOs. [#1656]
- Support for Taproot descriptors. [#1710]
- Ethereum: support 64-bit chain IDs. [#1771]
- Support for Ethereum EIP-1559 transactions. [#1834]
- Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp. [#1838]
- Add script_pubkey field to TxInput message. [#1857]
- Support of BIP-340 Schnorr signatures (using secp256k1-zkp). [#1897]
### Changed
- Update QR-code-generator library version. [#1639]
- Show warning dialog in SignMessage if a non-standard path is used. [#1656]
- Disable previous transaction streaming in Bitcoin if all internal inputs are Taproot. [#1656]
- Faster ECDSA signing and verification (using secp256k1-zkp). [#1897]
### Removed
- Remove BELL, ZNY support. [#1872]
### Fixed
- Remove rest of altcoin logic from bitcoin-only build. [#1633]
- Fix incorrect compile-time check of maximum protobuf message size. [#1854]
### Security
- Ensure that the user is always warned about non-standard paths.
- Avoid accidental build with broken stack protector. [#1642]
### Incompatible changes
- Timebounds must be set for a Stellar transaction. [#1755]
- Ethereum non-EIP-155 cross-chain signing is no longer supported. [#1794]
- Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp, StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp and StellarCreatePassiveOfferOp to StellarCreatePassiveSellOfferOp. [#1838]
## 1.10.3 [16th September 2021]
### Added
@ -426,11 +465,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
[#1491]: https://github.com/trezor/trezor-firmware/issues/1491
[#1518]: https://github.com/trezor/trezor-firmware/issues/1518
[#1549]: https://github.com/trezor/trezor-firmware/issues/1549
[#1586]: https://github.com/trezor/trezor-firmware/issues/1586
[#1627]: https://github.com/trezor/trezor-firmware/issues/1627
[#1633]: https://github.com/trezor/trezor-firmware/issues/1633
[#1639]: https://github.com/trezor/trezor-firmware/issues/1639
[#1642]: https://github.com/trezor/trezor-firmware/issues/1642
[#1647]: https://github.com/trezor/trezor-firmware/issues/1647
[#1650]: https://github.com/trezor/trezor-firmware/issues/1650
[#1656]: https://github.com/trezor/trezor-firmware/issues/1656
[#1660]: https://github.com/trezor/trezor-firmware/issues/1660
[#1705]: https://github.com/trezor/trezor-firmware/issues/1705
[#1710]: https://github.com/trezor/trezor-firmware/issues/1710
[#1743]: https://github.com/trezor/trezor-firmware/issues/1743
[#1755]: https://github.com/trezor/trezor-firmware/issues/1755
[#1765]: https://github.com/trezor/trezor-firmware/issues/1765
[#1767]: https://github.com/trezor/trezor-firmware/issues/1767
[#1771]: https://github.com/trezor/trezor-firmware/issues/1771
[#1794]: https://github.com/trezor/trezor-firmware/issues/1794
[#1834]: https://github.com/trezor/trezor-firmware/issues/1834
[#1838]: https://github.com/trezor/trezor-firmware/issues/1838
[#1854]: https://github.com/trezor/trezor-firmware/issues/1854
[#1857]: https://github.com/trezor/trezor-firmware/issues/1857
[#1872]: https://github.com/trezor/trezor-firmware/issues/1872
[#1897]: https://github.com/trezor/trezor-firmware/issues/1897

@ -702,6 +702,14 @@ static bool derive_node(TxInputType *tinput) {
if (!coin_path_check(coin, tinput->script_type, tinput->address_n_count,
tinput->address_n, tinput->has_multisig,
CoinPathCheckLevel_BASIC)) {
if (is_replacement) {
fsm_sendFailure(
FailureType_Failure_ProcessError,
_("Non-standard paths not allowed in replacement transactions."));
layoutHome();
return false;
}
if (config_getSafetyCheckLevel() == SafetyCheckLevel_Strict) {
fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path"));
signing_abort();

@ -18,10 +18,12 @@ import pytest
from trezorlib import btc, device, messages
from trezorlib.exceptions import TrezorFailure
from trezorlib.tools import parse_path
from trezorlib.tools import H_, parse_path
from ...tx_cache import TxCache
from ..signtx import request_finished, request_input, request_meta, request_output
B = messages.ButtonRequestType
TX_CACHE_MAINNET = TxCache("Bitcoin")
TX_CACHE_BCASH = TxCache("Bcash")
@ -31,14 +33,19 @@ TXHASH_8cc1f4 = bytes.fromhex(
TXHASH_d5f65e = bytes.fromhex(
"d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"
)
pytestmark = pytest.mark.altcoin
TXHASH_fa80a9 = bytes.fromhex(
"fa80a9949f1094119195064462f54d0e0eabd3139becd4514ae635b8c7fe3a46"
)
TXHASH_5dfd1b = bytes.fromhex(
"5dfd1b037633adc7f84a17b2df31c9994fe50b3ab3e246c44c4ceff3d326f62e"
)
# Adapted from TestMsgSigntx.test_one_one_fee,
# only changed the coin from Bitcoin to Litecoin.
# Litecoin does not have strong replay protection using SIGHASH_FORKID,
# spending from Bitcoin path should fail.
@pytest.mark.altcoin
def test_invalid_path_fail(client):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC
@ -68,6 +75,7 @@ def test_invalid_path_fail(client):
# only changed the coin from Bitcoin to Litecoin and set safety checks to prompt.
# Litecoin does not have strong replay protection using SIGHASH_FORKID, but
# spending from Bitcoin path should pass with safety checks set to prompt.
@pytest.mark.altcoin
def test_invalid_path_prompt(client):
# tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
# input 0: 0.0039 BTC
@ -97,6 +105,7 @@ def test_invalid_path_prompt(client):
# only changed the coin from Bitcoin to Bcash.
# Bcash does have strong replay protection using SIGHASH_FORKID,
# spending from Bitcoin path should work.
@pytest.mark.altcoin
def test_invalid_path_pass_forkid(client):
# tx: 8cc1f4adf7224ce855cf535a5104594a0004cb3b640d6714fdb00b9128832dd5
# input 0: 0.0039 BTC
@ -116,3 +125,95 @@ def test_invalid_path_pass_forkid(client):
)
btc.sign_tx(client, "Bcash", [inp1], [out1], prev_txes=TX_CACHE_BCASH)
def test_attack_path_segwit(client):
# Scenario: The attacker falsely claims that the transaction uses Testnet paths to
# avoid the path warning dialog, but in step6_sign_segwit_inputs() uses Bitcoin paths
# to get a valid signature.
device.apply_settings(
client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
)
inp1 = messages.TxInputType(
# The actual input that the attcker wants to get signed.
address_n=parse_path("84'/0'/0'/0/0"),
amount=9426,
prev_hash=TXHASH_fa80a9,
prev_index=0,
script_type=messages.InputScriptType.SPENDWITNESS,
)
inp2 = messages.TxInputType(
# The actual input that the attcker wants to get signed.
# We need this one to be from a different account, so that the match checker
# allows the transaction to pass.
address_n=parse_path("84'/0'/1'/0/1"),
amount=7086,
prev_hash=TXHASH_5dfd1b,
prev_index=0,
script_type=messages.InputScriptType.SPENDWITNESS,
)
out1 = messages.TxOutputType(
# Attacker's Mainnet address encoded as Testnet.
address="tb1q694ccp5qcc0udmfwgp692u2s2hjpq5h407urtu",
script_type=messages.OutputScriptType.PAYTOADDRESS,
amount=9426 + 7086 - 500,
)
attack_count = 6
def attack_processor(msg):
nonlocal attack_count
# Make the inputs look like they are coming from Testnet paths until we reach the
# signing phase.
if attack_count > 0 and msg.tx.inputs and msg.tx.inputs[0] in (inp1, inp2):
attack_count -= 1
msg.tx.inputs[0].address_n[1] = H_(1)
return msg
with client:
client.set_filter(messages.TxAck, attack_processor)
client.set_expected_responses(
[
# Step: process inputs
request_input(0),
# Attacker bypasses warning about non-standard path.
request_input(1),
# Attacker bypasses warning about non-standard path.
# Step: approve outputs
request_output(0),
messages.ButtonRequest(code=B.ConfirmOutput),
messages.ButtonRequest(code=B.SignTx),
# Step: verify inputs
request_input(0),
request_meta(TXHASH_fa80a9),
request_input(0, TXHASH_fa80a9),
request_output(0, TXHASH_fa80a9),
request_output(1, TXHASH_fa80a9),
request_input(1),
request_meta(TXHASH_5dfd1b),
request_input(0, TXHASH_5dfd1b),
request_output(0, TXHASH_5dfd1b),
request_output(1, TXHASH_5dfd1b),
# Step: serialize inputs
request_input(0),
request_input(1),
# Step: serialize outputs
request_output(0),
# Step: sign segwit inputs
request_input(0),
# Trezor must warn about non-standard path before signing.
messages.ButtonRequest(code=B.UnknownDerivationPath),
request_input(1),
# Trezor must warn about non-standard path before signing.
messages.ButtonRequest(code=B.UnknownDerivationPath),
request_finished(),
]
)
btc.sign_tx(
client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_MAINNET
)

@ -0,0 +1,22 @@
{
"bin_outputs": [
{
"amount": 7086,
"script_pubkey": "0014f6740e521befc61400662d9489a5f744883ca681"
},
{
"amount": 20120,
"script_pubkey": "001404278d66e85ad1073d6f7a8eeee8b96ca633e6e8"
}
],
"inputs": [
{
"prev_hash": "939cda2b4b609be5f5772dea5885431e18a61834bcbe5e0f895d6dfa05d2cc70",
"prev_index": 0,
"script_sig": "",
"sequence": 4294967293
}
],
"lock_time": 0,
"version": 1
}

@ -0,0 +1,22 @@
{
"bin_outputs": [
{
"amount": 9426,
"script_pubkey": "0014ece6935b2a5a5b5ff997c87370b16fa10f164410"
},
{
"amount": 309896,
"script_pubkey": "a914dfe58cc93d35fb99e15436f47d3bbfce8203280687"
}
],
"inputs": [
{
"prev_hash": "86a6e02943dcd057cfbe349f2c2274478a3a1be908eb788606a6950e727a0d36",
"prev_index": 0,
"script_sig": "16001495f41f5c0e0ec2c7fe27f0ac4bd59a5632a40b5f",
"sequence": 4294967295
}
],
"lock_time": 0,
"version": 1
}

@ -186,8 +186,8 @@
"bitcoin-test_nonstandard_paths.py::test_signmessage[m-3'-100'-4-255-script_types1]": "4f73135d2ec9add695e0a22d855816558b4ba9329a2828f9c9930be6245bdc2d",
"bitcoin-test_nonstandard_paths.py::test_signmessage[m-4-255-script_types0]": "0988cc8bdc5879744bd33190fddc5b5aa137fdd7214abb003c8000a871d98f14",
"bitcoin-test_nonstandard_paths.py::test_signmessage[m-49-0-63-0-255-script_types4]": "540df94c73a4eed8fe88cdb475e2b31df752dca9e47b102792c01064ee432752",
"bitcoin-test_nonstandard_paths.py::test_signtx[m-1195487518-6-255-script_types3]": "37cfe119620536464ae42b3fbcae7b89d9272ad904da2bd8e8ae47b1024b4007",
"bitcoin-test_nonstandard_paths.py::test_signtx[m-1195487518-script_types2]": "27a03a5be542d1f5f76a839e65daec766c1d7de8ae4637404ffcfea8267ea0ec",
"bitcoin-test_nonstandard_paths.py::test_signtx[m-1195487518-6-255-script_types3]": "3fb1ec777c4c1a4e320740d050444077e118a0fbcfec96cb7e5ead203dfe01a2",
"bitcoin-test_nonstandard_paths.py::test_signtx[m-1195487518-script_types2]": "e83d90183a5899d8881271e27ce030ec252df9c4a32ca4097cad811431553c37",
"bitcoin-test_nonstandard_paths.py::test_signtx[m-3'-100'-4-255-script_types1]": "efbe785820901471b0e55f9fd743c84a29fe719c2e1c8e6b2f87b0a20ce43cb2",
"bitcoin-test_nonstandard_paths.py::test_signtx[m-4-255-script_types0]": "efbe785820901471b0e55f9fd743c84a29fe719c2e1c8e6b2f87b0a20ce43cb2",
"bitcoin-test_nonstandard_paths.py::test_signtx[m-49-0-63-0-255-script_types4]": "4392475bb51d2dd9316036ed268ee84bafb6f3f7b0d2e1ab6be69a63775d5f66",
@ -288,8 +288,9 @@
"bitcoin-test_signtx_external.py::test_p2wpkh_with_false_proof": "ca3bdc82d0ddd668d50635ddbc91019095311e0c165094a89b9ae6eda53abdd6",
"bitcoin-test_signtx_external.py::test_p2wpkh_with_proof": "42cd0f5d700519154f417176625282d5054c1068f39dcc61c2c0be6c26c31a89",
"bitcoin-test_signtx_external.py::test_p2wsh_external_presigned": "864fb0b756bef195c9140dc9d1d4878a801c709b880fa38c703ca8438adfedb8",
"bitcoin-test_signtx_invalid_path.py::test_attack_path_segwit": "3feaa01d47aa9757e9d74f668927fd1445493c367adff94215405eb8e0a2749b",
"bitcoin-test_signtx_invalid_path.py::test_invalid_path_fail": "1c100ce4b7c1e47e72428f390de0846c1ff933e9f07894872644a369a9422738",
"bitcoin-test_signtx_invalid_path.py::test_invalid_path_pass_forkid": "85d3c2f3c85e1bcf774f3067d7eb32396c444f351ad15e68a328f87cf6bdb338",
"bitcoin-test_signtx_invalid_path.py::test_invalid_path_pass_forkid": "ef98eb752ec5fa948c952def7599f57a2bc5240b2d6b1eec0e02cc9be5c3040f",
"bitcoin-test_signtx_invalid_path.py::test_invalid_path_prompt": "12e137210397357ed754af0f4618ef03312b3e884930f55727d1b034f969bfd5",
"bitcoin-test_signtx_mixed_inputs.py::test_non_segwit_segwit_inputs": "34cbf0075c03f13db8285b0ca9fd3e32dc3380ef95116d873754ec10c9801b99",
"bitcoin-test_signtx_mixed_inputs.py::test_non_segwit_segwit_non_segwit_inputs": "6bbb1dc3e786d7ccc05fa62405d979d768b36753d8e4b18159e0bc9638d43596",
@ -846,6 +847,10 @@
"test_msg_sd_protect.py::test_enable_disable": "aa09194fbab845cc64e1187bf2e634858a4c848ebfe2890b30ac9073f980cb96",
"test_msg_sd_protect.py::test_refresh": "19d6d1a7bfa9a6dcf7da2c320d01ba03152d08faa08a11ea2b3dc28ad57b1b91",
"test_msg_sd_protect.py::test_wipe": "9e4b9968e7967e93f19d669acadd53c128a857b72afd7e354a1a350274b8aeba",
"test_msg_signtx_invalid_path.py-test_attack_path_segwit": "3feaa01d47aa9757e9d74f668927fd1445493c367adff94215405eb8e0a2749b",
"test_msg_signtx_invalid_path.py-test_invalid_path_fail": "1c100ce4b7c1e47e72428f390de0846c1ff933e9f07894872644a369a9422738",
"test_msg_signtx_invalid_path.py-test_invalid_path_pass_forkid": "ef98eb752ec5fa948c952def7599f57a2bc5240b2d6b1eec0e02cc9be5c3040f",
"test_msg_signtx_invalid_path.py-test_invalid_path_prompt": "12e137210397357ed754af0f4618ef03312b3e884930f55727d1b034f969bfd5",
"test_msg_wipedevice.py::test_autolock_not_retained": "c18d2809f505e79bf61aef073a33897b251a3dadab7db9c890f5baaaa4412f4c",
"test_msg_wipedevice.py::test_wipe_device": "365729fd052a9765fb68444b0ec0661037db712bf077d2e2126d6a4e892710bd",
"test_passphrase_slip39_advanced.py::test_128bit_passphrase": "0d854e06e58ec8e27f04d8604002f1dcb8fee790bdac07cbabb94e3ed357abe3",

Loading…
Cancel
Save