mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-19 00:29:03 +00:00
fixup! refactor(tests): move set_input_flow to SessionDebugWrapper context manager
but now the other way around
This commit is contained in:
parent
23a4c425fa
commit
0091823bd3
@ -947,7 +947,6 @@ class SessionDebugWrapper(Session):
|
||||
if isinstance(session, SessionDebugWrapper):
|
||||
raise Exception("Cannot wrap already wrapped session!")
|
||||
self.__dict__["_session"] = session
|
||||
self.reset_debug_features()
|
||||
|
||||
def __getattr__(self, name: str) -> t.Any:
|
||||
return getattr(self._session, name)
|
||||
@ -962,59 +961,24 @@ class SessionDebugWrapper(Session):
|
||||
def protocol_version(self) -> int:
|
||||
return self.client.protocol_version
|
||||
|
||||
@property
|
||||
def debug_client(self) -> TrezorClientDebugLink:
|
||||
if not isinstance(self.client, TrezorClientDebugLink):
|
||||
raise Exception("Debug client not available")
|
||||
return self.client
|
||||
|
||||
def _write(self, msg: t.Any) -> None:
|
||||
self._session._write(self._filter_message(msg))
|
||||
self._session._write(self.debug_client._filter_message(msg))
|
||||
|
||||
def _read(self) -> t.Any:
|
||||
resp = self._filter_message(self._session._read())
|
||||
if self.actual_responses is not None:
|
||||
self.actual_responses.append(resp)
|
||||
resp = self.debug_client._filter_message(self._session._read())
|
||||
if self.debug_client.actual_responses is not None:
|
||||
self.debug_client.actual_responses.append(resp)
|
||||
return resp
|
||||
|
||||
def resume(self) -> None:
|
||||
self._session.resume()
|
||||
|
||||
def set_expected_responses(
|
||||
self,
|
||||
expected: list["ExpectedMessage" | t.Tuple[bool, "ExpectedMessage"]],
|
||||
) -> None:
|
||||
"""Set a sequence of expected responses to session calls.
|
||||
|
||||
Within a given with-block, the list of received responses from device must
|
||||
match the list of expected responses, otherwise an ``AssertionError`` is raised.
|
||||
|
||||
If an expected response is given a field value other than ``None``, that field value
|
||||
must exactly match the received field value. If a given field is ``None``
|
||||
(or unspecified) in the expected response, the received field value is not
|
||||
checked.
|
||||
|
||||
Each expected response can also be a tuple ``(bool, message)``. In that case, the
|
||||
expected response is only evaluated if the first field is ``True``.
|
||||
This is useful for differentiating sequences between Trezor models:
|
||||
|
||||
>>> trezor_one = session.features.model == "1"
|
||||
>>> session.set_expected_responses([
|
||||
>>> messages.ButtonRequest(code=ConfirmOutput),
|
||||
>>> (trezor_one, messages.ButtonRequest(code=ConfirmOutput)),
|
||||
>>> messages.Success(),
|
||||
>>> ])
|
||||
"""
|
||||
if not self.in_with_statement:
|
||||
raise RuntimeError("Must be called inside 'with' statement")
|
||||
|
||||
# make sure all items are (bool, message) tuples
|
||||
expected_with_validity = (
|
||||
e if isinstance(e, tuple) else (True, e) for e in expected
|
||||
)
|
||||
|
||||
# only apply those items that are (True, message)
|
||||
self.expected_responses = [
|
||||
MessageFilter.from_message_or_type(expected)
|
||||
for valid, expected in expected_with_validity
|
||||
if valid
|
||||
]
|
||||
self.actual_responses = []
|
||||
|
||||
def lock(self) -> None:
|
||||
"""Lock the device.
|
||||
|
||||
@ -1035,6 +999,214 @@ class SessionDebugWrapper(Session):
|
||||
btc.get_address(self, "Testnet", PASSPHRASE_TEST_PATH)
|
||||
self.refresh_features()
|
||||
|
||||
|
||||
class TrezorClientDebugLink(TrezorClient):
|
||||
# This class implements automatic responses
|
||||
# and other functionality for unit tests
|
||||
# for various callbacks, created in order
|
||||
# to automatically pass unit tests.
|
||||
#
|
||||
# This mixing should be used only for purposes
|
||||
# of unit testing, because it will fail to work
|
||||
# without special DebugLink interface provided
|
||||
# by the device.
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
transport: Transport,
|
||||
auto_interact: bool = True,
|
||||
open_transport: bool = True,
|
||||
debug_transport: Transport | None = None,
|
||||
) -> None:
|
||||
try:
|
||||
debug_transport = debug_transport or transport.find_debug()
|
||||
self.debug = DebugLink(debug_transport, auto_interact)
|
||||
if open_transport:
|
||||
self.debug.open()
|
||||
# try to open debuglink, see if it works
|
||||
assert self.debug.transport.ping()
|
||||
except Exception:
|
||||
if not auto_interact:
|
||||
self.debug = NullDebugLink()
|
||||
else:
|
||||
raise
|
||||
|
||||
if open_transport:
|
||||
transport.open()
|
||||
|
||||
# set transport explicitly so that sync_responses can work
|
||||
super().__init__(transport)
|
||||
|
||||
self.transport = transport
|
||||
self.ui: DebugUI = DebugUI(self.debug)
|
||||
|
||||
def get_pin(_msg: messages.PinMatrixRequest) -> str:
|
||||
try:
|
||||
pin = self.ui.get_pin()
|
||||
except Cancelled:
|
||||
raise
|
||||
return pin
|
||||
|
||||
self.pin_callback = get_pin
|
||||
self.button_callback = self.ui.button_request
|
||||
|
||||
self.sync_responses()
|
||||
|
||||
# So that we can choose right screenshotting logic (T1 vs TT)
|
||||
# and know the supported debug capabilities
|
||||
self.debug.model = self.model
|
||||
self.debug.version = self.version
|
||||
|
||||
self.reset_debug_features()
|
||||
|
||||
@property
|
||||
def layout_type(self) -> LayoutType:
|
||||
return self.debug.layout_type
|
||||
|
||||
def get_new_client(self) -> TrezorClientDebugLink:
|
||||
new_client = TrezorClientDebugLink(
|
||||
self.transport,
|
||||
self.debug.allow_interactions,
|
||||
open_transport=False,
|
||||
debug_transport=self.debug.transport,
|
||||
)
|
||||
new_client.debug.screenshot_recording_dir = self.debug.screenshot_recording_dir
|
||||
new_client.debug.t1_screenshot_directory = self.debug.t1_screenshot_directory
|
||||
new_client.debug.t1_screenshot_counter = self.debug.t1_screenshot_counter
|
||||
return new_client
|
||||
|
||||
def close_transport(self) -> None:
|
||||
self.transport.close()
|
||||
self.debug.close()
|
||||
|
||||
def lock(self) -> None:
|
||||
s = self.get_seedless_session()
|
||||
s.lock()
|
||||
|
||||
def get_session(
|
||||
self,
|
||||
passphrase: str | object = "",
|
||||
derive_cardano: bool = False,
|
||||
) -> SessionDebugWrapper:
|
||||
if isinstance(passphrase, str):
|
||||
passphrase = Mnemonic.normalize_string(passphrase)
|
||||
session = SessionDebugWrapper(
|
||||
super().get_session(
|
||||
passphrase,
|
||||
derive_cardano,
|
||||
)
|
||||
)
|
||||
return session
|
||||
|
||||
# FIXME: can be deleted
|
||||
def get_seedless_session(
|
||||
self, *args: t.Any, **kwargs: t.Any
|
||||
) -> SessionDebugWrapper:
|
||||
session = super().get_seedless_session(*args, **kwargs)
|
||||
if not isinstance(session, SessionDebugWrapper):
|
||||
session = SessionDebugWrapper(session)
|
||||
return session
|
||||
|
||||
def watch_layout(self, watch: bool = True) -> None:
|
||||
"""Enable or disable watching layout changes.
|
||||
|
||||
Since trezor-core v2.3.2, it is necessary to call `watch_layout()` before
|
||||
using `debug.wait_layout()`, otherwise layout changes are not reported.
|
||||
"""
|
||||
if self.version >= (2, 3, 2):
|
||||
# version check is necessary because otherwise we cannot reliably detect
|
||||
# whether and where to wait for reply:
|
||||
# - T1 reports unknown debuglink messages on the wirelink
|
||||
# - TT < 2.3.0 does not reply to unknown debuglink messages due to a bug
|
||||
self.debug.watch_layout(watch)
|
||||
|
||||
def use_pin_sequence(self, pins: t.Iterable[str]) -> None:
|
||||
"""Respond to PIN prompts from device with the provided PINs.
|
||||
The sequence must be at least as long as the expected number of PIN prompts.
|
||||
"""
|
||||
self.ui.pins = iter(pins)
|
||||
|
||||
def use_mnemonic(self, mnemonic: str) -> None:
|
||||
"""Use the provided mnemonic to respond to device.
|
||||
Only applies to T1, where device prompts the host for mnemonic words."""
|
||||
self.mnemonic = Mnemonic.normalize_string(mnemonic).split(" ")
|
||||
|
||||
def sync_responses(self) -> None:
|
||||
"""Synchronize Trezor device receiving with caller.
|
||||
|
||||
When a failed test does not read out the response, the next caller will write
|
||||
a request, but read the previous response -- while the device had already sent
|
||||
and placed into queue the new response.
|
||||
|
||||
This function will call `Ping` and read responses until it locates a `Success`
|
||||
with the expected text. This means that we are reading up-to-date responses.
|
||||
"""
|
||||
import secrets
|
||||
|
||||
# Start by canceling whatever is on screen. This will work to cancel T1 PIN
|
||||
# prompt, which is in TINY mode and does not respond to `Ping`.
|
||||
if self.protocol_version is ProtocolVersion.V1:
|
||||
assert isinstance(self.protocol, ProtocolV1Channel)
|
||||
self.protocol.write(messages.Cancel())
|
||||
resp = self.protocol.read()
|
||||
message = "SYNC" + secrets.token_hex(8)
|
||||
self.protocol.write(messages.Ping(message=message))
|
||||
while resp != messages.Success(message=message):
|
||||
try:
|
||||
resp = self.protocol.read()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def mnemonic_callback(self, _) -> str:
|
||||
word, pos = self.debug.read_recovery_word()
|
||||
if word:
|
||||
return word
|
||||
if pos:
|
||||
return self.mnemonic[pos - 1]
|
||||
|
||||
raise RuntimeError("Unexpected call")
|
||||
|
||||
def set_expected_responses(
|
||||
self,
|
||||
expected: list["ExpectedMessage" | t.Tuple[bool, "ExpectedMessage"]],
|
||||
) -> None:
|
||||
"""Set a sequence of expected responses to session calls.
|
||||
|
||||
Within a given with-block, the list of received responses from device must
|
||||
match the list of expected responses, otherwise an ``AssertionError`` is raised.
|
||||
|
||||
If an expected response is given a field value other than ``None``, that field value
|
||||
must exactly match the received field value. If a given field is ``None``
|
||||
(or unspecified) in the expected response, the received field value is not
|
||||
checked.
|
||||
|
||||
Each expected response can also be a tuple ``(bool, message)``. In that case, the
|
||||
expected response is only evaluated if the first field is ``True``.
|
||||
This is useful for differentiating sequences between Trezor models:
|
||||
|
||||
>>> trezor_one = session.features.model == "1"
|
||||
>>> client.set_expected_responses([
|
||||
>>> messages.ButtonRequest(code=ConfirmOutput),
|
||||
>>> (trezor_one, messages.ButtonRequest(code=ConfirmOutput)),
|
||||
>>> messages.Success(),
|
||||
>>> ])
|
||||
"""
|
||||
if not self.in_with_statement:
|
||||
raise RuntimeError("Must be called inside 'with' statement")
|
||||
|
||||
# make sure all items are (bool, message) tuples
|
||||
expected_with_validity = (
|
||||
e if isinstance(e, tuple) else (True, e) for e in expected
|
||||
)
|
||||
|
||||
# only apply those items that are (True, message)
|
||||
self.expected_responses = [
|
||||
MessageFilter.from_message_or_type(expected)
|
||||
for valid, expected in expected_with_validity
|
||||
if valid
|
||||
]
|
||||
self.actual_responses = []
|
||||
|
||||
def set_filter(
|
||||
self,
|
||||
message_type: t.Type[protobuf.MessageType],
|
||||
@ -1067,7 +1239,7 @@ class SessionDebugWrapper(Session):
|
||||
|
||||
Clears all debugging state that might have been modified by a testcase.
|
||||
"""
|
||||
self.client.ui.clear() # type: ignore [Cannot access attribute]
|
||||
self.ui.clear()
|
||||
self.in_with_statement = False
|
||||
self.expected_responses: list[MessageFilter] | None = None
|
||||
self.actual_responses: list[protobuf.MessageType] | None = None
|
||||
@ -1076,7 +1248,7 @@ class SessionDebugWrapper(Session):
|
||||
t.Callable[[protobuf.MessageType], protobuf.MessageType] | None,
|
||||
] = {}
|
||||
|
||||
def __enter__(self) -> "SessionDebugWrapper":
|
||||
def __enter__(self) -> "TrezorClientDebugLink":
|
||||
# For usage in with/expected_responses
|
||||
if self.in_with_statement:
|
||||
raise RuntimeError("Do not nest!")
|
||||
@ -1091,10 +1263,8 @@ class SessionDebugWrapper(Session):
|
||||
actual_responses = self.actual_responses
|
||||
|
||||
# grab a copy of the inputflow generator to raise an exception through it
|
||||
if isinstance(self.client, TrezorClientDebugLink) and isinstance(
|
||||
self.client.ui, DebugUI
|
||||
):
|
||||
input_flow = self.client.ui.input_flow
|
||||
if isinstance(self.ui, DebugUI):
|
||||
input_flow = self.ui.input_flow
|
||||
else:
|
||||
input_flow = None
|
||||
|
||||
@ -1187,8 +1357,8 @@ class SessionDebugWrapper(Session):
|
||||
>>> # press Yes
|
||||
>>> client.debug.press_yes()
|
||||
>>>
|
||||
>>> with session:
|
||||
>>> session.set_input_flow(input_flow)
|
||||
>>> with client:
|
||||
>>> client.set_input_flow(input_flow)
|
||||
>>> some_call(session)
|
||||
"""
|
||||
if not self.in_with_statement:
|
||||
@ -1198,175 +1368,11 @@ class SessionDebugWrapper(Session):
|
||||
input_flow = input_flow()
|
||||
if not hasattr(input_flow, "send"):
|
||||
raise RuntimeError("input_flow should be a generator function")
|
||||
self.client.ui.input_flow = input_flow # type: ignore [Cannot access attribute]
|
||||
self.ui.input_flow = input_flow
|
||||
|
||||
next(input_flow) # start the generator
|
||||
|
||||
|
||||
class TrezorClientDebugLink(TrezorClient):
|
||||
# This class implements automatic responses
|
||||
# and other functionality for unit tests
|
||||
# for various callbacks, created in order
|
||||
# to automatically pass unit tests.
|
||||
#
|
||||
# This mixing should be used only for purposes
|
||||
# of unit testing, because it will fail to work
|
||||
# without special DebugLink interface provided
|
||||
# by the device.
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
transport: Transport,
|
||||
auto_interact: bool = True,
|
||||
open_transport: bool = True,
|
||||
debug_transport: Transport | None = None,
|
||||
) -> None:
|
||||
try:
|
||||
debug_transport = debug_transport or transport.find_debug()
|
||||
self.debug = DebugLink(debug_transport, auto_interact)
|
||||
if open_transport:
|
||||
self.debug.open()
|
||||
# try to open debuglink, see if it works
|
||||
assert self.debug.transport.ping()
|
||||
except Exception:
|
||||
if not auto_interact:
|
||||
self.debug = NullDebugLink()
|
||||
else:
|
||||
raise
|
||||
|
||||
if open_transport:
|
||||
transport.open()
|
||||
|
||||
# set transport explicitly so that sync_responses can work
|
||||
super().__init__(transport)
|
||||
|
||||
self.transport = transport
|
||||
self.ui: DebugUI = DebugUI(self.debug)
|
||||
|
||||
def get_pin(_msg: messages.PinMatrixRequest) -> str:
|
||||
try:
|
||||
pin = self.ui.get_pin()
|
||||
except Cancelled:
|
||||
raise
|
||||
return pin
|
||||
|
||||
self.pin_callback = get_pin
|
||||
self.button_callback = self.ui.button_request
|
||||
|
||||
self.sync_responses()
|
||||
|
||||
# So that we can choose right screenshotting logic (T1 vs TT)
|
||||
# and know the supported debug capabilities
|
||||
self.debug.model = self.model
|
||||
self.debug.version = self.version
|
||||
|
||||
@property
|
||||
def layout_type(self) -> LayoutType:
|
||||
return self.debug.layout_type
|
||||
|
||||
def get_new_client(self) -> TrezorClientDebugLink:
|
||||
new_client = TrezorClientDebugLink(
|
||||
self.transport,
|
||||
self.debug.allow_interactions,
|
||||
open_transport=False,
|
||||
debug_transport=self.debug.transport,
|
||||
)
|
||||
new_client.debug.screenshot_recording_dir = self.debug.screenshot_recording_dir
|
||||
new_client.debug.t1_screenshot_directory = self.debug.t1_screenshot_directory
|
||||
new_client.debug.t1_screenshot_counter = self.debug.t1_screenshot_counter
|
||||
return new_client
|
||||
|
||||
def close_transport(self) -> None:
|
||||
self.transport.close()
|
||||
self.debug.close()
|
||||
|
||||
def lock(self) -> None:
|
||||
s = self.get_seedless_session()
|
||||
s.lock()
|
||||
|
||||
def get_session(
|
||||
self,
|
||||
passphrase: str | object = "",
|
||||
derive_cardano: bool = False,
|
||||
) -> SessionDebugWrapper:
|
||||
if isinstance(passphrase, str):
|
||||
passphrase = Mnemonic.normalize_string(passphrase)
|
||||
session = SessionDebugWrapper(
|
||||
super().get_session(
|
||||
passphrase,
|
||||
derive_cardano,
|
||||
)
|
||||
)
|
||||
return session
|
||||
|
||||
def get_seedless_session(
|
||||
self, *args: t.Any, **kwargs: t.Any
|
||||
) -> SessionDebugWrapper:
|
||||
session = super().get_seedless_session(*args, **kwargs)
|
||||
if not isinstance(session, SessionDebugWrapper):
|
||||
session = SessionDebugWrapper(session)
|
||||
return session
|
||||
|
||||
def watch_layout(self, watch: bool = True) -> None:
|
||||
"""Enable or disable watching layout changes.
|
||||
|
||||
Since trezor-core v2.3.2, it is necessary to call `watch_layout()` before
|
||||
using `debug.wait_layout()`, otherwise layout changes are not reported.
|
||||
"""
|
||||
if self.version >= (2, 3, 2):
|
||||
# version check is necessary because otherwise we cannot reliably detect
|
||||
# whether and where to wait for reply:
|
||||
# - T1 reports unknown debuglink messages on the wirelink
|
||||
# - TT < 2.3.0 does not reply to unknown debuglink messages due to a bug
|
||||
self.debug.watch_layout(watch)
|
||||
|
||||
def use_pin_sequence(self, pins: t.Iterable[str]) -> None:
|
||||
"""Respond to PIN prompts from device with the provided PINs.
|
||||
The sequence must be at least as long as the expected number of PIN prompts.
|
||||
"""
|
||||
self.ui.pins = iter(pins)
|
||||
|
||||
def use_mnemonic(self, mnemonic: str) -> None:
|
||||
"""Use the provided mnemonic to respond to device.
|
||||
Only applies to T1, where device prompts the host for mnemonic words."""
|
||||
self.mnemonic = Mnemonic.normalize_string(mnemonic).split(" ")
|
||||
|
||||
def sync_responses(self) -> None:
|
||||
"""Synchronize Trezor device receiving with caller.
|
||||
|
||||
When a failed test does not read out the response, the next caller will write
|
||||
a request, but read the previous response -- while the device had already sent
|
||||
and placed into queue the new response.
|
||||
|
||||
This function will call `Ping` and read responses until it locates a `Success`
|
||||
with the expected text. This means that we are reading up-to-date responses.
|
||||
"""
|
||||
import secrets
|
||||
|
||||
# Start by canceling whatever is on screen. This will work to cancel T1 PIN
|
||||
# prompt, which is in TINY mode and does not respond to `Ping`.
|
||||
if self.protocol_version is ProtocolVersion.V1:
|
||||
assert isinstance(self.protocol, ProtocolV1Channel)
|
||||
self.protocol.write(messages.Cancel())
|
||||
resp = self.protocol.read()
|
||||
message = "SYNC" + secrets.token_hex(8)
|
||||
self.protocol.write(messages.Ping(message=message))
|
||||
while resp != messages.Success(message=message):
|
||||
try:
|
||||
resp = self.protocol.read()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def mnemonic_callback(self, _) -> str:
|
||||
word, pos = self.debug.read_recovery_word()
|
||||
if word:
|
||||
return word
|
||||
if pos:
|
||||
return self.mnemonic[pos - 1]
|
||||
|
||||
raise RuntimeError("Unexpected call")
|
||||
|
||||
|
||||
def load_device(
|
||||
session: "Session",
|
||||
mnemonic: str | t.Iterable[str],
|
||||
|
@ -76,9 +76,9 @@ if __name__ == "__main__":
|
||||
|
||||
# change PIN
|
||||
new_pin = "".join(random.choices(string.digits, k=random.randint(6, 10)))
|
||||
session.set_input_flow(pin_input_flow(client, last_pin, new_pin))
|
||||
client.set_input_flow(pin_input_flow(client, last_pin, new_pin))
|
||||
device.change_pin(client)
|
||||
session.set_input_flow(None)
|
||||
client.set_input_flow(None)
|
||||
last_pin = new_pin
|
||||
|
||||
print(f"iteration {i}")
|
||||
|
@ -193,13 +193,15 @@ def test_autolock_does_not_interrupt_signing(device_handler: "BackgroundDeviceHa
|
||||
assert TR.send__total_amount in layout.text_content()
|
||||
assert "0.0039 BTC" in layout.text_content()
|
||||
|
||||
client = session.client
|
||||
|
||||
def sleepy_filter(msg: MessageType) -> MessageType:
|
||||
time.sleep(10.1)
|
||||
session.set_filter(messages.TxAck, None)
|
||||
client.set_filter(messages.TxAck, None)
|
||||
return msg
|
||||
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, sleepy_filter)
|
||||
with client:
|
||||
client.set_filter(messages.TxAck, sleepy_filter)
|
||||
# confirm transaction
|
||||
if debug.layout_type is LayoutType.Bolt:
|
||||
debug.click(debug.screen_buttons.ok(), hold_ms=1000)
|
||||
@ -539,15 +541,17 @@ def test_autolock_does_not_interrupt_preauthorized(
|
||||
no_fee_indices=[],
|
||||
)
|
||||
|
||||
client = session.client
|
||||
|
||||
def sleepy_filter(msg: MessageType) -> MessageType:
|
||||
time.sleep(10.1)
|
||||
session.set_filter(messages.SignTx, None)
|
||||
client.set_filter(messages.SignTx, None)
|
||||
return msg
|
||||
|
||||
with session:
|
||||
with client:
|
||||
# Start DoPreauthorized flow when device is unlocked. Wait 10s before
|
||||
# delivering SignTx, by that time autolock timer should have fired.
|
||||
session.set_filter(messages.SignTx, sleepy_filter)
|
||||
client.set_filter(messages.SignTx, sleepy_filter)
|
||||
device_handler.run_with_provided_session(
|
||||
session,
|
||||
btc.sign_tx,
|
||||
|
@ -288,7 +288,7 @@ def _client_unlocked(
|
||||
|
||||
test_ui = request.config.getoption("ui")
|
||||
|
||||
# _raw_client.reset_debug_features()
|
||||
_raw_client.reset_debug_features()
|
||||
if isinstance(_raw_client.protocol, ProtocolV1Channel):
|
||||
try:
|
||||
_raw_client.sync_responses()
|
||||
@ -311,7 +311,7 @@ def _client_unlocked(
|
||||
_raw_client = _raw_client.get_new_client()
|
||||
session = _raw_client.get_seedless_session()
|
||||
wipe_device(session)
|
||||
sleep(1.5) # Makes tests more stable (wait for wipe to finish)
|
||||
# sleep(1.5) # Makes tests more stable (wait for wipe to finish)
|
||||
|
||||
if not _raw_client.features.bootloader_mode:
|
||||
_raw_client.refresh_features()
|
||||
|
@ -51,9 +51,9 @@ def test_binance_get_address_chunkify_details(
|
||||
):
|
||||
# data from https://github.com/binance-chain/javascript-sdk/blob/master/__tests__/crypto.test.js#L50
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowAddressQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
address = get_address(
|
||||
session, parse_path(path), show_display=True, chunkify=True
|
||||
)
|
||||
|
@ -32,9 +32,9 @@ BINANCE_PATH = parse_path("m/44h/714h/0h/0/0")
|
||||
mnemonic="offer caution gift cross surge pretty orange during eye soldier popular holiday mention east eight office fashion ill parrot vault rent devote earth cousin"
|
||||
)
|
||||
def test_binance_get_public_key(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowXpubQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
sig = binance.get_public_key(session, BINANCE_PATH, show_display=True)
|
||||
assert (
|
||||
sig.hex()
|
||||
|
@ -65,7 +65,7 @@ def test_sign_tx(session: Session, chunkify: bool):
|
||||
assert session.features.unlocked is False
|
||||
commitment_data = b"\x0fwww.example.com" + (1).to_bytes(ROUND_ID_LEN, "big")
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
session.client.use_pin_sequence([PIN])
|
||||
btc.authorize_coinjoin(
|
||||
session,
|
||||
@ -80,8 +80,8 @@ def test_sign_tx(session: Session, chunkify: bool):
|
||||
|
||||
session.call(messages.LockDevice())
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[messages.PreauthorizedRequest, messages.OwnershipProof]
|
||||
)
|
||||
btc.get_ownership_proof(
|
||||
@ -94,8 +94,8 @@ def test_sign_tx(session: Session, chunkify: bool):
|
||||
preauthorized=True,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[messages.PreauthorizedRequest, messages.OwnershipProof]
|
||||
)
|
||||
btc.get_ownership_proof(
|
||||
@ -207,8 +207,8 @@ def test_sign_tx(session: Session, chunkify: bool):
|
||||
no_fee_indices=[],
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.PreauthorizedRequest(),
|
||||
request_input(0),
|
||||
@ -452,8 +452,8 @@ def test_sign_tx_spend(session: Session):
|
||||
prev_txes=TX_CACHE_TESTNET,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=B.Other),
|
||||
messages.UnlockedPathRequest,
|
||||
@ -526,8 +526,8 @@ def test_sign_tx_migration(session: Session):
|
||||
prev_txes=TX_CACHE_TESTNET,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=B.Other),
|
||||
messages.UnlockedPathRequest,
|
||||
@ -666,8 +666,8 @@ def test_get_public_key(session: Session):
|
||||
)
|
||||
|
||||
# Get unlock path MAC.
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=B.Other),
|
||||
messages.UnlockedPathRequest,
|
||||
@ -689,8 +689,8 @@ def test_get_public_key(session: Session):
|
||||
)
|
||||
|
||||
# Ensure that user does not need to confirm access when path unlock is requested with MAC.
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.UnlockedPathRequest,
|
||||
messages.PublicKey,
|
||||
@ -720,8 +720,8 @@ def test_get_address(session: Session):
|
||||
)
|
||||
|
||||
# Unlock CoinJoin path.
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=B.Other),
|
||||
messages.UnlockedPathRequest,
|
||||
|
@ -72,8 +72,8 @@ def test_send_bch_change(session: Session):
|
||||
amount=73_452,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -124,8 +124,8 @@ def test_send_bch_nochange(session: Session):
|
||||
amount=1_934_960,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -182,8 +182,8 @@ def test_send_bch_oldaddr(session: Session):
|
||||
amount=1_934_960,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -252,9 +252,9 @@ def test_attack_change_input(session: Session):
|
||||
|
||||
return msg
|
||||
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -327,8 +327,8 @@ def test_send_bch_multisig_wrongchange(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=23_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -395,8 +395,8 @@ def test_send_bch_multisig_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=24_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -434,8 +434,8 @@ def test_send_bch_multisig_change(session: Session):
|
||||
)
|
||||
out2.address_n[2] = H_(1)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -496,8 +496,8 @@ def test_send_bch_external_presigned(session: Session):
|
||||
amount=1_934_960,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
|
@ -71,8 +71,8 @@ def test_send_bitcoin_gold_change(session: Session):
|
||||
amount=1_252_382_934 - 1_896_050 - 1_000,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -124,8 +124,8 @@ def test_send_bitcoin_gold_nochange(session: Session):
|
||||
amount=1_252_382_934 + 38_448_607 - 1_000,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -193,9 +193,9 @@ def test_attack_change_input(session: Session):
|
||||
|
||||
return msg
|
||||
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -254,8 +254,8 @@ def test_send_btg_multisig_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOMULTISIG,
|
||||
amount=1_252_382_934 - 24_000 - 1_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -293,8 +293,8 @@ def test_send_btg_multisig_change(session: Session):
|
||||
)
|
||||
out2.address_n[2] = H_(1)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -347,8 +347,8 @@ def test_send_p2sh(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
amount=1_252_382_934 - 11_000 - 12_300_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -400,8 +400,8 @@ def test_send_p2sh_witness_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=1_252_382_934 - 11_000 - 12_300_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -460,8 +460,8 @@ def test_send_multisig_1(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -484,7 +484,7 @@ def test_send_multisig_1(session: Session):
|
||||
inp1.multisig.signatures[0] = signatures[0]
|
||||
# sign with third key
|
||||
inp1.address_n[2] = H_(3)
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -537,7 +537,7 @@ def test_send_mixed_inputs(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Bgold", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
@ -577,8 +577,8 @@ def test_send_btg_external_presigned(session: Session):
|
||||
amount=1_252_382_934 + 58_456 - 1_000,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
|
@ -57,8 +57,8 @@ def test_send_dash(session: Session):
|
||||
amount=999_999_000,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -106,8 +106,8 @@ def test_send_dash_dip2_input(session: Session):
|
||||
amount=95_000_000,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
|
@ -76,8 +76,8 @@ def test_send_decred(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -133,8 +133,8 @@ def test_purchase_ticket_decred(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -197,8 +197,8 @@ def test_spend_from_stake_generation_and_revocation_decred(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -278,8 +278,8 @@ def test_send_decred_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -384,8 +384,8 @@ def test_decred_multisig_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
|
@ -168,9 +168,9 @@ def _address_n(purpose, coin, account, script_type):
|
||||
def test_descriptors(
|
||||
session: Session, coin, account, purpose, script_type, descriptors
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowXpubQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
address_n = _address_n(purpose, coin, account, script_type)
|
||||
res = btc.get_public_node(
|
||||
@ -191,10 +191,10 @@ def test_descriptors(
|
||||
def test_descriptors_trezorlib(
|
||||
session: Session, coin, account, purpose, script_type, descriptors
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if session.client.model != models.T1B1:
|
||||
IF = InputFlowShowXpubQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
res = btc_cli._get_descriptor(
|
||||
session, coin, account, purpose, script_type, show_display=True
|
||||
)
|
||||
|
@ -270,10 +270,10 @@ def test_multisig(session: Session):
|
||||
xpubs.append(node.xpub)
|
||||
|
||||
for nr in range(1, 4):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
assert (
|
||||
btc.get_address(
|
||||
session,
|
||||
@ -321,10 +321,10 @@ def test_multisig_missing(session: Session, show_display):
|
||||
)
|
||||
|
||||
for multisig in (multisig1, multisig2):
|
||||
with pytest.raises(TrezorFailure), session:
|
||||
with pytest.raises(TrezorFailure), session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.get_address(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -345,10 +345,10 @@ def test_bch_multisig(session: Session):
|
||||
xpubs.append(node.xpub)
|
||||
|
||||
for nr in range(1, 4):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
assert (
|
||||
btc.get_address(
|
||||
session,
|
||||
@ -396,8 +396,8 @@ def test_invalid_path(session: Session):
|
||||
|
||||
def test_unknown_path(session: Session):
|
||||
UNKNOWN_PATH = parse_path("m/44h/9h/0h/0/0")
|
||||
with session:
|
||||
session.set_expected_responses([messages.Failure])
|
||||
with session.client as client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
|
||||
with pytest.raises(TrezorFailure, match="Forbidden key path"):
|
||||
# account number is too high
|
||||
@ -406,8 +406,8 @@ def test_unknown_path(session: Session):
|
||||
# disable safety checks
|
||||
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(
|
||||
code=messages.ButtonRequestType.UnknownDerivationPath
|
||||
@ -418,13 +418,13 @@ def test_unknown_path(session: Session):
|
||||
)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
# try again with a warning
|
||||
btc.get_address(session, "Bitcoin", UNKNOWN_PATH, show_display=True)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
# no warning is displayed when the call is silent
|
||||
session.set_expected_responses([messages.Address])
|
||||
client.set_expected_responses([messages.Address])
|
||||
btc.get_address(session, "Bitcoin", UNKNOWN_PATH, show_display=False)
|
||||
|
||||
|
||||
@ -455,10 +455,10 @@ def test_multisig_different_paths(session: Session):
|
||||
with pytest.raises(
|
||||
Exception, match="Using different paths for different xpubs is not allowed"
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.get_address(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -469,10 +469,10 @@ def test_multisig_different_paths(session: Session):
|
||||
)
|
||||
|
||||
device.apply_settings(session, safety_checks=SafetyCheckLevel.PromptTemporarily)
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.get_address(
|
||||
session,
|
||||
"Bitcoin",
|
||||
|
@ -74,10 +74,10 @@ def test_show_segwit(session: Session):
|
||||
|
||||
@pytest.mark.altcoin
|
||||
def test_show_segwit_altcoin(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
assert (
|
||||
btc.get_address(
|
||||
session,
|
||||
|
@ -63,9 +63,9 @@ def test_show_t1(
|
||||
yield
|
||||
session.client.debug.press_yes()
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
# This is the only place where even T1 is using input flow
|
||||
session.set_input_flow(input_flow_t1)
|
||||
client.set_input_flow(input_flow_t1)
|
||||
assert (
|
||||
btc.get_address(
|
||||
session,
|
||||
@ -88,9 +88,9 @@ def test_show_tt(
|
||||
script_type: messages.InputScriptType,
|
||||
address: str,
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowAddressQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
assert (
|
||||
btc.get_address(
|
||||
session,
|
||||
@ -109,9 +109,9 @@ def test_show_tt(
|
||||
def test_show_cancel(
|
||||
session: Session, path: str, script_type: messages.InputScriptType, address: str
|
||||
):
|
||||
with session, pytest.raises(Cancelled):
|
||||
with session.client as client, pytest.raises(Cancelled):
|
||||
IF = InputFlowShowAddressQRCodeCancel(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.get_address(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -157,10 +157,10 @@ def test_show_multisig_3(session: Session):
|
||||
|
||||
for multisig in (multisig1, multisig2):
|
||||
for i in [1, 2, 3]:
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
assert (
|
||||
btc.get_address(
|
||||
session,
|
||||
@ -273,9 +273,9 @@ def test_show_multisig_xpubs(
|
||||
)
|
||||
|
||||
for i in range(3):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowMultisigXPUBs(session.client, address, xpubs, i)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
session.client.debug.synchronize_at("Homescreen")
|
||||
session.client.watch_layout()
|
||||
btc.get_address(
|
||||
@ -314,10 +314,10 @@ def test_show_multisig_15(session: Session):
|
||||
|
||||
for multisig in [multisig1, multisig2]:
|
||||
for i in range(15):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
assert (
|
||||
btc.get_address(
|
||||
session,
|
||||
|
@ -119,9 +119,9 @@ def test_get_public_node(session: Session, coin_name, xpub_magic, path, xpub):
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.parametrize("coin_name, xpub_magic, path, xpub", VECTORS_BITCOIN)
|
||||
def test_get_public_node_show(session: Session, coin_name, xpub_magic, path, xpub):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowXpubQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
res = btc.get_public_node(session, path, coin_name=coin_name, show_display=True)
|
||||
assert res.xpub == xpub
|
||||
assert bip32.serialize(res.node, xpub_magic) == xpub
|
||||
@ -158,14 +158,14 @@ def test_get_public_node_show_legacy(
|
||||
client.debug.press_yes() # finish the flow
|
||||
yield
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
# test XPUB display flow (without showing QR code)
|
||||
res = btc.get_public_node(session, path, coin_name=coin_name, show_display=True)
|
||||
assert res.xpub == xpub
|
||||
assert bip32.serialize(res.node, xpub_magic) == xpub
|
||||
|
||||
# test XPUB QR code display using the input flow above
|
||||
session.set_input_flow(input_flow)
|
||||
client.set_input_flow(input_flow)
|
||||
res = btc.get_public_node(session, path, coin_name=coin_name, show_display=True)
|
||||
assert res.xpub == xpub
|
||||
assert bip32.serialize(res.node, xpub_magic) == xpub
|
||||
|
@ -61,8 +61,8 @@ def test_one_one_fee_sapling(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -125,8 +125,8 @@ def test_one_one_rewards_claim(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
|
@ -101,8 +101,8 @@ def test_2_of_3(session: Session, chunkify: bool):
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
|
||||
# Now we have first signature
|
||||
signatures1, _ = btc.sign_tx(
|
||||
@ -143,8 +143,8 @@ def test_2_of_3(session: Session, chunkify: bool):
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
signatures2, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp3], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -362,7 +362,7 @@ def test_15_of_15(session: Session):
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
sig, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -424,6 +424,7 @@ def test_attack_change_input(session: Session):
|
||||
attacker to provide a 1-of-2 multisig change address. When `input_real`
|
||||
is provided in the signing phase, an error must occur.
|
||||
"""
|
||||
client = session.client
|
||||
address_n = parse_path("m/48h/1h/0h/1h/0/0") # 2NErUdruXmM8o8bQySrzB3WdBRcmc5br4E8
|
||||
attacker_multisig_public_key = bytes.fromhex(
|
||||
"03653a148b68584acb97947344a7d4fd6a6f8b8485cad12987ff8edac874268088"
|
||||
@ -475,10 +476,10 @@ def test_attack_change_input(session: Session):
|
||||
)
|
||||
|
||||
# Transaction can be signed without the attack processor
|
||||
with session:
|
||||
with client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
IF = InputFlowConfirmAllWarnings(client)
|
||||
client.set_input_flow(IF.get())
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
@ -497,8 +498,8 @@ def test_attack_change_input(session: Session):
|
||||
attack_count -= 1
|
||||
return msg
|
||||
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
with client:
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.sign_tx(
|
||||
session,
|
||||
|
@ -263,8 +263,8 @@ def test_external_external(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(_responses(session, INP1, INP2))
|
||||
with session.client as client:
|
||||
client.set_expected_responses(_responses(session, INP1, INP2))
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -288,8 +288,8 @@ def test_external_internal(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
_responses(
|
||||
session,
|
||||
INP1,
|
||||
@ -300,7 +300,7 @@ def test_external_internal(session: Session):
|
||||
)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -324,8 +324,8 @@ def test_internal_external(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
_responses(
|
||||
session,
|
||||
INP1,
|
||||
@ -336,7 +336,7 @@ def test_internal_external(session: Session):
|
||||
)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -360,8 +360,8 @@ def test_multisig_external_external(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(_responses(session, INP1, INP2))
|
||||
with session.client as client:
|
||||
client.set_expected_responses(_responses(session, INP1, INP2))
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -393,8 +393,8 @@ def test_multisig_change_match_first(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
_responses(session, INP1, INP2, change_indices=[1])
|
||||
)
|
||||
btc.sign_tx(
|
||||
@ -428,8 +428,8 @@ def test_multisig_change_match_second(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
_responses(session, INP1, INP2, change_indices=[2])
|
||||
)
|
||||
btc.sign_tx(
|
||||
@ -464,8 +464,8 @@ def test_sorted_multisig_change_match_first(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
_responses(session, INP4, INP5, change_indices=[1])
|
||||
)
|
||||
btc.sign_tx(
|
||||
@ -499,8 +499,8 @@ def test_multisig_mismatch_multisig_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(_responses(session, INP1, INP2))
|
||||
with session.client as client:
|
||||
client.set_expected_responses(_responses(session, INP1, INP2))
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -532,8 +532,8 @@ def test_sorted_multisig_mismatch_multisig_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(_responses(session, INP4, INP5))
|
||||
with session.client as client:
|
||||
client.set_expected_responses(_responses(session, INP4, INP5))
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -568,8 +568,8 @@ def test_multisig_mismatch_multisig_change_different_paths(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOMULTISIG,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(_responses(session, INP1, INP2))
|
||||
with session.client as client:
|
||||
client.set_expected_responses(_responses(session, INP1, INP2))
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -601,8 +601,8 @@ def test_multisig_mismatch_inputs(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(_responses(session, INP1, INP3))
|
||||
with session.client as client:
|
||||
client.set_expected_responses(_responses(session, INP1, INP3))
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -635,8 +635,8 @@ def test_sorted_multisig_mismatch_inputs(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(_responses(session, INP4, INP6))
|
||||
with session.client as client:
|
||||
client.set_expected_responses(_responses(session, INP4, INP6))
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
|
@ -113,10 +113,10 @@ def test_getaddress(
|
||||
script_types: list[messages.InputScriptType],
|
||||
):
|
||||
for script_type in script_types:
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
res = btc.get_address(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -134,10 +134,10 @@ def test_signmessage(
|
||||
session: Session, path: str, script_types: list[messages.InputScriptType]
|
||||
):
|
||||
for script_type in script_types:
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
sig = btc.sign_message(
|
||||
session,
|
||||
@ -175,10 +175,10 @@ def test_signtx(
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Bitcoin", [inp1], [out1], prev_txes={prevhash: prevtx}
|
||||
)
|
||||
@ -202,10 +202,10 @@ def test_getaddress_multisig(
|
||||
]
|
||||
multisig = messages.MultisigRedeemScriptType(pubkeys=pubs, m=2)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
address = btc.get_address(
|
||||
session,
|
||||
"Bitcoin",
|
||||
@ -261,10 +261,10 @@ def test_signtx_multisig(session: Session, paths: list[str], address_index: list
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
sig, _ = btc.sign_tx(
|
||||
session, "Bitcoin", [inp1], [out1], prev_txes={prevhash: prevtx}
|
||||
)
|
||||
|
@ -63,8 +63,8 @@ def test_opreturn(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -110,8 +110,8 @@ def test_nonzero_opreturn(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[request_input(0), request_output(0), messages.Failure()]
|
||||
)
|
||||
|
||||
@ -136,8 +136,8 @@ def test_opreturn_address(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOOPRETURN,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[request_input(0), request_output(0), messages.Failure()]
|
||||
)
|
||||
with pytest.raises(
|
||||
|
@ -327,9 +327,9 @@ def test_signmessage_long(
|
||||
message: str,
|
||||
signature: str,
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignVerifyMessageLong(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
sig = btc.sign_message(
|
||||
session,
|
||||
coin_name=coin_name,
|
||||
@ -356,9 +356,9 @@ def test_signmessage_info(
|
||||
message: str,
|
||||
signature: str,
|
||||
):
|
||||
with session, pytest.raises(Cancelled):
|
||||
with session.client as client, pytest.raises(Cancelled):
|
||||
IF = InputFlowSignMessageInfo(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
sig = btc.sign_message(
|
||||
session,
|
||||
coin_name=coin_name,
|
||||
@ -390,13 +390,13 @@ MESSAGE_LENGTHS = (
|
||||
@pytest.mark.models("core")
|
||||
@pytest.mark.parametrize("message,is_long", MESSAGE_LENGTHS)
|
||||
def test_signmessage_pagination(session: Session, message: str, is_long: bool):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = (
|
||||
InputFlowSignVerifyMessageLong
|
||||
if is_long
|
||||
else InputFlowSignMessagePagination
|
||||
)(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.sign_message(
|
||||
session,
|
||||
coin_name="Bitcoin",
|
||||
@ -417,8 +417,8 @@ def test_signmessage_pagination_trailing_newline(session: Session):
|
||||
message = "THIS\nMUST\nNOT\nBE\nPAGINATED\n"
|
||||
# The trailing newline must not cause a new paginated screen to appear.
|
||||
# The UI must be a single dialog without pagination.
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# expect address confirmation
|
||||
message_filters.ButtonRequest(code=messages.ButtonRequestType.Other),
|
||||
@ -438,8 +438,8 @@ def test_signmessage_pagination_trailing_newline(session: Session):
|
||||
def test_signmessage_path_warning(session: Session):
|
||||
message = "This is an example of a signed message."
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# expect a path warning
|
||||
message_filters.ButtonRequest(
|
||||
@ -452,7 +452,7 @@ def test_signmessage_path_warning(session: Session):
|
||||
)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.sign_message(
|
||||
session,
|
||||
coin_name="Bitcoin",
|
||||
|
@ -125,8 +125,8 @@ def test_one_one_fee(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -178,8 +178,8 @@ def test_testnet_one_two_fee(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -228,8 +228,8 @@ def test_testnet_fee_high_warning(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -280,8 +280,8 @@ def test_one_two_fee(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -342,8 +342,8 @@ def test_one_three_fee(session: Session, chunkify: bool):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -413,8 +413,8 @@ def test_two_two(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -557,8 +557,8 @@ def test_lots_of_change(session: Session):
|
||||
|
||||
request_change_outputs = [request_output(i + 1) for i in range(cnt)]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -608,8 +608,8 @@ def test_fee_high_warning(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -664,9 +664,9 @@ def test_fee_high_hardfail(session: Session):
|
||||
device.apply_settings(
|
||||
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignTxHighFee(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_CACHE_TESTNET
|
||||
@ -696,8 +696,8 @@ def test_not_enough_funds(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -726,8 +726,8 @@ def test_p2sh(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOSCRIPTHASH,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -785,6 +785,7 @@ def test_testnet_big_amount(session: Session):
|
||||
|
||||
def test_attack_change_outputs(session: Session):
|
||||
# input tx: ac4ca0e7827a1228f44449cb57b4b9a809a667ca044dc43bb124627fed4bc10a
|
||||
client = session.client
|
||||
|
||||
inp1 = messages.TxInputType(
|
||||
address_n=parse_path("m/44h/0h/0h/0/55"), # 14nw9rFTWGUncHZjSqpPSJQaptWW7iRRB8
|
||||
@ -813,8 +814,8 @@ def test_attack_change_outputs(session: Session):
|
||||
)
|
||||
|
||||
# Test if the transaction can be signed normally
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -869,11 +870,11 @@ def test_attack_change_outputs(session: Session):
|
||||
|
||||
return msg
|
||||
|
||||
with session, pytest.raises(
|
||||
with client, pytest.raises(
|
||||
TrezorFailure, match="Transaction has changed during signing"
|
||||
):
|
||||
# Set up attack processors
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
|
||||
btc.sign_tx(
|
||||
session,
|
||||
@ -924,11 +925,11 @@ def test_attack_modify_change_address(session: Session):
|
||||
|
||||
return msg
|
||||
|
||||
with session, pytest.raises(
|
||||
with session.client as client, pytest.raises(
|
||||
TrezorFailure, match="Transaction has changed during signing"
|
||||
):
|
||||
# Set up attack processors
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
|
||||
btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_CACHE_TESTNET
|
||||
@ -982,9 +983,9 @@ def test_attack_change_input_address(session: Session):
|
||||
return msg
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -1033,8 +1034,8 @@ def test_spend_coinbase(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -1091,8 +1092,8 @@ def test_two_changes(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -1150,8 +1151,8 @@ def test_change_on_main_chain_allowed(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -1418,8 +1419,8 @@ def test_lock_time(session: Session, lock_time: int, sequence: int):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -1467,9 +1468,9 @@ def test_lock_time_blockheight(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowLockTimeBlockHeight(session.client, "499999999")
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(
|
||||
session,
|
||||
@ -1506,9 +1507,9 @@ def test_lock_time_datetime(session: Session, lock_time_str: str):
|
||||
lock_time_utc = lock_time_naive.replace(tzinfo=timezone.utc)
|
||||
lock_time_timestamp = int(lock_time_utc.timestamp())
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowLockTimeDatetime(session.client, lock_time_str)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(
|
||||
session,
|
||||
@ -1538,9 +1539,9 @@ def test_information(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignTxInformation(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(
|
||||
session,
|
||||
@ -1573,9 +1574,9 @@ def test_information_mixed(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignTxInformationMixed(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(
|
||||
session,
|
||||
@ -1604,9 +1605,9 @@ def test_information_cancel(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session, pytest.raises(Cancelled):
|
||||
with session.client as client, pytest.raises(Cancelled):
|
||||
IF = InputFlowSignTxInformationCancel(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(
|
||||
session,
|
||||
@ -1654,9 +1655,9 @@ def test_information_replacement(session: Session):
|
||||
orig_index=0,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignTxInformationReplacement(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(
|
||||
session,
|
||||
|
@ -61,7 +61,7 @@ def test_signtx_testnet(session: Session, amount_unit):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
amount=100_000 - 40_000 - 10_000,
|
||||
)
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
@ -95,7 +95,7 @@ def test_signtx_btc(session: Session, amount_unit):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Bitcoin",
|
||||
|
@ -142,7 +142,7 @@ def test_p2pkh_presigned(session: Session):
|
||||
)
|
||||
|
||||
# Test with first input as pre-signed external.
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
@ -155,7 +155,7 @@ def test_p2pkh_presigned(session: Session):
|
||||
assert serialized_tx.hex() == expected_tx
|
||||
|
||||
# Test with second input as pre-signed external.
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
@ -216,8 +216,8 @@ def test_p2wpkh_in_p2sh_presigned(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -267,8 +267,8 @@ def test_p2wpkh_in_p2sh_presigned(session: Session):
|
||||
|
||||
# Test corrupted script hash in scriptsig.
|
||||
inp1.script_sig[10] ^= 1
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -339,7 +339,7 @@ def test_p2wpkh_presigned(session: Session):
|
||||
)
|
||||
|
||||
# Test with second input as pre-signed external.
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
@ -399,8 +399,8 @@ def test_p2wsh_external_presigned(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -444,8 +444,8 @@ def test_p2wsh_external_presigned(session: Session):
|
||||
|
||||
# Test corrupted signature in witness.
|
||||
inp2.witness[10] ^= 1
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -509,8 +509,8 @@ def test_p2tr_external_presigned(session: Session):
|
||||
amount=4_600,
|
||||
script_type=messages.OutputScriptType.PAYTOTAPROOT,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -541,8 +541,8 @@ def test_p2tr_external_presigned(session: Session):
|
||||
|
||||
# Test corrupted signature in witness.
|
||||
inp2.witness[10] ^= 1
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -610,9 +610,9 @@ def test_p2wpkh_with_proof(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
is_t1 = session.model is models.T1B1
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -703,9 +703,9 @@ def test_p2tr_with_proof(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
is_t1 = session.model is models.T1B1
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -770,8 +770,8 @@ def test_p2wpkh_with_false_proof(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOWITNESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
|
@ -80,10 +80,10 @@ def test_invalid_path_prompt(session: Session):
|
||||
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(session, "Litecoin", [inp1], [out1], prev_txes=PREV_TXES)
|
||||
|
||||
@ -106,10 +106,10 @@ def test_invalid_path_pass_forkid(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
btc.sign_tx(session, "Bcash", [inp1], [out1], prev_txes=PREV_TXES)
|
||||
|
||||
@ -178,8 +178,8 @@ def test_attack_path_segwit(session: Session):
|
||||
|
||||
return msg
|
||||
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
with session.client as client:
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.sign_tx(
|
||||
session, "Testnet", [inp1, inp2], [out1], prev_txes={prev_hash: prev_tx}
|
||||
@ -202,8 +202,8 @@ def test_invalid_path_fail_asap(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOWITNESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
messages.Failure(code=messages.FailureType.DataError),
|
||||
|
@ -58,7 +58,7 @@ def test_non_segwit_segwit_inputs(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
signatures, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
@ -94,7 +94,7 @@ def test_segwit_non_segwit_inputs(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
signatures, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1, inp2], [out1], prev_txes=TX_API
|
||||
)
|
||||
@ -138,7 +138,7 @@ def test_segwit_non_segwit_segwit_inputs(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
signatures, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1, inp2, inp3], [out1], prev_txes=TX_API
|
||||
)
|
||||
@ -180,7 +180,7 @@ def test_non_segwit_segwit_non_segwit_inputs(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
signatures, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1, inp2, inp3], [out1], prev_txes=TX_API
|
||||
)
|
||||
|
@ -203,9 +203,9 @@ def test_payment_request_details(session: Session):
|
||||
)
|
||||
]
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowPaymentRequestDetails(session.client, outputs)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
|
@ -130,11 +130,11 @@ def test_invalid_prev_hash_attack(session: Session, prev_hash):
|
||||
msg.tx.inputs[0].prev_hash = prev_hash
|
||||
return msg
|
||||
|
||||
with session, pytest.raises(TrezorFailure) as e:
|
||||
session.set_filter(messages.TxAck, attack_filter)
|
||||
with session.client as client, pytest.raises(TrezorFailure) as e:
|
||||
client.set_filter(messages.TxAck, attack_filter)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
IF = InputFlowConfirmAllWarnings(client)
|
||||
client.set_input_flow(IF.get())
|
||||
btc.sign_tx(session, "Bitcoin", [inp1], [out1], prev_txes=PREV_TXES)
|
||||
|
||||
# check that injection was performed
|
||||
@ -168,9 +168,9 @@ def test_invalid_prev_hash_in_prevtx(session: Session, prev_hash):
|
||||
tx_hash = hash_tx(serialize_tx(prev_tx))
|
||||
inp0.prev_hash = tx_hash
|
||||
|
||||
with session, pytest.raises(TrezorFailure) as e:
|
||||
with session.client as client, pytest.raises(TrezorFailure) as e:
|
||||
if session.model is not models.T1B1:
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
btc.sign_tx(session, "Bitcoin", [inp0], [out1], prev_txes={tx_hash: prev_tx})
|
||||
_check_error_message(prev_hash, session.model, e.value.message)
|
||||
|
@ -116,8 +116,8 @@ def test_p2pkh_fee_bump(session: Session):
|
||||
orig_index=1,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_meta(TXHASH_50f6f1),
|
||||
@ -190,7 +190,7 @@ def test_p2wpkh_op_return_fee_bump(session: Session):
|
||||
orig_index=1,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
@ -243,8 +243,8 @@ def test_p2tr_fee_bump(session: Session):
|
||||
orig_index=1,
|
||||
script_type=messages.OutputScriptType.PAYTOTAPROOT,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_meta(TXHASH_8e4af7),
|
||||
@ -312,8 +312,8 @@ def test_p2wpkh_finalize(session: Session):
|
||||
orig_index=1,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_meta(TXHASH_70f987),
|
||||
@ -444,8 +444,8 @@ def test_p2wpkh_payjoin(
|
||||
orig_index=1,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_meta(TXHASH_65b768),
|
||||
@ -520,8 +520,8 @@ def test_p2wpkh_in_p2sh_remove_change(session: Session):
|
||||
orig_index=0,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_meta(TXHASH_334cd7),
|
||||
@ -599,8 +599,8 @@ def test_p2wpkh_in_p2sh_fee_bump_from_external(session: Session):
|
||||
orig_index=0,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_meta(TXHASH_334cd7),
|
||||
@ -720,8 +720,8 @@ def test_tx_meld(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_meta(TXHASH_334cd7),
|
||||
|
@ -66,8 +66,8 @@ def test_send_p2sh(session: Session, chunkify: bool):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
amount=123_456_789 - 11_000 - 12_300_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -124,8 +124,8 @@ def test_send_p2sh_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123_456_789 - 11_000 - 12_300_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -179,8 +179,8 @@ def test_testnet_segwit_big_amount(session: Session):
|
||||
amount=2**32 + 1,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -254,8 +254,8 @@ def test_send_multisig_1(session: Session):
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
signatures, _ = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -265,8 +265,8 @@ def test_send_multisig_1(session: Session):
|
||||
# sign with third key
|
||||
inp1.address_n[2] = H_(3)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -282,6 +282,7 @@ def test_attack_change_input_address(session: Session):
|
||||
# Simulates an attack where the user is coerced into unknowingly
|
||||
# transferring funds from one account to another one of their accounts,
|
||||
# potentially resulting in privacy issues.
|
||||
client = session.client
|
||||
|
||||
inp1 = messages.TxInputType(
|
||||
address_n=parse_path("m/49h/1h/0h/1/0"),
|
||||
@ -303,8 +304,8 @@ def test_attack_change_input_address(session: Session):
|
||||
)
|
||||
|
||||
# Test if the transaction can be signed normally.
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -349,8 +350,8 @@ def test_attack_change_input_address(session: Session):
|
||||
return msg
|
||||
|
||||
# Now run the attack, must trigger the exception
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
with client:
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
with pytest.raises(TrezorFailure):
|
||||
btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
|
||||
@ -360,6 +361,7 @@ def test_attack_change_input_address(session: Session):
|
||||
def test_attack_mixed_inputs(session: Session):
|
||||
TRUE_AMOUNT = 123_456_789
|
||||
FAKE_AMOUNT = 120_000_000
|
||||
client = session.client
|
||||
|
||||
inp1 = messages.TxInputType(
|
||||
address_n=parse_path("m/44h/1h/0h/0/0"),
|
||||
@ -421,10 +423,10 @@ def test_attack_mixed_inputs(session: Session):
|
||||
# T1 asks for first input for witness again
|
||||
expected_responses.insert(-2, request_input(0))
|
||||
|
||||
with session:
|
||||
with client:
|
||||
# Sign unmodified transaction.
|
||||
# "Fee over threshold" warning is displayed - fee is the whole TRUE_AMOUNT
|
||||
session.set_expected_responses(expected_responses)
|
||||
client.set_expected_responses(expected_responses)
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
@ -446,8 +448,8 @@ def test_attack_mixed_inputs(session: Session):
|
||||
expected_responses[:4] + expected_responses[5:16] + [messages.Failure()]
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure) as e, session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with pytest.raises(TrezorFailure) as e, client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Testnet",
|
||||
|
@ -82,8 +82,8 @@ def test_send_p2sh(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
amount=123_456_789 - 11_000 - 12_300_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -137,8 +137,8 @@ def test_send_p2sh_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOP2SHWITNESS,
|
||||
amount=123_456_789 - 11_000 - 12_300_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -190,8 +190,8 @@ def test_send_native(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
amount=100_000 - 40_000 - 10_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -244,7 +244,7 @@ def test_send_to_taproot(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
amount=10_000 - 7_000 - 200,
|
||||
)
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1, out2], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -277,8 +277,8 @@ def test_send_native_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOWITNESS,
|
||||
amount=100_000 - 40_000 - 10_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -344,8 +344,8 @@ def test_send_both(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -449,8 +449,8 @@ def test_send_multisig_1(session: Session):
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
signatures, _ = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -460,8 +460,8 @@ def test_send_multisig_1(session: Session):
|
||||
# sign with third key
|
||||
inp1.address_n[2] = H_(3)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -526,8 +526,8 @@ def test_send_multisig_2(session: Session):
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
signatures, _ = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -537,8 +537,8 @@ def test_send_multisig_2(session: Session):
|
||||
# sign with first key
|
||||
inp1.address_n[2] = H_(1)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -611,11 +611,11 @@ def test_send_multisig_3_change(session: Session):
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
signatures, _ = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -626,11 +626,11 @@ def test_send_multisig_3_change(session: Session):
|
||||
inp1.address_n[2] = H_(3)
|
||||
out1.address_n[2] = H_(3)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -703,11 +703,11 @@ def test_send_multisig_4_change(session: Session):
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
signatures, _ = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -718,11 +718,11 @@ def test_send_multisig_4_change(session: Session):
|
||||
inp1.address_n[2] = H_(3)
|
||||
out1.address_n[2] = H_(3)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
if is_core(session):
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session, "Testnet", [inp1], [out1], prev_txes=TX_API_TESTNET
|
||||
)
|
||||
@ -788,8 +788,8 @@ def test_multisig_mismatch_inputs_single(session: Session):
|
||||
amount=100_000 + 100_000 - 50_000 - 10_000,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
|
@ -79,8 +79,8 @@ def test_send_p2tr(session: Session, chunkify: bool):
|
||||
amount=4_450,
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -133,8 +133,8 @@ def test_send_two_with_change(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOTAPROOT,
|
||||
amount=6_800 + 13_000 - 200 - 15_000,
|
||||
)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -222,8 +222,8 @@ def test_send_mixed(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOTAPROOT,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# process inputs
|
||||
request_input(0),
|
||||
@ -353,9 +353,9 @@ def test_attack_script_type(session: Session):
|
||||
|
||||
return msg
|
||||
|
||||
with session:
|
||||
session.set_filter(messages.TxAck, attack_processor)
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_filter(messages.TxAck, attack_processor)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -406,8 +406,8 @@ def test_send_invalid_address(session: Session, address: str):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session, pytest.raises(TrezorFailure):
|
||||
session.set_expected_responses(
|
||||
with session.client as client, pytest.raises(TrezorFailure):
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
|
@ -40,9 +40,9 @@ def test_message_long_legacy(session: Session):
|
||||
|
||||
@pytest.mark.models("core")
|
||||
def test_message_long_core(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignVerifyMessageLong(session.client, verify=True)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
ret = btc.verify_message(
|
||||
session,
|
||||
"Bitcoin",
|
||||
|
@ -75,7 +75,7 @@ def test_v3_not_supported(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session, pytest.raises(TrezorFailure, match="DataError"):
|
||||
with session.client, pytest.raises(TrezorFailure, match="DataError"):
|
||||
btc.sign_tx(
|
||||
session,
|
||||
"Zcash Testnet",
|
||||
@ -106,8 +106,8 @@ def test_one_one_fee_sapling(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -210,7 +210,7 @@ def test_spend_old_versions(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
_, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Zcash Testnet",
|
||||
@ -259,8 +259,8 @@ def test_external_presigned(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
|
@ -95,9 +95,9 @@ def test_cardano_get_address(session: Session, chunkify: bool, parameters, resul
|
||||
"cardano/get_public_key.derivations.json",
|
||||
)
|
||||
def test_cardano_get_public_key(session: Session, parameters, result):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowXpubQRCode(session.client, passphrase_request_expected=False)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
# session.init_device(new_session=True, derive_cardano=True)
|
||||
|
||||
derivation_type = CardanoDerivationType.__members__[
|
||||
|
@ -122,10 +122,10 @@ def call_sign_tx(session: Session, parameters, input_flow=None, chunkify: bool =
|
||||
else:
|
||||
device.apply_settings(session, safety_checks=messages.SafetyCheckLevel.Strict)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
if input_flow is not None:
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(input_flow(session.client))
|
||||
client.set_input_flow(input_flow(session.client))
|
||||
|
||||
return cardano.sign_tx(
|
||||
session=session,
|
||||
|
@ -29,9 +29,9 @@ from ...input_flows import InputFlowShowXpubQRCode
|
||||
@pytest.mark.models("t2t1")
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_eos_get_public_key(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowXpubQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
public_key = get_public_key(
|
||||
session, parse_path("m/44h/194h/0h/0/0"), show_display=True
|
||||
)
|
||||
|
@ -60,7 +60,7 @@ def test_eos_signtx_transfer_token(session: Session, chunkify: bool):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID, chunkify=chunkify)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -93,7 +93,7 @@ def test_eos_signtx_buyram(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -126,7 +126,7 @@ def test_eos_signtx_buyrambytes(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -155,7 +155,7 @@ def test_eos_signtx_sellram(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -190,7 +190,7 @@ def test_eos_signtx_delegate(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -224,7 +224,7 @@ def test_eos_signtx_undelegate(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -253,7 +253,7 @@ def test_eos_signtx_refund(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -287,7 +287,7 @@ def test_eos_signtx_linkauth(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -320,7 +320,7 @@ def test_eos_signtx_unlinkauth(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -376,7 +376,7 @@ def test_eos_signtx_updateauth(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -405,7 +405,7 @@ def test_eos_signtx_deleteauth(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -468,7 +468,7 @@ def test_eos_signtx_vote(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -497,7 +497,7 @@ def test_eos_signtx_vote_proxy(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -526,7 +526,7 @@ def test_eos_signtx_unknown(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -602,7 +602,7 @@ def test_eos_signtx_newaccount(session: Session):
|
||||
"transaction_extensions": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
@ -638,7 +638,7 @@ def test_eos_signtx_setcontract(session: Session):
|
||||
"context_free_data": [],
|
||||
}
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
resp = eos.sign_tx(session, ADDRESS_N, transaction, CHAIN_ID)
|
||||
assert isinstance(resp, EosSignedTx)
|
||||
assert (
|
||||
|
@ -123,9 +123,9 @@ def test_external_token(session: Session) -> None:
|
||||
|
||||
|
||||
def test_external_chain_without_token(session: Session) -> None:
|
||||
with session:
|
||||
with session.client as client:
|
||||
if not session.client.debug.legacy_debug:
|
||||
session.set_input_flow(InputFlowConfirmAllWarnings(session.client).get())
|
||||
client.set_input_flow(InputFlowConfirmAllWarnings(session.client).get())
|
||||
# when using an external chains, unknown tokens are allowed
|
||||
network = common.encode_network(chain_id=66666, slip44=60)
|
||||
params = DEFAULT_ERC20_PARAMS.copy()
|
||||
@ -145,9 +145,9 @@ def test_external_chain_token_ok(session: Session) -> None:
|
||||
|
||||
|
||||
def test_external_chain_token_mismatch(session: Session) -> None:
|
||||
with session:
|
||||
with session.client as client:
|
||||
if not session.client.debug.legacy_debug:
|
||||
session.set_input_flow(InputFlowConfirmAllWarnings(session.client).get())
|
||||
client.set_input_flow(InputFlowConfirmAllWarnings(session.client).get())
|
||||
# when providing external defs, we explicitly allow, but not use, tokens
|
||||
# from other chains
|
||||
network = common.encode_network(chain_id=66666, slip44=60)
|
||||
|
@ -37,9 +37,9 @@ def test_getaddress(session: Session, parameters, result):
|
||||
@pytest.mark.models("core", reason="No input flow for T1")
|
||||
@parametrize_using_common_fixtures("ethereum/getaddress.json")
|
||||
def test_getaddress_chunkify_details(session: Session, parameters, result):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowAddressQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
address_n = parse_path(parameters["path"])
|
||||
assert (
|
||||
ethereum.get_address(session, address_n, show_display=True, chunkify=True)
|
||||
|
@ -29,7 +29,7 @@ pytestmark = [pytest.mark.altcoin, pytest.mark.ethereum]
|
||||
@pytest.mark.models("core")
|
||||
@parametrize_using_common_fixtures("ethereum/sign_typed_data.json")
|
||||
def test_ethereum_sign_typed_data(session: Session, parameters, result):
|
||||
with session:
|
||||
with session.client:
|
||||
address_n = parse_path(parameters["path"])
|
||||
ret = ethereum.sign_typed_data(
|
||||
session,
|
||||
@ -44,7 +44,7 @@ def test_ethereum_sign_typed_data(session: Session, parameters, result):
|
||||
@pytest.mark.models("legacy")
|
||||
@parametrize_using_common_fixtures("ethereum/sign_typed_data.json")
|
||||
def test_ethereum_sign_typed_data_blind(session: Session, parameters, result):
|
||||
with session:
|
||||
with session.client:
|
||||
address_n = parse_path(parameters["path"])
|
||||
ret = ethereum.sign_typed_data_hash(
|
||||
session,
|
||||
@ -97,10 +97,10 @@ DATA = {
|
||||
|
||||
@pytest.mark.models("core", skip="delizia", reason="Not yet implemented in new UI")
|
||||
def test_ethereum_sign_typed_data_show_more_button(session: Session):
|
||||
with session:
|
||||
session.client.watch_layout()
|
||||
IF = InputFlowEIP712ShowMore(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
with session.client as client:
|
||||
client.watch_layout()
|
||||
IF = InputFlowEIP712ShowMore(client)
|
||||
client.set_input_flow(IF.get())
|
||||
ethereum.sign_typed_data(
|
||||
session,
|
||||
parse_path("m/44h/60h/0h/0/0"),
|
||||
@ -111,10 +111,10 @@ def test_ethereum_sign_typed_data_show_more_button(session: Session):
|
||||
|
||||
@pytest.mark.models("core")
|
||||
def test_ethereum_sign_typed_data_cancel(session: Session):
|
||||
with session, pytest.raises(exceptions.Cancelled):
|
||||
with session.client as client, pytest.raises(exceptions.Cancelled):
|
||||
session.client.watch_layout()
|
||||
IF = InputFlowEIP712Cancel(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
ethereum.sign_typed_data(
|
||||
session,
|
||||
parse_path("m/44h/60h/0h/0/0"),
|
||||
|
@ -36,9 +36,9 @@ def test_signmessage(session: Session, parameters, result):
|
||||
assert res.address == result["address"]
|
||||
assert res.signature.hex() == result["sig"]
|
||||
else:
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignVerifyMessageLong(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
res = ethereum.sign_message(
|
||||
session, parse_path(parameters["path"]), parameters["msg"]
|
||||
)
|
||||
@ -57,9 +57,9 @@ def test_verify(session: Session, parameters, result):
|
||||
)
|
||||
assert res is True
|
||||
else:
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSignVerifyMessageLong(session.client, verify=True)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
res = ethereum.verify_message(
|
||||
session,
|
||||
parameters["address"],
|
||||
|
@ -73,10 +73,10 @@ def _do_test_signtx(
|
||||
input_flow=None,
|
||||
chunkify: bool = False,
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if input_flow:
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(input_flow)
|
||||
client.watch_layout()
|
||||
client.set_input_flow(input_flow)
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx(
|
||||
session,
|
||||
n=parse_path(parameters["path"]),
|
||||
@ -151,9 +151,9 @@ def test_signtx_go_back_from_summary(session: Session):
|
||||
def test_signtx_eip1559(
|
||||
session: Session, chunkify: bool, parameters: dict, result: dict
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
if not session.client.debug.legacy_debug:
|
||||
session.set_input_flow(InputFlowConfirmAllWarnings(session.client).get())
|
||||
client.set_input_flow(InputFlowConfirmAllWarnings(session.client).get())
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
||||
session,
|
||||
n=parse_path(parameters["path"]),
|
||||
@ -222,8 +222,8 @@ def test_data_streaming(session: Session):
|
||||
"""Only verifying the expected responses, the signatures are
|
||||
checked in vectorized function above.
|
||||
"""
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.SignTx),
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.SignTx),
|
||||
@ -270,7 +270,7 @@ def test_data_streaming(session: Session):
|
||||
|
||||
|
||||
def test_signtx_eip1559_access_list(session: Session):
|
||||
with session:
|
||||
with session.client:
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
||||
session,
|
||||
@ -309,7 +309,7 @@ def test_signtx_eip1559_access_list(session: Session):
|
||||
|
||||
|
||||
def test_signtx_eip1559_access_list_larger(session: Session):
|
||||
with session:
|
||||
with session.client:
|
||||
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
||||
session,
|
||||
@ -442,6 +442,8 @@ HEXDATA = "0123456789abcd000023456789abcd010003456789abcd020000456789abcd0300000
|
||||
)
|
||||
@pytest.mark.models("core", skip="delizia", reason="Not yet implemented in new UI")
|
||||
def test_signtx_data_pagination(session: Session, flow):
|
||||
client = session.client
|
||||
|
||||
def _sign_tx_call():
|
||||
ethereum.sign_tx(
|
||||
session,
|
||||
@ -456,15 +458,15 @@ def test_signtx_data_pagination(session: Session, flow):
|
||||
data=bytes.fromhex(HEXDATA),
|
||||
)
|
||||
|
||||
with session:
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(flow(session.client))
|
||||
with client:
|
||||
client.watch_layout()
|
||||
client.set_input_flow(flow(session.client))
|
||||
_sign_tx_call()
|
||||
|
||||
if flow is not input_flow_data_scroll_down:
|
||||
with session, pytest.raises(exceptions.Cancelled):
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(flow(session.client, cancel=True))
|
||||
with client, pytest.raises(exceptions.Cancelled):
|
||||
client.watch_layout()
|
||||
client.set_input_flow(flow(session.client, cancel=True))
|
||||
_sign_tx_call()
|
||||
|
||||
|
||||
@ -504,7 +506,7 @@ def test_signtx_staking_bad_inputs(session: Session, parameters: dict, result: d
|
||||
@pytest.mark.models("core")
|
||||
@parametrize_using_common_fixtures("ethereum/sign_tx_staking_eip1559.json")
|
||||
def test_signtx_staking_eip1559(session: Session, parameters: dict, result: dict):
|
||||
with session:
|
||||
with session.client:
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
||||
session,
|
||||
n=parse_path(parameters["path"]),
|
||||
|
@ -33,8 +33,8 @@ def test_encrypt(client: Client):
|
||||
client.debug.press_yes()
|
||||
|
||||
session = client.get_session()
|
||||
with session:
|
||||
session.set_input_flow(input_flow())
|
||||
with session.client as client:
|
||||
client.set_input_flow(input_flow())
|
||||
misc.encrypt_keyvalue(
|
||||
session,
|
||||
[],
|
||||
|
@ -41,8 +41,8 @@ def entropy(data):
|
||||
|
||||
@pytest.mark.parametrize("entropy_length", ENTROPY_LENGTHS)
|
||||
def test_entropy(session: Session, entropy_length):
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[m.ButtonRequest(code=m.ButtonRequestType.ProtectCall), m.Entropy]
|
||||
)
|
||||
ent = misc.get_entropy(session, entropy_length)
|
||||
|
@ -56,9 +56,9 @@ def test_monero_getaddress(session: Session, path: str, expected_address: bytes)
|
||||
def test_monero_getaddress_chunkify_details(
|
||||
session: Session, path: str, expected_address: bytes
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowAddressQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
address = monero.get_address(
|
||||
session, parse_path(path), show_display=True, chunkify=True
|
||||
)
|
||||
|
@ -32,7 +32,7 @@ pytestmark = [
|
||||
|
||||
# assertion data from T1
|
||||
def test_nem_signtx_importance_transfer(session: Session):
|
||||
with session:
|
||||
with session.client:
|
||||
tx = nem.sign_tx(
|
||||
session,
|
||||
parse_path("m/44h/1h/0h/0h/0h"),
|
||||
|
@ -33,8 +33,8 @@ pytestmark = [
|
||||
# assertion data from T1
|
||||
@pytest.mark.parametrize("chunkify", (True, False))
|
||||
def test_nem_signtx_simple(session: Session, chunkify: bool):
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
|
||||
@ -83,8 +83,8 @@ def test_nem_signtx_simple(session: Session, chunkify: bool):
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_nem_signtx_encrypted_payload(session: Session):
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
# Confirm transfer and network fee
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ConfirmOutput),
|
||||
|
@ -51,10 +51,10 @@ def do_recover_legacy(session: Session, mnemonic: list[str]):
|
||||
|
||||
|
||||
def do_recover_core(session: Session, mnemonic: list[str], mismatch: bool = False):
|
||||
with session:
|
||||
with session.client as client:
|
||||
session.client.watch_layout()
|
||||
IF = InputFlowBip39RecoveryDryRun(session.client, mnemonic, mismatch=mismatch)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
return device.recover(session, type=messages.RecoveryType.DryRun)
|
||||
|
||||
|
||||
@ -87,10 +87,10 @@ def test_invalid_seed_t1(session: Session):
|
||||
|
||||
@pytest.mark.models("core")
|
||||
def test_invalid_seed_core(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
session.client.watch_layout()
|
||||
IF = InputFlowBip39RecoveryDryRunInvalid(session)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
return device.recover(
|
||||
session,
|
||||
|
@ -28,9 +28,9 @@ pytestmark = pytest.mark.models("core")
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
@pytest.mark.uninitialized_session
|
||||
def test_tt_pin_passphrase(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39Recovery(session.client, MNEMONIC12.split(" "), pin="654")
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
pin_protection=True,
|
||||
@ -49,9 +49,9 @@ def test_tt_pin_passphrase(session: Session):
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
@pytest.mark.uninitialized_session
|
||||
def test_tt_nopin_nopassphrase(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39Recovery(session.client, MNEMONIC12.split(" "))
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
pin_protection=False,
|
||||
|
@ -48,11 +48,11 @@ VECTORS = (
|
||||
def _test_secret(
|
||||
session: Session, shares: list[str], secret: str, click_info: bool = False
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedRecovery(
|
||||
session.client, shares, click_info=click_info
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
pin_protection=False,
|
||||
@ -91,9 +91,9 @@ def test_extra_share_entered(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_abort(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedRecoveryAbort(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
session.refresh_features()
|
||||
@ -102,11 +102,11 @@ def test_abort(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_noabort(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedRecoveryNoAbort(
|
||||
session.client, EXTRA_GROUP_SHARE + MNEMONIC_SLIP39_ADVANCED_20
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
session.refresh_features()
|
||||
assert session.features.initialized is True
|
||||
@ -120,11 +120,11 @@ def test_same_share(session: Session):
|
||||
# second share is first 4 words of first
|
||||
second_share = MNEMONIC_SLIP39_ADVANCED_20[1].split(" ")[:4]
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedRecoveryShareAlreadyEntered(
|
||||
session, first_share, second_share
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
||||
@ -136,10 +136,10 @@ def test_group_threshold_reached(session: Session):
|
||||
# second share is first 3 words of first
|
||||
second_share = MNEMONIC_SLIP39_ADVANCED_20[0].split(" ")[:3]
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedRecoveryThresholdReached(
|
||||
session, first_share, second_share
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
@ -40,11 +40,11 @@ EXTRA_GROUP_SHARE = [
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_ADVANCED_20, passphrase=False)
|
||||
def test_2of3_dryrun(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedRecoveryDryRun(
|
||||
session.client, EXTRA_GROUP_SHARE + MNEMONIC_SLIP39_ADVANCED_20
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
passphrase_protection=False,
|
||||
@ -57,13 +57,13 @@ def test_2of3_dryrun(session: Session):
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_ADVANCED_20)
|
||||
def test_2of3_invalid_seed_dryrun(session: Session):
|
||||
# test fails because of different seed on device
|
||||
with session, pytest.raises(
|
||||
with session.client as client, pytest.raises(
|
||||
TrezorFailure, match=r"The seed does not match the one in the device"
|
||||
):
|
||||
IF = InputFlowSlip39AdvancedRecoveryDryRun(
|
||||
session.client, INVALID_SHARES_SLIP39_ADVANCED_20, mismatch=True
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
passphrase_protection=False,
|
||||
|
@ -73,9 +73,9 @@ VECTORS = (
|
||||
def test_secret(
|
||||
session: Session, shares: list[str], secret: str, backup_type: messages.BackupType
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecovery(session.client, shares)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
||||
# Workflow successfully ended
|
||||
@ -89,11 +89,11 @@ def test_secret(
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_recover_with_pin_passphrase(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecovery(
|
||||
session.client, MNEMONIC_SLIP39_BASIC_20_3of6, pin="654"
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
pin_protection=True,
|
||||
@ -109,9 +109,9 @@ def test_recover_with_pin_passphrase(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_abort(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryAbort(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
session.refresh_features()
|
||||
@ -123,9 +123,9 @@ def test_abort(session: Session):
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_abort_on_number_of_words(session: Session):
|
||||
# on Caesar, test_abort actually aborts on the # of words selection
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryAbortOnNumberOfWords(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
assert session.features.initialized is False
|
||||
@ -134,11 +134,11 @@ def test_abort_on_number_of_words(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_abort_between_shares(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryAbortBetweenShares(
|
||||
session.client, MNEMONIC_SLIP39_BASIC_20_3of6
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
session.refresh_features()
|
||||
@ -148,11 +148,11 @@ def test_abort_between_shares(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_noabort(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryNoAbort(
|
||||
session.client, MNEMONIC_SLIP39_BASIC_20_3of6
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
session.refresh_features()
|
||||
assert session.features.initialized is True
|
||||
@ -160,9 +160,9 @@ def test_noabort(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_invalid_mnemonic_first_share(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryInvalidFirstShare(session)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
session.refresh_features()
|
||||
@ -171,11 +171,11 @@ def test_invalid_mnemonic_first_share(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_invalid_mnemonic_second_share(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryInvalidSecondShare(
|
||||
session, MNEMONIC_SLIP39_BASIC_20_3of6
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
session.refresh_features()
|
||||
@ -186,9 +186,9 @@ def test_invalid_mnemonic_second_share(session: Session):
|
||||
@pytest.mark.parametrize("nth_word", range(3))
|
||||
def test_wrong_nth_word(session: Session, nth_word: int):
|
||||
share = MNEMONIC_SLIP39_BASIC_20_3of6[0].split(" ")
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryWrongNthWord(session, share, nth_word)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
||||
@ -196,18 +196,18 @@ def test_wrong_nth_word(session: Session, nth_word: int):
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_same_share(session: Session):
|
||||
share = MNEMONIC_SLIP39_BASIC_20_3of6[0].split(" ")
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoverySameShare(session, share)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
||||
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
def test_1of1(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecovery(session.client, MNEMONIC_SLIP39_BASIC_20_1of1)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
pin_protection=False,
|
||||
|
@ -38,9 +38,9 @@ INVALID_SHARES_20_2of3 = [
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=SHARES_20_2of3[0:2])
|
||||
def test_2of3_dryrun(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecoveryDryRun(session.client, SHARES_20_2of3[1:3])
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
passphrase_protection=False,
|
||||
@ -53,13 +53,13 @@ def test_2of3_dryrun(session: Session):
|
||||
@pytest.mark.setup_client(mnemonic=SHARES_20_2of3[0:2])
|
||||
def test_2of3_invalid_seed_dryrun(session: Session):
|
||||
# test fails because of different seed on device
|
||||
with session, pytest.raises(
|
||||
with session.client as client, pytest.raises(
|
||||
TrezorFailure, match=r"The seed does not match the one in the device"
|
||||
):
|
||||
IF = InputFlowSlip39BasicRecoveryDryRun(
|
||||
session.client, INVALID_SHARES_20_2of3, mismatch=True
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(
|
||||
session,
|
||||
passphrase_protection=False,
|
||||
|
@ -32,9 +32,9 @@ from ...input_flows import (
|
||||
|
||||
|
||||
def backup_flow_bip39(session: Session) -> bytes:
|
||||
with session:
|
||||
IF = InputFlowBip39Backup(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39Backup(client)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
assert IF.mnemonic is not None
|
||||
@ -42,9 +42,9 @@ def backup_flow_bip39(session: Session) -> bytes:
|
||||
|
||||
|
||||
def backup_flow_slip39_basic(session: Session):
|
||||
with session:
|
||||
IF = InputFlowSlip39BasicBackup(session.client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicBackup(client, False)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
groups = shamir.decode_mnemonics(IF.mnemonics[:3])
|
||||
@ -53,9 +53,9 @@ def backup_flow_slip39_basic(session: Session):
|
||||
|
||||
|
||||
def backup_flow_slip39_advanced(session: Session):
|
||||
with session:
|
||||
IF = InputFlowSlip39AdvancedBackup(session.client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedBackup(client, False)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
mnemonics = IF.mnemonics[0:3] + IF.mnemonics[5:8] + IF.mnemonics[10:13]
|
||||
@ -78,7 +78,7 @@ VECTORS = [
|
||||
def test_skip_backup_msg(session: Session, backup_type, backup_flow):
|
||||
assert session.features.initialized is False
|
||||
|
||||
with session:
|
||||
with session.client:
|
||||
device.setup(
|
||||
session,
|
||||
skip_backup=True,
|
||||
@ -116,9 +116,9 @@ def test_skip_backup_msg(session: Session, backup_type, backup_flow):
|
||||
def test_skip_backup_manual(session: Session, backup_type: BackupType, backup_flow):
|
||||
assert session.features.initialized is False
|
||||
|
||||
with session:
|
||||
IF = InputFlowResetSkipBackup(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
with session.client as client:
|
||||
IF = InputFlowResetSkipBackup(client)
|
||||
client.set_input_flow(IF.get())
|
||||
device.setup(
|
||||
session,
|
||||
pin_protection=False,
|
||||
|
@ -35,9 +35,9 @@ pytestmark = pytest.mark.models("core")
|
||||
|
||||
def reset_device(session: Session, strength: int):
|
||||
debug = session.client.debug
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39ResetBackup(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.setup(
|
||||
@ -91,9 +91,9 @@ def test_reset_device_pin(session: Session):
|
||||
debug = session.client.debug
|
||||
strength = 256 # 24 words
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39ResetPIN(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# PIN, passphrase, display random
|
||||
device.setup(
|
||||
@ -129,9 +129,9 @@ def test_reset_device_pin(session: Session):
|
||||
def test_reset_entropy_check(session: Session):
|
||||
strength = 128 # 12 words
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39ResetBackup(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# No PIN, no passphrase
|
||||
path_xpubs = device.setup(
|
||||
@ -176,9 +176,9 @@ def test_reset_failed_check(session: Session):
|
||||
debug = session.client.debug
|
||||
strength = 256 # 24 words
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39ResetFailedCheck(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# PIN, passphrase, display random
|
||||
device.setup(
|
||||
@ -263,9 +263,9 @@ def test_already_initialized(session: Session):
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
@pytest.mark.uninitialized_session
|
||||
def test_entropy_check(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
delizia = session.client.debug.layout_type is LayoutType.Delizia
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(name="setup_device"),
|
||||
(delizia, messages.ButtonRequest(name="confirm_setup_device")),
|
||||
@ -300,9 +300,9 @@ def test_entropy_check(session: Session):
|
||||
@pytest.mark.setup_client(uninitialized=True)
|
||||
@pytest.mark.uninitialized_session
|
||||
def test_no_entropy_check(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
delizia = session.client.debug.layout_type is LayoutType.Delizia
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(name="setup_device"),
|
||||
(delizia, messages.ButtonRequest(name="confirm_setup_device")),
|
||||
|
@ -47,9 +47,9 @@ def test_reset_recovery(client: Client):
|
||||
|
||||
|
||||
def reset(session: Session, strength: int = 128, skip_backup: bool = False) -> str:
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39ResetBackup(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.setup(
|
||||
@ -77,9 +77,9 @@ def reset(session: Session, strength: int = 128, skip_backup: bool = False) -> s
|
||||
|
||||
def recover(session: Session, mnemonic: str):
|
||||
words = mnemonic.split(" ")
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39Recovery(session.client, words)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
session.client.watch_layout()
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
||||
|
@ -68,9 +68,9 @@ def test_reset_recovery(client: Client):
|
||||
|
||||
|
||||
def reset(session: Session, strength: int = 128) -> list[str]:
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedResetRecovery(session.client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.setup(
|
||||
@ -97,9 +97,9 @@ def reset(session: Session, strength: int = 128) -> list[str]:
|
||||
|
||||
|
||||
def recover(session: Session, shares: list[str]):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedRecovery(session.client, shares, False)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
||||
# Workflow successfully ended
|
||||
|
@ -58,9 +58,9 @@ def test_reset_recovery(client: Client):
|
||||
|
||||
|
||||
def reset(session: Session, strength: int = 128) -> list[str]:
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicResetRecovery(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.setup(
|
||||
@ -87,9 +87,9 @@ def reset(session: Session, strength: int = 128) -> list[str]:
|
||||
|
||||
|
||||
def recover(session: Session, shares: t.Sequence[str]):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicRecovery(session.client, shares)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, pin_protection=False, label="label")
|
||||
|
||||
# Workflow successfully ended
|
||||
|
@ -35,9 +35,9 @@ def test_reset_device_slip39_advanced(client: Client):
|
||||
member_threshold = 3
|
||||
|
||||
session = client.get_seedless_session()
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedResetRecovery(client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.setup(
|
||||
session,
|
||||
|
@ -34,9 +34,9 @@ pytestmark = pytest.mark.models("core")
|
||||
def reset_device(session: Session, strength: int):
|
||||
member_threshold = 3
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicResetRecovery(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# No PIN, no passphrase, don't display random
|
||||
device.setup(
|
||||
@ -89,9 +89,9 @@ def test_reset_entropy_check(session: Session):
|
||||
|
||||
strength = 128 # 20 words
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicResetRecovery(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# No PIN, no passphrase.
|
||||
path_xpubs = device.setup(
|
||||
|
@ -52,9 +52,9 @@ def test_ripple_get_address(session: Session, path: str, expected_address: str):
|
||||
def test_ripple_get_address_chunkify_details(
|
||||
session: Session, path: str, expected_address: str
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowAddressQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
address = get_address(
|
||||
session, parse_path(path), show_display=True, chunkify=True
|
||||
)
|
||||
|
@ -47,9 +47,9 @@ pytestmark = [
|
||||
def test_solana_sign_tx(session: Session, parameters, result):
|
||||
serialized_tx = _serialize_tx(parameters["construct"])
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
actual_result = sign_tx(
|
||||
session,
|
||||
address_n=parse_path(parameters["address"]),
|
||||
|
@ -122,9 +122,9 @@ def test_get_address(session: Session, parameters, result):
|
||||
@pytest.mark.models("core")
|
||||
@parametrize_using_common_fixtures("stellar/get_address.json")
|
||||
def test_get_address_chunkify_details(session: Session, parameters, result):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowAddressQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
address_n = parse_path(parameters["path"])
|
||||
address = stellar.get_address(
|
||||
session, address_n, show_display=True, chunkify=True
|
||||
|
@ -38,9 +38,9 @@ def pin_request(session: Session):
|
||||
|
||||
|
||||
def set_autolock_delay(session: Session, delay):
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
pin_request(session),
|
||||
messages.ButtonRequest,
|
||||
@ -52,18 +52,19 @@ def set_autolock_delay(session: Session, delay):
|
||||
|
||||
|
||||
def test_apply_auto_lock_delay(session: Session):
|
||||
client = session.client
|
||||
set_autolock_delay(session, 10 * 1000)
|
||||
|
||||
time.sleep(0.1) # sleep less than auto-lock delay
|
||||
with session:
|
||||
with client:
|
||||
# No PIN protection is required.
|
||||
session.set_expected_responses([messages.Address])
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
time.sleep(10.5) # sleep more than auto-lock delay
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses([pin_request(session), messages.Address])
|
||||
with client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses([pin_request(session), messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
|
||||
@ -85,8 +86,8 @@ def test_apply_auto_lock_delay_valid(session: Session, seconds):
|
||||
|
||||
def test_autolock_default_value(session: Session):
|
||||
assert session.features.auto_lock_delay_ms is None
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
device.apply_settings(session, label="pls unlock")
|
||||
session.refresh_features()
|
||||
assert session.features.auto_lock_delay_ms == 60 * 10 * 1000
|
||||
@ -98,9 +99,9 @@ def test_autolock_default_value(session: Session):
|
||||
)
|
||||
def test_apply_auto_lock_delay_out_of_range(session: Session, seconds):
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[
|
||||
pin_request(session),
|
||||
messages.Failure(code=messages.FailureType.ProcessError),
|
||||
|
@ -48,8 +48,8 @@ def test_busy_state(session: Session):
|
||||
_assert_busy(session, True)
|
||||
assert session.features.unlocked is False
|
||||
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN])
|
||||
btc.get_address(
|
||||
session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"), show_display=True
|
||||
)
|
||||
|
@ -40,9 +40,9 @@ def test_cancel_message_via_cancel(session: Session, message):
|
||||
yield
|
||||
session.cancel()
|
||||
|
||||
with session, pytest.raises(Cancelled):
|
||||
session.set_expected_responses([m.ButtonRequest(), m.Failure()])
|
||||
session.set_input_flow(input_flow)
|
||||
with session.client as client, pytest.raises(Cancelled):
|
||||
client.set_expected_responses([m.ButtonRequest(), m.Failure()])
|
||||
client.set_input_flow(input_flow)
|
||||
session.call(message)
|
||||
|
||||
|
||||
|
@ -47,12 +47,12 @@ def test_pin(session: Session):
|
||||
)
|
||||
assert isinstance(resp, messages.PinMatrixRequest)
|
||||
|
||||
with session:
|
||||
state = session.client.debug.state()
|
||||
with session.client as client:
|
||||
state = client.debug.state()
|
||||
assert state.pin == "1234"
|
||||
assert state.matrix != ""
|
||||
|
||||
pin_encoded = session.client.debug.encode_pin("1234")
|
||||
pin_encoded = client.debug.encode_pin("1234")
|
||||
resp = session.call_raw(messages.PinMatrixAck(pin=pin_encoded))
|
||||
assert isinstance(resp, messages.PassphraseRequest)
|
||||
|
||||
|
@ -79,9 +79,9 @@ def _check_ping_screen_texts(session: Session, title: str, right_button: str) ->
|
||||
if session.model in (models.T2T1, models.T3T1):
|
||||
right_button = "-"
|
||||
|
||||
with session:
|
||||
session.client.watch_layout(True)
|
||||
session.set_input_flow(ping_input_flow(session, title, right_button))
|
||||
with session.client as client:
|
||||
client.watch_layout(True)
|
||||
client.set_input_flow(ping_input_flow(session, title, right_button))
|
||||
ping = session.call(messages.Ping(message="ahoj!", button_protection=True))
|
||||
assert ping == messages.Success(message="ahoj!")
|
||||
|
||||
@ -93,7 +93,7 @@ def test_error_too_long(session: Session):
|
||||
max_length = MAX_DATA_LENGTH[session.model]
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Translations too long"
|
||||
), session:
|
||||
), session.client:
|
||||
bad_data = (max_length + 1) * b"a"
|
||||
device.change_language(session, language_data=bad_data)
|
||||
assert session.features.language == "en-US"
|
||||
@ -104,7 +104,9 @@ def test_error_invalid_data_length(session: Session):
|
||||
assert session.features.language == "en-US"
|
||||
# Invalid data length
|
||||
# Sending more data than advertised in the header
|
||||
with pytest.raises(exceptions.TrezorFailure, match="Invalid data length"), session:
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Invalid data length"
|
||||
), session.client:
|
||||
good_data = build_and_sign_blob("cs", session)
|
||||
bad_data = good_data + b"abcd"
|
||||
device.change_language(session, language_data=bad_data)
|
||||
@ -118,7 +120,7 @@ def test_error_invalid_header_magic(session: Session):
|
||||
# Does not match the expected magic
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Invalid translations data"
|
||||
), session:
|
||||
), session.client:
|
||||
good_data = build_and_sign_blob("cs", session)
|
||||
bad_data = 4 * b"a" + good_data[4:]
|
||||
device.change_language(session, language_data=bad_data)
|
||||
@ -132,7 +134,7 @@ def test_error_invalid_data_hash(session: Session):
|
||||
# Changing the data after their hash has been calculated
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Translation data verification failed"
|
||||
), session:
|
||||
), session.client:
|
||||
good_data = build_and_sign_blob("cs", session)
|
||||
bad_data = good_data[:-8] + 8 * b"a"
|
||||
device.change_language(
|
||||
@ -149,7 +151,7 @@ def test_error_version_mismatch(session: Session):
|
||||
# Change the version to one not matching the current device
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Translations version mismatch"
|
||||
), session:
|
||||
), session.client:
|
||||
blob = prepare_blob("cs", session.model, (3, 5, 4, 0))
|
||||
device.change_language(
|
||||
session,
|
||||
@ -165,7 +167,7 @@ def test_error_invalid_signature(session: Session):
|
||||
# Changing the data in the signature section
|
||||
with pytest.raises(
|
||||
exceptions.TrezorFailure, match="Invalid translations data"
|
||||
), session:
|
||||
), session.client:
|
||||
blob = prepare_blob("cs", session.model, session.version)
|
||||
blob.proof = translations.Proof(
|
||||
merkle_proof=[],
|
||||
@ -274,8 +276,8 @@ def test_reject_update(session: Session):
|
||||
yield
|
||||
session.client.debug.press_no()
|
||||
|
||||
with pytest.raises(exceptions.Cancelled), session:
|
||||
session.set_input_flow(input_flow_reject)
|
||||
with pytest.raises(exceptions.Cancelled), session.client as client:
|
||||
client.set_input_flow(input_flow_reject)
|
||||
device.change_language(session, language_data)
|
||||
|
||||
assert session.features.language == "en-US"
|
||||
@ -311,8 +313,8 @@ def _maybe_confirm_set_language(
|
||||
else:
|
||||
expected_responses = expected_responses_silent
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
device.change_language(session, language_data, show_display=show_display)
|
||||
assert session.features.language is not None
|
||||
assert session.features.language[:2] == lang
|
||||
@ -320,9 +322,9 @@ def _maybe_confirm_set_language(
|
||||
# explicitly handle the cases when expected_responses are correct for
|
||||
# change_language but incorrect for selected is_displayed mode (otherwise the
|
||||
# user would get an unhelpful generic expected_responses mismatch)
|
||||
if is_displayed and session.actual_responses == expected_responses_silent:
|
||||
if is_displayed and client.actual_responses == expected_responses_silent:
|
||||
raise AssertionError("Change should have been visible but was silent")
|
||||
if not is_displayed and session.actual_responses == expected_responses_confirm:
|
||||
if not is_displayed and client.actual_responses == expected_responses_confirm:
|
||||
raise AssertionError("Change should have been silent but was visible")
|
||||
# if the expected_responses do not match either, the generic error message will
|
||||
# be raised by the session context manager
|
||||
|
@ -20,6 +20,7 @@ import pytest
|
||||
|
||||
from trezorlib import btc, device, exceptions, messages, misc, models
|
||||
from trezorlib.debuglink import SessionDebugWrapper as Session
|
||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from ..input_flows import InputFlowConfirmAllWarnings
|
||||
@ -50,19 +51,19 @@ T1_HOMESCREEN = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x
|
||||
TR_HOMESCREEN = b"TOIG\x80\x00@\x00\x0c\x04\x00\x00\xa5RY\x96\xdc0\x08\xe4\x06\xdc\xff\x96\xdc\x80\xa8\x16\x90z\xd2y\xf9\x18{<m\xc9\x02j\xeb\xea_\xddy\xfe~\xf14:\xfc\xe2I\x00\xf8\xff\x13\xff\xfa\xc6>\xc0\xf1\xe5\xc9y\x0f\x95\x7f;C\xfe\xd0\xe1K\xefS\x96o\xf9\xb739\x1a\n\xc7\xde\x89\xff\x11\xd8=\xd5\xcf\xb1\x9f\xf7U\xf2\xa3spx\xb0&t\xe4\xaf3x\xcaT\xec\xe50k\xb4\xe8\nl\x16\xbf`'\xf3\xa7Z\x8d-\x98h\x1c\x03\x07\xf0\xcf\xf0\x8aD\x13\xec\x1f@y\x9e\xd8\xa3\xc6\x84F*\x1dx\x02U\x00\x10\xd3\x8cF\xbb\x97y\x18J\xa5T\x18x\x1c\x02\xc6\x90\xfd\xdc\x89\x1a\x94\xb3\xeb\x01\xdc\x9f2\x8c/\xe9/\x8c$\xc6\x9c\x1e\xf8C\x8f@\x17Q\x1d\x11F\x02g\xe4A \xebO\xad\xc6\xe3F\xa7\x8b\xf830R\x82\x0b\x8e\x16\x1dL,\x14\xce\x057tht^\xfe\x00\x9e\x86\xc2\x86\xa3b~^Bl\x18\x1f\xb9+w\x11\x14\xceO\xe9\xb6W\xd8\x85\xbeX\x17\xc2\x13,M`y\xd1~\xa3/\xcd0\xed6\xda\xf5b\x15\xb5\x18\x0f_\xf6\xe2\xdc\x8d\x8ez\xdd\xd5\r^O\x9e\xb6|\xc4e\x0f\x1f\xff0k\xd4\xb8\n\x12{\x8d\x8a>\x0b5\xa2o\xf2jZ\xe5\xee\xdc\x14\xd1\xbd\xd5\xad\x95\xbe\x8c\t\x8f\xb9\xde\xc4\xa551,#`\x94'\x1b\xe7\xd53u\x8fq\xbd4v>3\x8f\xcc\x1d\xbcV>\x90^\xb3L\xc3\xde0]\x05\xec\x83\xd0\x07\xd2(\xbb\xcf+\xd0\xc7ru\xecn\x14k-\xc0|\xd2\x0e\xe8\xe08\xa8<\xdaQ+{\xad\x01\x02#\x16\x12+\xc8\xe0P\x06\xedD7\xae\xd0\xa4\x97\x84\xe32\xca;]\xd04x:\x94`\xbe\xca\x89\xe2\xcb\xc5L\x03\xac|\xe7\xd5\x1f\xe3\x08_\xee!\x04\xd2\xef\x00\xd8\xea\x91p)\xed^#\xb1\xa78eJ\x00F*\xc7\xf1\x0c\x1a\x04\xf5l\xcc\xfc\xa4\x83,c\x1e\xb1>\xc5q\x8b\xe6Y9\xc7\x07\xfa\xcf\xf9\x15\x8a\xdd\x11\x1f\x98\x82\xbe>\xbe+u#g]aC\\\x1bC\xb1\xe8P\xce2\xd6\xb6r\x12\x1c*\xd3\x92\x9d9\xf9cB\x82\xf9S.\xc2B\xe7\x9d\xcf\xdb\xf3\xfd#\xfd\x94x9p<D?\x0e0\xd0)ufMK\x9d\x84\xbf\x95\x02\x15\x04\xaf\x9b\xd7|\x9f\xf5\xc2\x19D\xe1\xe8pC=\\\xb54\xff\xfd<\xfc\x8b\x83\x19\x9aZ\x99J\x9d\xa2oP6\xb2=\xe0\xe5=Z0\x7f\xb6\xe9\xb1\x98\n\xcc \xdb\x9f\xb6\xf4\xc2\x82Z:\t\xf2\xcd\x88\xe3\x8a0\n\x13\xdd\xf9;\xdbtr\xf4kj\xa6\x90\x9d\x97\x92+#\xf4;t\x1e6\x80\xcd)\xfe\xe1\xabdD(V\xf5\xcc\xcf\xbeY\xd8\xddX\x08*\xc5\xd6\xa1\xa2\xae\x89s]\xafj\x9b\x07\x8d\xcf\xb5\n\x162\xb7\xb0\x02p\xc0.{\xbf\xd6\xc7|\x8a\x8c\xc9g\xa8DO\x85\xf6<E\x05Ek\x8c\xbfU\x13bz\xcf\xd0\x07\xcd^\x0f\x9b\x951\xa1vb\x17u:\xd2X\x91/\x0f\x9a\xae\x16T\x81\xb6\x8e\xdc,\xb0\xa1=\x11af%^\xec\x95\x83\xa9\xb8+\xd0i\xe0+#%\x02\xfd2\x84\xf3\xde\x0c\x88\x8c\x80\xf7\xc2H\xaa#\x80m\xf4\x1e\xd4#\x04J\r\xb6\xf83s\x8c\x0e\x0bx\xabw\xbe\x90\x94\x90:C\x88\x9bR`B\xc02\x1a\x08\xca-M9\xac\xa3TP\xb1\x83\xf2\x8aT\xe9\xc0c9(\xe5d\xd1\xac\xfd\x83\xf3\xb4C\x95\x04doh\xd7M\xed \xd0\x90\xc9|\x8a\x1fX\x1f\x0eI\x12\x8e&\xc3\x91NM-\x02\xeckp\x1a/\x19\x9d\xf2\xb4$\x0eG:\xbe\xb2~\x10(,\x1cd\x07\xbb]n^F@\x173'\xc63\xdf!u\xf4F\xa9\xc3\x96E!e\xc2Iv\xe8zQH=v\x89\x9a\x04a^\x10\x06\x01\x04!2\xa6\x1b\xba\x111/\xfa\xfa\x9c\x15 @\xf6\xb9{&\xcc\x84\xfa\xd6\x81\x90\xd4\x92\xcf\x89/\xc8\x80\xadP\xa3\xf4Xa\x1f\x04A\x07\xe6N\xd2oEZ\xc9\xa6(!\x8e#|\x0e\xfbq\xce\xe6\x8b-;\x06_\x04n\xdc\x8d^\x05s\xd2\xa8\x0f\xfa/\xfa\xf8\xe1x\n\xa3\xf701i7\x0c \x87\xec#\x80\x9c^X\x02\x01C\xc7\x85\x83\x9dS\xf5\x07"
|
||||
|
||||
|
||||
def _set_expected_responses(session: Session):
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
if session.model is models.T1B1:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_PIN_T1)
|
||||
def _set_expected_responses(client: Client):
|
||||
client.use_pin_sequence([PIN4])
|
||||
if client.model is models.T1B1:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_PIN_T1)
|
||||
else:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_PIN_TT)
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_PIN_TT)
|
||||
|
||||
|
||||
def test_apply_settings(session: Session):
|
||||
assert session.features.label == "test"
|
||||
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
with session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, label="new label")
|
||||
|
||||
assert session.features.label == "new label"
|
||||
@ -72,8 +73,8 @@ def test_apply_settings(session: Session):
|
||||
def test_apply_settings_rotation(session: Session):
|
||||
assert session.features.display_rotation is None
|
||||
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
with session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, display_rotation=messages.DisplayRotation.West)
|
||||
|
||||
assert session.features.display_rotation == messages.DisplayRotation.West
|
||||
@ -81,20 +82,21 @@ def test_apply_settings_rotation(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4, passphrase=False)
|
||||
def test_apply_settings_passphrase(session: Session):
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
client = session.client
|
||||
with client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, use_passphrase=True)
|
||||
|
||||
assert session.features.passphrase_protection is True
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, use_passphrase=False)
|
||||
|
||||
assert session.features.passphrase_protection is False
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, use_passphrase=True)
|
||||
|
||||
assert session.features.passphrase_protection is True
|
||||
@ -103,32 +105,33 @@ def test_apply_settings_passphrase(session: Session):
|
||||
@pytest.mark.setup_client(passphrase=False)
|
||||
@pytest.mark.models("core")
|
||||
def test_apply_settings_passphrase_on_device(session: Session):
|
||||
client = session.client
|
||||
# enable passphrase
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, use_passphrase=True)
|
||||
|
||||
assert session.features.passphrase_protection is True
|
||||
|
||||
# enable force on device
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, passphrase_always_on_device=True)
|
||||
|
||||
assert session.features.passphrase_protection is True
|
||||
assert session.features.passphrase_always_on_device is True
|
||||
|
||||
# turning off the passphrase should also clear the always_on_device setting
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, use_passphrase=False)
|
||||
|
||||
assert session.features.passphrase_protection is False
|
||||
assert session.features.passphrase_always_on_device is False
|
||||
|
||||
# and turning it back on does not modify always_on_device
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, use_passphrase=True)
|
||||
|
||||
assert session.features.passphrase_protection is True
|
||||
@ -137,35 +140,36 @@ def test_apply_settings_passphrase_on_device(session: Session):
|
||||
|
||||
@pytest.mark.models("safe3")
|
||||
def test_apply_homescreen_tr_toif_good(session: Session):
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
with session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=TR_HOMESCREEN)
|
||||
|
||||
# Revert to default settings
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, homescreen=b"")
|
||||
|
||||
|
||||
@pytest.mark.models("safe3")
|
||||
@pytest.mark.setup_client(pin=None) # so that "PIN NOT SET" is shown in the header
|
||||
def test_apply_homescreen_tr_toif_with_notification(session: Session):
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, homescreen=TR_HOMESCREEN)
|
||||
|
||||
|
||||
@pytest.mark.models("safe3")
|
||||
def test_apply_homescreen_tr_toif_with_long_label(session: Session):
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
client = session.client
|
||||
with session.client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=TR_HOMESCREEN)
|
||||
|
||||
# Showing longer label
|
||||
with session:
|
||||
with session.client:
|
||||
device.apply_settings(session, label="My long label")
|
||||
|
||||
# Showing label that will not fit on the line
|
||||
with session:
|
||||
with session.client:
|
||||
device.apply_settings(session, label="My even longer label")
|
||||
|
||||
|
||||
@ -173,8 +177,8 @@ def test_apply_homescreen_tr_toif_with_long_label(session: Session):
|
||||
def test_apply_homescreen_tr_toif_wrong_size(session: Session):
|
||||
# 64x64 img
|
||||
img = b"TOIG@\x00@\x009\x02\x00\x00}R\xdb\x81$A\x08\"\x03\xf3\xcf\xd2\x0c<\x01-{\xefc\xe6\xd5\xbbU\xa2\x08T\xd6\xcfw\xf4\xe7\xc7\xb7X\xf1\xe3\x1bl\xf0\xf7\x1b\xf8\x1f\xcf\xe7}\xe1\x83\xcf|>\x8d%\x14\xa5\xb3\xe9p5\xa1;~4:\xcd\xe0&\x11\x1d\xe9\xf6\xa1\x1fw\xf54\x95eWx\xda\xd0u\x91\x86\xb8\xbc\xdf\xdc\x008f\x15\xc6\xf6\x7f\xf0T\xb8\xc1\xa3\xc5_A\xc0G\x930\xe7\xdc=\xd5\xa7\xc1\xbcI\x16\xb8s\x9c&\xaa\x06\xc1}\x8b\x19\x9d'c\xc3\xe3^\xc3m\xb6n\xb0(\x16\xf6\xdeg\xb3\x96:i\xe5\x9c\x02\x93\x9fF\x9f-\xa7\"w\xf3X\x9f\x87\x08\x84\"v,\xab!9:<j+\xcb\xf3_\xc7\xd6^<\xce\xc1\xb8!\xec\x8f/\xb1\xc1\x8f\xbd\xcc\x06\x90\x0e\x98)[\xdb\x15\x99\xaf\xf2~\x8e\xd0\xdb\xcd\xfd\x90\x12\xb6\xdd\xc3\xdd|\x96$\x01P\x86H\xbc\xc0}\xa2\x08\xe5\x82\x06\xd2\xeb\x07[\r\xe4\xdeP\xf4\x86;\xa5\x14c\x12\xe3\xb16x\xad\xc7\x1d\x02\xef\x86<\xc6\x95\xd3/\xc4 \xa1\xf5V\xe2\t\xb2\x8a\xd6`\xf2\xcf\xb7\xd6\x07\xdf8X\xa7\x18\x03\x96\x82\xa4 \xeb.*kP\xceu\x9d~}H\xe9\xb8\x04<4\xff\xf8\xcf\xf6\xa0\xf2\xfcM\xe3/?k\xff\x18\x1d\xb1\xee\xc5\xf5\x1f\x01\x14\x03;\x1bU\x1f~\xcf\xb3\xf7w\xe5\nMfd/\xb93\x9fq\x9bQ\xb7'\xbfvq\x1d\xce\r\xbaDo\x90\xbc\xc5:?;\x84y\x8a\x1e\xad\xe9\xb7\x14\x10~\x9b@\xf8\x82\xdc\x89\xe7\xf0\xe0k4o\x9a\xa0\xc4\xb9\xba\xc56\x01i\x85EO'e6\xb7\x15\xb4G\x05\xe1\xe7%\xd3&\x93\x91\xc9CTQ\xeb\xcc\xd0\xd7E9\xa9JK\xcc\x00\x95(\xdc.\xd2#7:Yo}y_*\x1a\xae6)\x97\x9d\xc0\x80vl\x02\\M\xfe\xc9sW\xa8\xfbD\x99\xb8\xb0:\xbc\x80\xfd\xef\xd3\x94\xbe\x18j9z\x12S\xa1\xec$\x1c\xe3\xd1\xd0\xf4\xdd\xbfI\xf1rBj\x0f\x1cz\x1d\xf7\xa5tR\xb3\xfc\xa4\xd0\xfah\xc3Mj\xbe\x14r\x9d\x84z\xd2\x7f\x13\xb4w\xce\xa0\xaeW\xa4\x18\x0b\xe4\x8f\xe6\xc3\xbeQ\x93\xb0L<J\xe3g9\xb5W#f\xd1\x0b\x96|\xd6z1;\x85\x7f\xe3\xe6[\x02A\xdc\xa4\x02\x1b\x91\x88\x7f"
|
||||
with pytest.raises(exceptions.TrezorFailure), session:
|
||||
_set_expected_responses(session)
|
||||
with pytest.raises(exceptions.TrezorFailure), session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=img)
|
||||
|
||||
|
||||
@ -182,15 +186,15 @@ def test_apply_homescreen_tr_toif_wrong_size(session: Session):
|
||||
def test_apply_homescreen_tr_upload_jpeg_fail(session: Session):
|
||||
with open(HERE / "test_bg.jpg", "rb") as f:
|
||||
img = f.read()
|
||||
with pytest.raises(exceptions.TrezorFailure), session:
|
||||
_set_expected_responses(session)
|
||||
with pytest.raises(exceptions.TrezorFailure), session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=img)
|
||||
|
||||
|
||||
@pytest.mark.models("safe3")
|
||||
def test_apply_homescreen_tr_upload_t1_fail(session: Session):
|
||||
with pytest.raises(exceptions.TrezorFailure), session:
|
||||
_set_expected_responses(session)
|
||||
with pytest.raises(exceptions.TrezorFailure), session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=T1_HOMESCREEN)
|
||||
|
||||
|
||||
@ -198,8 +202,8 @@ def test_apply_homescreen_tr_upload_t1_fail(session: Session):
|
||||
def test_apply_homescreen_toif(session: Session):
|
||||
img = b"TOIf\x90\x00\x90\x00~\x00\x00\x00\xed\xd2\xcb\r\x83@\x10D\xc1^.\xde#!\xac31\x99\x10\x8aC%\x14~\x16\x92Y9\x02WI3\x01<\xf5cI2d\x1es(\xe1[\xdbn\xba\xca\xe8s7\xa4\xd5\xd4\xb3\x13\xbdw\xf6:\xf3\xd1\xe7%\xc7]\xdd_\xb3\x9e\x9f\x9e\x9fN\xed\xaaE\xef\xdc\xcf$D\xa7\xa4X\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0OV"
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure), session:
|
||||
_set_expected_responses(session)
|
||||
with pytest.raises(exceptions.TrezorFailure), session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=img)
|
||||
|
||||
|
||||
@ -208,11 +212,11 @@ def test_apply_homescreen_jpeg(session: Session):
|
||||
with open(HERE / "test_bg.jpg", "rb") as f:
|
||||
img = f.read()
|
||||
# raise Exception("FAILS FOR SOME REASON ")
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
with session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=img)
|
||||
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, homescreen=b"")
|
||||
|
||||
|
||||
@ -267,8 +271,8 @@ def test_apply_homescreen_jpeg_progressive(session: Session):
|
||||
b"\x00\x00\x00\x00\x90\xff\xda\x00\x08\x01\x01\x00\x01?\x10a?\xff\xd9"
|
||||
)
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure), session:
|
||||
_set_expected_responses(session)
|
||||
with pytest.raises(exceptions.TrezorFailure), session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=img)
|
||||
|
||||
|
||||
@ -313,76 +317,79 @@ def test_apply_homescreen_jpeg_wrong_size(session: Session):
|
||||
b"\x00\x00\x1f\xff\xd9"
|
||||
)
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure), session:
|
||||
_set_expected_responses(session)
|
||||
with pytest.raises(exceptions.TrezorFailure), session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=img)
|
||||
|
||||
|
||||
@pytest.mark.models("legacy")
|
||||
def test_apply_homescreen(session: Session):
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
with session.client as client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, homescreen=T1_HOMESCREEN)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_safety_checks(session: Session):
|
||||
client = session.client
|
||||
|
||||
def get_bad_address():
|
||||
btc.get_address(session, "Bitcoin", parse_path("m/44h"), show_display=True)
|
||||
|
||||
assert session.features.safety_checks == messages.SafetyCheckLevel.Strict
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), session:
|
||||
session.set_expected_responses([messages.Failure])
|
||||
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
get_bad_address()
|
||||
|
||||
if session.model is not models.T1B1:
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(
|
||||
session, safety_checks=messages.SafetyCheckLevel.PromptAlways
|
||||
)
|
||||
|
||||
assert session.features.safety_checks == messages.SafetyCheckLevel.PromptAlways
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest, messages.ButtonRequest, messages.Address]
|
||||
)
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
get_bad_address()
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(session, safety_checks=messages.SafetyCheckLevel.Strict)
|
||||
|
||||
assert session.features.safety_checks == messages.SafetyCheckLevel.Strict
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), session:
|
||||
session.set_expected_responses([messages.Failure])
|
||||
with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
get_bad_address()
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_NOPIN)
|
||||
device.apply_settings(
|
||||
session, safety_checks=messages.SafetyCheckLevel.PromptTemporarily
|
||||
)
|
||||
|
||||
assert session.features.safety_checks == messages.SafetyCheckLevel.PromptTemporarily
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest, messages.ButtonRequest, messages.Address]
|
||||
)
|
||||
if session.model is not models.T1B1:
|
||||
IF = InputFlowConfirmAllWarnings(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
get_bad_address()
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
def test_experimental_features(session: Session):
|
||||
client = session.client
|
||||
|
||||
def experimental_call():
|
||||
misc.get_nonce(session)
|
||||
@ -390,38 +397,38 @@ def test_experimental_features(session: Session):
|
||||
assert session.features.experimental_features is None
|
||||
|
||||
# unlock
|
||||
with session:
|
||||
_set_expected_responses(session)
|
||||
with session.client:
|
||||
_set_expected_responses(client)
|
||||
device.apply_settings(session, label="new label")
|
||||
|
||||
assert not session.features.experimental_features
|
||||
|
||||
with pytest.raises(exceptions.TrezorFailure, match="DataError"), session:
|
||||
session.set_expected_responses([messages.Failure])
|
||||
with pytest.raises(exceptions.TrezorFailure, match="DataError"), client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
experimental_call()
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(EXPECTED_RESPONSES_EXPERIMENTAL_FEATURES)
|
||||
with client:
|
||||
client.set_expected_responses(EXPECTED_RESPONSES_EXPERIMENTAL_FEATURES)
|
||||
device.apply_settings(session, experimental_features=True)
|
||||
|
||||
assert session.features.experimental_features
|
||||
|
||||
with session:
|
||||
session.set_expected_responses([messages.Nonce])
|
||||
with client:
|
||||
client.set_expected_responses([messages.Nonce])
|
||||
experimental_call()
|
||||
|
||||
# relock and try again
|
||||
session.lock()
|
||||
with session:
|
||||
with client:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses([messages.ButtonRequest, messages.Nonce])
|
||||
client.set_expected_responses([messages.ButtonRequest, messages.Nonce])
|
||||
experimental_call()
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_label_too_long(session: Session):
|
||||
with pytest.raises(exceptions.TrezorFailure), session:
|
||||
session.set_expected_responses([messages.Failure])
|
||||
with pytest.raises(exceptions.TrezorFailure), session.client as client:
|
||||
client.set_expected_responses([messages.Failure])
|
||||
device.apply_settings(session, label="A" * 33)
|
||||
|
||||
|
||||
|
@ -44,9 +44,9 @@ from ..input_flows import (
|
||||
def test_backup_bip39(session: Session):
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39Backup(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
assert IF.mnemonic == MNEMONIC12
|
||||
@ -71,9 +71,9 @@ def test_backup_slip39_basic(session: Session, click_info: bool):
|
||||
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicBackup(session.client, click_info)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
session.refresh_features()
|
||||
@ -95,12 +95,12 @@ def test_backup_slip39_basic(session: Session, click_info: bool):
|
||||
def test_backup_slip39_single(session: Session):
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowBip39Backup(
|
||||
session.client,
|
||||
confirm_success=(session.client.layout_type is not LayoutType.Delizia),
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
assert session.features.initialized is True
|
||||
@ -127,9 +127,9 @@ def test_backup_slip39_advanced(session: Session, click_info: bool):
|
||||
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39AdvancedBackup(session.client, click_info)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
session.refresh_features()
|
||||
@ -158,9 +158,9 @@ def test_backup_slip39_advanced(session: Session, click_info: bool):
|
||||
def test_backup_slip39_custom(session: Session, share_threshold, share_count):
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39CustomBackup(session.client, share_count)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(
|
||||
session, group_threshold=1, groups=[(share_threshold, share_count)]
|
||||
)
|
||||
|
@ -34,7 +34,7 @@ pytestmark = pytest.mark.models("legacy")
|
||||
|
||||
def _set_wipe_code(session: Session, pin, wipe_code):
|
||||
# Set/change wipe code.
|
||||
with session:
|
||||
with session.client as client:
|
||||
if session.features.pin_protection:
|
||||
pins = [pin, wipe_code, wipe_code]
|
||||
pin_matrices = [
|
||||
@ -49,8 +49,8 @@ def _set_wipe_code(session: Session, pin, wipe_code):
|
||||
messages.PinMatrixRequest(type=PinType.WipeCodeSecond),
|
||||
]
|
||||
|
||||
session.client.use_pin_sequence(pins)
|
||||
session.set_expected_responses(
|
||||
client.use_pin_sequence(pins)
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] + pin_matrices + [messages.Success]
|
||||
)
|
||||
device.change_wipe_code(session)
|
||||
@ -58,8 +58,8 @@ def _set_wipe_code(session: Session, pin, wipe_code):
|
||||
|
||||
def _change_pin(session: Session, old_pin, new_pin):
|
||||
assert session.features.pin_protection is True
|
||||
with session:
|
||||
session.client.use_pin_sequence([old_pin, new_pin, new_pin])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([old_pin, new_pin, new_pin])
|
||||
try:
|
||||
return device.change_pin(session)
|
||||
except exceptions.TrezorFailure as f:
|
||||
@ -96,8 +96,8 @@ def test_set_remove_wipe_code(session: Session):
|
||||
_check_wipe_code(session, PIN4, WIPE_CODE6)
|
||||
|
||||
# Test remove wipe code.
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
device.change_wipe_code(session, remove=True)
|
||||
|
||||
# Check that there's no wipe code protection now.
|
||||
@ -111,9 +111,9 @@ def test_set_wipe_code_mismatch(session: Session):
|
||||
assert session.features.wipe_code_protection is False
|
||||
|
||||
# Let's set a new wipe code.
|
||||
with session:
|
||||
session.client.use_pin_sequence([WIPE_CODE4, WIPE_CODE6])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([WIPE_CODE4, WIPE_CODE6])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(),
|
||||
messages.PinMatrixRequest(type=PinType.WipeCodeFirst),
|
||||
@ -125,8 +125,8 @@ def test_set_wipe_code_mismatch(session: Session):
|
||||
device.change_wipe_code(session)
|
||||
|
||||
# Check that there is no wipe code protection.
|
||||
session.client.refresh_features()
|
||||
assert session.client.features.wipe_code_protection is False
|
||||
client.refresh_features()
|
||||
assert client.features.wipe_code_protection is False
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4)
|
||||
@ -135,9 +135,9 @@ def test_set_wipe_code_to_pin(session: Session):
|
||||
assert session.features.wipe_code_protection is None
|
||||
|
||||
# Let's try setting the wipe code to the curent PIN value.
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4, PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4, PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(),
|
||||
messages.PinMatrixRequest(type=PinType.Current),
|
||||
@ -149,8 +149,8 @@ def test_set_wipe_code_to_pin(session: Session):
|
||||
device.change_wipe_code(session)
|
||||
|
||||
# Check that there is no wipe code protection.
|
||||
session.client.refresh_features()
|
||||
assert session.client.features.wipe_code_protection is False
|
||||
client.refresh_features()
|
||||
assert client.features.wipe_code_protection is False
|
||||
|
||||
|
||||
def test_set_pin_to_wipe_code(session: Session):
|
||||
@ -159,9 +159,9 @@ def test_set_pin_to_wipe_code(session: Session):
|
||||
_set_wipe_code(session, None, WIPE_CODE4)
|
||||
|
||||
# Try to set the PIN to the current wipe code value.
|
||||
with session:
|
||||
session.client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(),
|
||||
messages.PinMatrixRequest(type=PinType.NewFirst),
|
||||
|
@ -37,13 +37,13 @@ def _check_wipe_code(session: Session, pin: str, wipe_code: str):
|
||||
assert session.features.wipe_code_protection is True
|
||||
|
||||
# Try to change the PIN to the current wipe code value. The operation should fail.
|
||||
with session, pytest.raises(TrezorFailure):
|
||||
session.client.use_pin_sequence([pin, wipe_code, wipe_code])
|
||||
with session.client as client, pytest.raises(TrezorFailure):
|
||||
client.use_pin_sequence([pin, wipe_code, wipe_code])
|
||||
if session.client.layout_type is LayoutType.Caesar:
|
||||
br_count = 6
|
||||
else:
|
||||
br_count = 5
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] * br_count
|
||||
+ [messages.Failure(code=messages.FailureType.PinInvalid)]
|
||||
)
|
||||
@ -51,8 +51,8 @@ def _check_wipe_code(session: Session, pin: str, wipe_code: str):
|
||||
|
||||
|
||||
def _ensure_unlocked(session: Session, pin: str):
|
||||
with session:
|
||||
session.client.use_pin_sequence([pin])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([pin])
|
||||
btc.get_address(session, "Testnet", PASSPHRASE_TEST_PATH)
|
||||
|
||||
session.refresh_features()
|
||||
@ -60,22 +60,23 @@ def _ensure_unlocked(session: Session, pin: str):
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4)
|
||||
def test_set_remove_wipe_code(session: Session):
|
||||
client = session.client
|
||||
|
||||
# Test set wipe code.
|
||||
assert session.features.wipe_code_protection is None
|
||||
_ensure_unlocked(session, PIN4)
|
||||
assert session.features.wipe_code_protection is False
|
||||
|
||||
if session.client.layout_type is LayoutType.Caesar:
|
||||
if client.layout_type is LayoutType.Caesar:
|
||||
br_count = 6
|
||||
else:
|
||||
br_count = 5
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] * br_count + [messages.Success]
|
||||
)
|
||||
session.client.use_pin_sequence([PIN4, WIPE_CODE_MAX, WIPE_CODE_MAX])
|
||||
client.use_pin_sequence([PIN4, WIPE_CODE_MAX, WIPE_CODE_MAX])
|
||||
device.change_wipe_code(session)
|
||||
|
||||
# session.init_device()
|
||||
@ -83,11 +84,11 @@ def test_set_remove_wipe_code(session: Session):
|
||||
_check_wipe_code(session, PIN4, WIPE_CODE_MAX)
|
||||
|
||||
# Test change wipe code.
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] * br_count + [messages.Success]
|
||||
)
|
||||
session.client.use_pin_sequence([PIN4, WIPE_CODE6, WIPE_CODE6])
|
||||
client.use_pin_sequence([PIN4, WIPE_CODE6, WIPE_CODE6])
|
||||
device.change_wipe_code(session)
|
||||
|
||||
# session.init_device()
|
||||
@ -95,11 +96,11 @@ def test_set_remove_wipe_code(session: Session):
|
||||
_check_wipe_code(session, PIN4, WIPE_CODE6)
|
||||
|
||||
# Test remove wipe code.
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] * 3 + [messages.Success]
|
||||
)
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
client.use_pin_sequence([PIN4])
|
||||
device.change_wipe_code(session, remove=True)
|
||||
|
||||
# session.init_device()
|
||||
@ -107,11 +108,11 @@ def test_set_remove_wipe_code(session: Session):
|
||||
|
||||
|
||||
def test_set_wipe_code_mismatch(session: Session):
|
||||
with session, pytest.raises(TrezorFailure):
|
||||
with session.client as client, pytest.raises(TrezorFailure):
|
||||
IF = InputFlowNewCodeMismatch(
|
||||
session.client, WIPE_CODE4, WIPE_CODE6, what="wipe_code"
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
device.change_wipe_code(session)
|
||||
|
||||
@ -124,15 +125,15 @@ def test_set_wipe_code_mismatch(session: Session):
|
||||
def test_set_wipe_code_to_pin(session: Session):
|
||||
_ensure_unlocked(session, PIN4)
|
||||
|
||||
with session:
|
||||
if session.client.layout_type is LayoutType.Caesar:
|
||||
with session.client as client:
|
||||
if client.layout_type is LayoutType.Caesar:
|
||||
br_count = 8
|
||||
else:
|
||||
br_count = 7
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] * br_count + [messages.Success],
|
||||
)
|
||||
session.client.use_pin_sequence([PIN4, PIN4, WIPE_CODE4, WIPE_CODE4])
|
||||
client.use_pin_sequence([PIN4, PIN4, WIPE_CODE4, WIPE_CODE4])
|
||||
device.change_wipe_code(session)
|
||||
|
||||
# session.init_device()
|
||||
@ -141,27 +142,28 @@ def test_set_wipe_code_to_pin(session: Session):
|
||||
|
||||
|
||||
def test_set_pin_to_wipe_code(session: Session):
|
||||
client = session.client
|
||||
# Set wipe code.
|
||||
with session:
|
||||
if session.client.layout_type is LayoutType.Caesar:
|
||||
with client:
|
||||
if client.layout_type is LayoutType.Caesar:
|
||||
br_count = 5
|
||||
else:
|
||||
br_count = 4
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] * br_count + [messages.Success]
|
||||
)
|
||||
session.client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
|
||||
client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
|
||||
device.change_wipe_code(session)
|
||||
|
||||
# Try to set the PIN to the current wipe code value.
|
||||
with session, pytest.raises(TrezorFailure):
|
||||
if session.client.layout_type is LayoutType.Caesar:
|
||||
with client, pytest.raises(TrezorFailure):
|
||||
if client.layout_type is LayoutType.Caesar:
|
||||
br_count = 6
|
||||
else:
|
||||
br_count = 4
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest()] * br_count
|
||||
+ [messages.Failure(code=messages.FailureType.PinInvalid)]
|
||||
)
|
||||
session.client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
|
||||
client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
|
||||
device.change_pin(session)
|
||||
|
@ -33,16 +33,16 @@ pytestmark = pytest.mark.models("legacy")
|
||||
|
||||
def _check_pin(session: Session, pin):
|
||||
session.lock()
|
||||
with session:
|
||||
session.client.use_pin_sequence([pin])
|
||||
session.set_expected_responses([messages.PinMatrixRequest, messages.Address])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([pin])
|
||||
client.set_expected_responses([messages.PinMatrixRequest, messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
|
||||
def _check_no_pin(session: Session):
|
||||
session.lock()
|
||||
with session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with session.client as client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
|
||||
@ -53,9 +53,9 @@ def test_set_pin(session: Session):
|
||||
_check_no_pin(session)
|
||||
|
||||
# Let's set new PIN
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN_MAX, PIN_MAX])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN_MAX, PIN_MAX])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||
messages.PinMatrixRequest,
|
||||
@ -78,9 +78,9 @@ def test_change_pin(session: Session):
|
||||
_check_pin(session, PIN4)
|
||||
|
||||
# Let's change PIN
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4, PIN_MAX, PIN_MAX])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4, PIN_MAX, PIN_MAX])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||
messages.PinMatrixRequest,
|
||||
@ -104,9 +104,9 @@ def test_remove_pin(session: Session):
|
||||
_check_pin(session, PIN4)
|
||||
|
||||
# Let's remove PIN
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||
messages.PinMatrixRequest,
|
||||
@ -126,10 +126,10 @@ def test_set_mismatch(session: Session):
|
||||
_check_no_pin(session)
|
||||
|
||||
# Let's set new PIN
|
||||
with session, pytest.raises(TrezorFailure, match="PIN mismatch"):
|
||||
with session.client as client, pytest.raises(TrezorFailure, match="PIN mismatch"):
|
||||
# use different PINs for first and second attempt. This will fail.
|
||||
session.client.use_pin_sequence([PIN4, PIN_MAX])
|
||||
session.set_expected_responses(
|
||||
client.use_pin_sequence([PIN4, PIN_MAX])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||
messages.PinMatrixRequest,
|
||||
@ -150,9 +150,9 @@ def test_change_mismatch(session: Session):
|
||||
assert session.features.pin_protection is True
|
||||
|
||||
# Let's set new PIN
|
||||
with session, pytest.raises(TrezorFailure, match="PIN mismatch"):
|
||||
session.client.use_pin_sequence([PIN4, PIN6, PIN6 + "3"])
|
||||
session.set_expected_responses(
|
||||
with session.client as client, pytest.raises(TrezorFailure, match="PIN mismatch"):
|
||||
client.use_pin_sequence([PIN4, PIN6, PIN6 + "3"])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||
messages.PinMatrixRequest,
|
||||
|
@ -37,13 +37,13 @@ pytestmark = pytest.mark.models("core")
|
||||
|
||||
def _check_pin(session: Session, pin: str):
|
||||
|
||||
with session:
|
||||
session.client.ui.__init__(session.client.debug)
|
||||
session.client.use_pin_sequence([pin, pin, pin, pin, pin, pin])
|
||||
with session.client as client:
|
||||
client.ui.__init__(session.client.debug)
|
||||
client.use_pin_sequence([pin, pin, pin, pin, pin, pin])
|
||||
session.lock()
|
||||
assert session.features.pin_protection is True
|
||||
assert session.features.unlocked is False
|
||||
session.set_expected_responses([messages.ButtonRequest, messages.Address])
|
||||
client.set_expected_responses([messages.ButtonRequest, messages.Address])
|
||||
btc.get_address(session, "Testnet", PASSPHRASE_TEST_PATH)
|
||||
|
||||
|
||||
@ -51,8 +51,8 @@ def _check_no_pin(session: Session):
|
||||
session.lock()
|
||||
assert session.features.pin_protection is False
|
||||
|
||||
with session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with session.client as client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
btc.get_address(session, "Testnet", PASSPHRASE_TEST_PATH)
|
||||
|
||||
|
||||
@ -63,13 +63,13 @@ def test_set_pin(session: Session):
|
||||
_check_no_pin(session)
|
||||
|
||||
# Let's set new PIN
|
||||
with session:
|
||||
if session.client.layout_type is LayoutType.Caesar:
|
||||
with session.client as client:
|
||||
if client.layout_type is LayoutType.Caesar:
|
||||
br_count = 6
|
||||
else:
|
||||
br_count = 4
|
||||
session.client.use_pin_sequence([PIN_MAX, PIN_MAX])
|
||||
session.set_expected_responses(
|
||||
client.use_pin_sequence([PIN_MAX, PIN_MAX])
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest] * br_count + [messages.Success]
|
||||
)
|
||||
device.change_pin(session)
|
||||
@ -86,13 +86,13 @@ def test_change_pin(session: Session):
|
||||
_check_pin(session, PIN4)
|
||||
|
||||
# Let's change PIN
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4, PIN_MAX, PIN_MAX])
|
||||
if session.client.layout_type is LayoutType.Caesar:
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4, PIN_MAX, PIN_MAX])
|
||||
if client.layout_type is LayoutType.Caesar:
|
||||
br_count = 6
|
||||
else:
|
||||
br_count = 5
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest] * br_count
|
||||
+ [messages.Success] # , messages.Features]
|
||||
)
|
||||
@ -113,11 +113,9 @@ def test_remove_pin(session: Session):
|
||||
_check_pin(session, PIN4)
|
||||
|
||||
# Let's remove PIN
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(
|
||||
[messages.ButtonRequest] * 3 + [messages.Success]
|
||||
)
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses([messages.ButtonRequest] * 3 + [messages.Success])
|
||||
device.change_pin(session, remove=True)
|
||||
|
||||
# Check that there's no PIN protection now
|
||||
@ -132,9 +130,9 @@ def test_set_failed(session: Session):
|
||||
# Check that there's no PIN protection
|
||||
_check_no_pin(session)
|
||||
|
||||
with session, pytest.raises(TrezorFailure):
|
||||
with session.client as client, pytest.raises(TrezorFailure):
|
||||
IF = InputFlowNewCodeMismatch(session.client, PIN4, PIN60, what="pin")
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
device.change_pin(session)
|
||||
|
||||
@ -151,9 +149,9 @@ def test_change_failed(session: Session):
|
||||
# Check current PIN value
|
||||
_check_pin(session, PIN4)
|
||||
|
||||
with session, pytest.raises(Cancelled):
|
||||
with session.client as client, pytest.raises(Cancelled):
|
||||
IF = InputFlowCodeChangeFail(session, PIN4, "457891", "381847")
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
device.change_pin(session)
|
||||
|
||||
@ -170,9 +168,9 @@ def test_change_invalid_current(session: Session):
|
||||
# Check current PIN value
|
||||
_check_pin(session, PIN4)
|
||||
|
||||
with session, pytest.raises(TrezorFailure):
|
||||
with session.client as client, pytest.raises(TrezorFailure):
|
||||
IF = InputFlowWrongPIN(session.client, PIN60)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
device.change_pin(session)
|
||||
|
||||
@ -200,7 +198,7 @@ def test_pin_menu_cancel_setup(session: Session):
|
||||
# tap to confirm
|
||||
debug.click(debug.screen_buttons.tap_to_confirm())
|
||||
|
||||
with session, pytest.raises(Cancelled):
|
||||
session.set_input_flow(cancel_pin_setup_input_flow)
|
||||
with session.client as client, pytest.raises(Cancelled):
|
||||
client.set_input_flow(cancel_pin_setup_input_flow)
|
||||
session.call(messages.ChangePin())
|
||||
_check_no_pin(session)
|
||||
|
@ -19,13 +19,14 @@ from trezorlib.debuglink import SessionDebugWrapper as Session
|
||||
|
||||
|
||||
def test_ping(session: Session):
|
||||
with session:
|
||||
session.set_expected_responses([messages.Success])
|
||||
client = session.client
|
||||
with client:
|
||||
client.set_expected_responses([messages.Success])
|
||||
res = session.call(messages.Ping(message="random data"))
|
||||
assert res.message == "random data"
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||
messages.Success,
|
||||
|
@ -69,7 +69,7 @@ def test_autolock_not_retained(session: Session):
|
||||
time.sleep(10.5)
|
||||
session = client.get_session()
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
# after sleeping for the pre-wipe autolock amount, Trezor must still be unlocked
|
||||
session.set_expected_responses([messages.Address])
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
@ -33,17 +33,17 @@ pytestmark = pytest.mark.setup_client(pin=PIN4)
|
||||
|
||||
@pytest.mark.setup_client(pin=None)
|
||||
def test_no_protection(session: Session):
|
||||
with session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with session.client as client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
|
||||
def test_correct_pin(session: Session):
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
# Expected responses differ between T1 and TT
|
||||
is_t1 = session.model is models.T1B1
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[
|
||||
(is_t1, messages.PinMatrixRequest),
|
||||
(
|
||||
@ -65,10 +65,10 @@ def test_incorrect_pin_t1(session: Session):
|
||||
|
||||
@pytest.mark.models("core")
|
||||
def test_incorrect_pin_t2(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
# After first incorrect attempt, TT will not raise an error, but instead ask for another attempt
|
||||
session.client.use_pin_sequence([BAD_PIN, PIN4])
|
||||
session.set_expected_responses(
|
||||
client.use_pin_sequence([BAD_PIN, PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.PinEntry),
|
||||
messages.ButtonRequest(code=messages.ButtonRequestType.PinEntry),
|
||||
@ -82,15 +82,15 @@ def test_incorrect_pin_t2(session: Session):
|
||||
def test_exponential_backoff_t1(session: Session):
|
||||
for attempt in range(3):
|
||||
start = time.time()
|
||||
with session, pytest.raises(PinException):
|
||||
session.client.use_pin_sequence([BAD_PIN])
|
||||
with session.client as client, pytest.raises(PinException):
|
||||
client.use_pin_sequence([BAD_PIN])
|
||||
get_test_address(session)
|
||||
check_pin_backoff_time(attempt, start)
|
||||
|
||||
|
||||
@pytest.mark.models("core")
|
||||
def test_exponential_backoff_t2(session: Session):
|
||||
with session:
|
||||
IF = InputFlowPINBackoff(session.client, BAD_PIN, PIN4)
|
||||
session.set_input_flow(IF.get())
|
||||
with session.client as client:
|
||||
IF = InputFlowPINBackoff(client, BAD_PIN, PIN4)
|
||||
client.set_input_flow(IF.get())
|
||||
get_test_address(session)
|
||||
|
@ -56,26 +56,26 @@ def _assert_protection(
|
||||
session: Session, pin: bool = True, passphrase: bool = True
|
||||
) -> Session:
|
||||
"""Make sure PIN and passphrase protection have expected values"""
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
session.ensure_unlocked()
|
||||
session.client.refresh_features()
|
||||
assert session.client.features.pin_protection is pin
|
||||
assert session.client.features.passphrase_protection is passphrase
|
||||
client.refresh_features()
|
||||
assert client.features.pin_protection is pin
|
||||
assert client.features.passphrase_protection is passphrase
|
||||
session.lock()
|
||||
# session.end()
|
||||
if session.protocol_version == ProtocolVersion.V1:
|
||||
new_session = session.client.get_session()
|
||||
new_session = client.get_session()
|
||||
return new_session
|
||||
|
||||
|
||||
def test_initialize(session: Session):
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
session.ensure_unlocked()
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.set_expected_responses([messages.Features])
|
||||
with session.client as client:
|
||||
client.set_expected_responses([messages.Features])
|
||||
session.call(messages.Initialize(session_id=session.id))
|
||||
|
||||
|
||||
@ -86,8 +86,8 @@ def test_passphrase_reporting(session: Session, passphrase):
|
||||
"""On TT, passphrase_protection is a private setting, so a locked device should
|
||||
report passphrase_protection=None.
|
||||
"""
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
device.apply_settings(session, use_passphrase=passphrase)
|
||||
|
||||
session.lock()
|
||||
@ -108,9 +108,9 @@ def test_passphrase_reporting(session: Session, passphrase):
|
||||
def test_apply_settings(session: Session):
|
||||
session = _assert_protection(session)
|
||||
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
_pin_request(session),
|
||||
messages.ButtonRequest,
|
||||
@ -124,9 +124,9 @@ def test_apply_settings(session: Session):
|
||||
@pytest.mark.models("legacy")
|
||||
def test_change_pin_t1(session: Session):
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4, PIN4, PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4, PIN4, PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest,
|
||||
_pin_request(session),
|
||||
@ -141,16 +141,16 @@ def test_change_pin_t1(session: Session):
|
||||
@pytest.mark.models("core")
|
||||
def test_change_pin_t2(session: Session):
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4, PIN4, PIN4, PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4, PIN4, PIN4, PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
_pin_request(session),
|
||||
messages.ButtonRequest,
|
||||
_pin_request(session),
|
||||
_pin_request(session),
|
||||
(
|
||||
session.client.layout_type is LayoutType.Caesar,
|
||||
client.layout_type is LayoutType.Caesar,
|
||||
messages.ButtonRequest,
|
||||
),
|
||||
_pin_request(session),
|
||||
@ -165,16 +165,16 @@ def test_change_pin_t2(session: Session):
|
||||
@pytest.mark.setup_client(pin=None, passphrase=False)
|
||||
def test_ping(session: Session):
|
||||
session = _assert_protection(session, pin=False, passphrase=False)
|
||||
with session:
|
||||
session.set_expected_responses([messages.ButtonRequest, messages.Success])
|
||||
with session.client as client:
|
||||
client.set_expected_responses([messages.ButtonRequest, messages.Success])
|
||||
session.call(messages.Ping(message="msg", button_protection=True))
|
||||
|
||||
|
||||
def test_get_entropy(session: Session):
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
_pin_request(session),
|
||||
messages.ButtonRequest(code=B.ProtectCall),
|
||||
@ -187,43 +187,44 @@ def test_get_entropy(session: Session):
|
||||
def test_get_public_key(session: Session):
|
||||
session = _assert_protection(session)
|
||||
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
expected_responses = [_pin_request(session)]
|
||||
|
||||
if session.protocol_version == ProtocolVersion.V1:
|
||||
expected_responses.append(messages.PassphraseRequest)
|
||||
expected_responses.append(messages.PublicKey)
|
||||
|
||||
session.set_expected_responses(expected_responses)
|
||||
client.set_expected_responses(expected_responses)
|
||||
btc.get_public_node(session, [])
|
||||
|
||||
|
||||
def test_get_address(session: Session):
|
||||
session = _assert_protection(session)
|
||||
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
expected_responses = [_pin_request(session)]
|
||||
if session.protocol_version == ProtocolVersion.V1:
|
||||
expected_responses.append(messages.PassphraseRequest)
|
||||
expected_responses.append(messages.Address)
|
||||
|
||||
session.set_expected_responses(expected_responses)
|
||||
client.set_expected_responses(expected_responses)
|
||||
|
||||
get_test_address(session)
|
||||
|
||||
|
||||
def test_wipe_device(session: Session):
|
||||
client = session.client
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.set_expected_responses([messages.ButtonRequest, messages.Success])
|
||||
with client:
|
||||
client.set_expected_responses([messages.ButtonRequest, messages.Success])
|
||||
device.wipe(session)
|
||||
client = session.client.get_new_client()
|
||||
client = client.get_new_client()
|
||||
session = client.get_seedless_session()
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses([messages.Features])
|
||||
with client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses([messages.Features])
|
||||
session.call(messages.GetFeatures())
|
||||
|
||||
|
||||
@ -232,8 +233,8 @@ def test_wipe_device(session: Session):
|
||||
def test_reset_device(session: Session):
|
||||
assert session.features.pin_protection is False
|
||||
assert session.features.passphrase_protection is False
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest]
|
||||
+ [messages.EntropyRequest]
|
||||
+ [messages.ButtonRequest] * 24
|
||||
@ -269,8 +270,8 @@ def test_recovery_device(session: Session):
|
||||
assert session.features.pin_protection is False
|
||||
assert session.features.passphrase_protection is False
|
||||
session.client.use_mnemonic(MNEMONIC12)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[messages.ButtonRequest]
|
||||
+ [messages.WordRequest] * 24
|
||||
+ [messages.Success] # , messages.Features]
|
||||
@ -282,7 +283,7 @@ def test_recovery_device(session: Session):
|
||||
False,
|
||||
False,
|
||||
"label",
|
||||
input_callback=session.client.mnemonic_callback,
|
||||
input_callback=client.mnemonic_callback,
|
||||
)
|
||||
|
||||
with pytest.raises(TrezorFailure):
|
||||
@ -301,8 +302,8 @@ def test_recovery_device(session: Session):
|
||||
def test_sign_message(session: Session):
|
||||
session = _assert_protection(session)
|
||||
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
|
||||
expected_responses = [_pin_request(session)]
|
||||
|
||||
@ -317,7 +318,7 @@ def test_sign_message(session: Session):
|
||||
]
|
||||
)
|
||||
|
||||
session.set_expected_responses(expected_responses)
|
||||
client.set_expected_responses(expected_responses)
|
||||
|
||||
btc.sign_message(
|
||||
session, "Bitcoin", parse_path("m/44h/0h/0h/0/0"), "testing message"
|
||||
@ -327,8 +328,8 @@ def test_sign_message(session: Session):
|
||||
@pytest.mark.models("legacy")
|
||||
def test_verify_message_t1(session: Session):
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.ButtonRequest,
|
||||
messages.ButtonRequest,
|
||||
@ -350,9 +351,9 @@ def test_verify_message_t1(session: Session):
|
||||
@pytest.mark.models("core")
|
||||
def test_verify_message_t2(session: Session):
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses(
|
||||
[
|
||||
_pin_request(session),
|
||||
messages.ButtonRequest,
|
||||
@ -389,8 +390,8 @@ def test_signtx(session: Session):
|
||||
)
|
||||
|
||||
session = _assert_protection(session)
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
expected_responses = [_pin_request(session)]
|
||||
if session.protocol_version == ProtocolVersion.V1:
|
||||
expected_responses.append(messages.PassphraseRequest)
|
||||
@ -412,7 +413,7 @@ def test_signtx(session: Session):
|
||||
request_finished(),
|
||||
]
|
||||
)
|
||||
session.set_expected_responses(expected_responses)
|
||||
client.set_expected_responses(expected_responses)
|
||||
|
||||
btc.sign_tx(session, "Bitcoin", [inp1], [out1], prev_txes=TxCache("Bitcoin"))
|
||||
|
||||
@ -426,36 +427,38 @@ def test_signtx(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(pin=PIN4, passphrase=False)
|
||||
def test_unlocked(session: Session):
|
||||
client = session.client
|
||||
assert session.features.unlocked is False
|
||||
|
||||
session = _assert_protection(session, passphrase=False)
|
||||
|
||||
with session:
|
||||
session.client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses([_pin_request(session), messages.Address])
|
||||
with client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
client.set_expected_responses([_pin_request(session), messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
session.refresh_features()
|
||||
assert session.features.unlocked is True
|
||||
with session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
|
||||
@pytest.mark.setup_client(pin=None, passphrase=True)
|
||||
def test_passphrase_cached(session: Session):
|
||||
client = session.client
|
||||
session = _assert_protection(session, pin=False)
|
||||
with session:
|
||||
with client:
|
||||
if session.protocol_version == 1:
|
||||
session.set_expected_responses(
|
||||
client.set_expected_responses(
|
||||
[messages.PassphraseRequest, messages.Address]
|
||||
)
|
||||
elif session.protocol_version == 2:
|
||||
session.set_expected_responses([messages.Address])
|
||||
client.set_expected_responses([messages.Address])
|
||||
else:
|
||||
raise Exception("Unknown session type")
|
||||
get_test_address(session)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
@ -34,14 +34,15 @@ pytestmark = pytest.mark.models("core")
|
||||
|
||||
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
|
||||
def test_repeated_backup(session: Session):
|
||||
client = session.client
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
assert session.features.recovery_status == messages.RecoveryStatus.Nothing
|
||||
|
||||
# initial device backup
|
||||
mnemonics = []
|
||||
with session:
|
||||
IF = InputFlowSlip39BasicBackup(session.client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicBackup(client, False)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
mnemonics = IF.mnemonics
|
||||
|
||||
@ -56,11 +57,11 @@ def test_repeated_backup(session: Session):
|
||||
device.backup(session)
|
||||
|
||||
# unlock repeated backup by entering 3 of the 5 shares we have got
|
||||
with session:
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicRecoveryDryRun(
|
||||
session.client, mnemonics[:3], unlock_repeated_backup=True
|
||||
client, mnemonics[:3], unlock_repeated_backup=True
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, type=messages.RecoveryType.UnlockRepeatedBackup)
|
||||
assert (
|
||||
session.features.backup_availability
|
||||
@ -69,9 +70,9 @@ def test_repeated_backup(session: Session):
|
||||
assert session.features.recovery_status == messages.RecoveryStatus.Backup
|
||||
|
||||
# we can now perform another backup
|
||||
with session:
|
||||
IF = InputFlowSlip39BasicBackup(session.client, False, repeated=True)
|
||||
session.set_input_flow(IF.get())
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicBackup(client, False, repeated=True)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
# the backup feature is locked again...
|
||||
@ -85,6 +86,7 @@ def test_repeated_backup(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC_SLIP39_SINGLE_EXT_20)
|
||||
def test_repeated_backup_upgrade_single(session: Session):
|
||||
client = session.client
|
||||
assert (
|
||||
session.features.backup_availability == messages.BackupAvailability.NotAvailable
|
||||
)
|
||||
@ -92,11 +94,11 @@ def test_repeated_backup_upgrade_single(session: Session):
|
||||
assert session.features.backup_type == messages.BackupType.Slip39_Single_Extendable
|
||||
|
||||
# unlock repeated backup by entering the single share
|
||||
with session:
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicRecoveryDryRun(
|
||||
session.client, MNEMONIC_SLIP39_SINGLE_EXT_20, unlock_repeated_backup=True
|
||||
client, MNEMONIC_SLIP39_SINGLE_EXT_20, unlock_repeated_backup=True
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, type=messages.RecoveryType.UnlockRepeatedBackup)
|
||||
assert (
|
||||
session.features.backup_availability
|
||||
@ -105,9 +107,9 @@ def test_repeated_backup_upgrade_single(session: Session):
|
||||
assert session.features.recovery_status == messages.RecoveryStatus.Backup
|
||||
|
||||
# we can now perform another backup
|
||||
with session:
|
||||
IF = InputFlowSlip39BasicBackup(session.client, False, repeated=True)
|
||||
session.set_input_flow(IF.get())
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicBackup(client, False, repeated=True)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
|
||||
# backup type was upgraded:
|
||||
@ -123,14 +125,15 @@ def test_repeated_backup_upgrade_single(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
|
||||
def test_repeated_backup_cancel(session: Session):
|
||||
client = session.client
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
assert session.features.recovery_status == messages.RecoveryStatus.Nothing
|
||||
|
||||
# initial device backup
|
||||
mnemonics = []
|
||||
with session:
|
||||
IF = InputFlowSlip39BasicBackup(session.client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicBackup(client, False)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
mnemonics = IF.mnemonics
|
||||
|
||||
@ -145,11 +148,11 @@ def test_repeated_backup_cancel(session: Session):
|
||||
device.backup(session)
|
||||
|
||||
# unlock repeated backup by entering 3 of the 5 shares we have got
|
||||
with session:
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicRecoveryDryRun(
|
||||
session.client, mnemonics[:3], unlock_repeated_backup=True
|
||||
client, mnemonics[:3], unlock_repeated_backup=True
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, type=messages.RecoveryType.UnlockRepeatedBackup)
|
||||
assert (
|
||||
session.features.backup_availability
|
||||
@ -157,7 +160,7 @@ def test_repeated_backup_cancel(session: Session):
|
||||
)
|
||||
assert session.features.recovery_status == messages.RecoveryStatus.Backup
|
||||
|
||||
layout = session.client.debug.read_layout()
|
||||
layout = client.debug.read_layout()
|
||||
assert TR.recovery__unlock_repeated_backup in layout.text_content()
|
||||
|
||||
# send a Cancel message
|
||||
@ -178,14 +181,15 @@ def test_repeated_backup_cancel(session: Session):
|
||||
|
||||
@pytest.mark.setup_client(needs_backup=True, mnemonic=MNEMONIC_SLIP39_BASIC_20_3of6)
|
||||
def test_repeated_backup_send_disallowed_message(session: Session):
|
||||
client = session.client
|
||||
assert session.features.backup_availability == messages.BackupAvailability.Required
|
||||
assert session.features.recovery_status == messages.RecoveryStatus.Nothing
|
||||
|
||||
# initial device backup
|
||||
mnemonics = []
|
||||
with session:
|
||||
IF = InputFlowSlip39BasicBackup(session.client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicBackup(client, False)
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
mnemonics = IF.mnemonics
|
||||
|
||||
@ -200,11 +204,11 @@ def test_repeated_backup_send_disallowed_message(session: Session):
|
||||
device.backup(session)
|
||||
|
||||
# unlock repeated backup by entering 3 of the 5 shares we have got
|
||||
with session:
|
||||
with client:
|
||||
IF = InputFlowSlip39BasicRecoveryDryRun(
|
||||
session.client, mnemonics[:3], unlock_repeated_backup=True
|
||||
client, mnemonics[:3], unlock_repeated_backup=True
|
||||
)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.recover(session, type=messages.RecoveryType.UnlockRepeatedBackup)
|
||||
assert (
|
||||
session.features.backup_availability
|
||||
@ -212,7 +216,7 @@ def test_repeated_backup_send_disallowed_message(session: Session):
|
||||
)
|
||||
assert session.features.recovery_status == messages.RecoveryStatus.Backup
|
||||
|
||||
layout = session.client.debug.read_layout()
|
||||
layout = client.debug.read_layout()
|
||||
assert TR.recovery__unlock_repeated_backup in layout.text_content()
|
||||
|
||||
# send a GetAddress message
|
||||
@ -233,8 +237,7 @@ def test_repeated_backup_send_disallowed_message(session: Session):
|
||||
|
||||
# we are still on the confirmation screen!
|
||||
assert (
|
||||
TR.recovery__unlock_repeated_backup
|
||||
in session.client.debug.read_layout().text_content()
|
||||
TR.recovery__unlock_repeated_backup in client.debug.read_layout().text_content()
|
||||
)
|
||||
with pytest.raises(exceptions.Cancelled):
|
||||
session.call(messages.Cancel())
|
||||
|
@ -36,7 +36,8 @@ def test_sd_format(session: Session):
|
||||
|
||||
@pytest.mark.sd_card(formatted=False)
|
||||
def test_sd_no_format(session: Session):
|
||||
debug = session.client.debug
|
||||
client = session.client
|
||||
debug = client.debug
|
||||
|
||||
def input_flow():
|
||||
yield # enable SD protection?
|
||||
@ -45,8 +46,8 @@ def test_sd_no_format(session: Session):
|
||||
yield # format SD card
|
||||
debug.press_no()
|
||||
|
||||
with session, pytest.raises(TrezorFailure) as e:
|
||||
session.set_input_flow(input_flow)
|
||||
with client, pytest.raises(TrezorFailure) as e:
|
||||
client.set_input_flow(input_flow)
|
||||
device.sd_protect(session, Op.ENABLE)
|
||||
|
||||
assert e.value.code == messages.FailureType.ProcessError
|
||||
@ -55,7 +56,8 @@ def test_sd_no_format(session: Session):
|
||||
@pytest.mark.sd_card
|
||||
@pytest.mark.setup_client(pin=PIN)
|
||||
def test_sd_protect_unlock(session: Session):
|
||||
debug = session.client.debug
|
||||
client = session.client
|
||||
debug = client.debug
|
||||
layout = debug.read_layout
|
||||
|
||||
def input_flow_enable_sd_protect():
|
||||
@ -76,9 +78,9 @@ def test_sd_protect_unlock(session: Session):
|
||||
assert TR.sd_card__enabled in layout().text_content()
|
||||
debug.press_yes()
|
||||
|
||||
with session:
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(input_flow_enable_sd_protect)
|
||||
with client:
|
||||
client.watch_layout()
|
||||
client.set_input_flow(input_flow_enable_sd_protect)
|
||||
device.sd_protect(session, Op.ENABLE)
|
||||
|
||||
def input_flow_change_pin():
|
||||
@ -102,9 +104,9 @@ def test_sd_protect_unlock(session: Session):
|
||||
assert TR.pin__changed in layout().text_content()
|
||||
debug.press_yes()
|
||||
|
||||
with session:
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(input_flow_change_pin)
|
||||
with client:
|
||||
client.watch_layout()
|
||||
client.set_input_flow(input_flow_change_pin)
|
||||
device.change_pin(session)
|
||||
|
||||
debug.erase_sd_card(format=False)
|
||||
@ -125,9 +127,9 @@ def test_sd_protect_unlock(session: Session):
|
||||
)
|
||||
debug.press_no() # close
|
||||
|
||||
with session, pytest.raises(TrezorFailure) as e:
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(input_flow_change_pin_format)
|
||||
with client, pytest.raises(TrezorFailure) as e:
|
||||
client.watch_layout()
|
||||
client.set_input_flow(input_flow_change_pin_format)
|
||||
device.change_pin(session)
|
||||
|
||||
assert e.value.code == messages.FailureType.ProcessError
|
||||
|
@ -57,15 +57,15 @@ def test_clear_session(client: Client):
|
||||
cached_responses = [messages.PublicKey]
|
||||
session = client.get_session()
|
||||
session.lock()
|
||||
with session:
|
||||
with client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(init_responses + cached_responses)
|
||||
client.set_expected_responses(init_responses + cached_responses)
|
||||
assert _get_public_node(session, ADDRESS_N, passphrase="").xpub == XPUB
|
||||
|
||||
session.resume()
|
||||
with session:
|
||||
with client:
|
||||
# pin and passphrase are cached
|
||||
session.set_expected_responses(cached_responses)
|
||||
client.set_expected_responses(cached_responses)
|
||||
assert _get_public_node(session, ADDRESS_N).xpub == XPUB
|
||||
|
||||
session.lock()
|
||||
@ -73,15 +73,15 @@ def test_clear_session(client: Client):
|
||||
session = client.get_session()
|
||||
|
||||
# session cache is cleared
|
||||
with session:
|
||||
with client:
|
||||
client.use_pin_sequence([PIN4])
|
||||
session.set_expected_responses(init_responses + cached_responses)
|
||||
client.set_expected_responses(init_responses + cached_responses)
|
||||
assert _get_public_node(session, ADDRESS_N, passphrase="").xpub == XPUB
|
||||
|
||||
session.resume()
|
||||
with session:
|
||||
with client:
|
||||
# pin and passphrase are cached
|
||||
session.set_expected_responses(cached_responses)
|
||||
client.set_expected_responses(cached_responses)
|
||||
assert _get_public_node(session, ADDRESS_N).xpub == XPUB
|
||||
|
||||
|
||||
@ -92,8 +92,8 @@ def test_end_session(client: Client):
|
||||
assert session.id is not None
|
||||
|
||||
# get_address will succeed
|
||||
with session as session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
session.end()
|
||||
@ -105,13 +105,13 @@ def test_end_session(client: Client):
|
||||
|
||||
session = client.get_session()
|
||||
assert session.id is not None
|
||||
with session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
get_test_address(session)
|
||||
|
||||
with session as session:
|
||||
with client:
|
||||
# end_session should succeed on empty session too
|
||||
session.set_expected_responses([messages.Success] * 2)
|
||||
client.set_expected_responses([messages.Success] * 2)
|
||||
session.end()
|
||||
session.end()
|
||||
|
||||
@ -154,8 +154,8 @@ def test_end_session_only_current(client: Client):
|
||||
@pytest.mark.setup_client(passphrase=True)
|
||||
def test_session_recycling(client: Client):
|
||||
session = client.get_session(passphrase="TREZOR")
|
||||
with session:
|
||||
session.set_expected_responses([messages.Address])
|
||||
with client:
|
||||
client.set_expected_responses([messages.Address])
|
||||
address = get_test_address(session)
|
||||
|
||||
# create and close 100 sessions - more than the session limit
|
||||
@ -164,9 +164,9 @@ def test_session_recycling(client: Client):
|
||||
session_x.end()
|
||||
|
||||
# it should still be possible to resume the original session
|
||||
with session:
|
||||
with client:
|
||||
# passphrase should still be cached
|
||||
session.set_expected_responses([messages.Address] * 3)
|
||||
client.set_expected_responses([messages.Address] * 3)
|
||||
session.resume()
|
||||
get_test_address(session)
|
||||
get_test_address(session)
|
||||
|
@ -66,8 +66,8 @@ def _get_xpub(
|
||||
else:
|
||||
expected_responses = [messages.PublicKey]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
result = session.call_raw(XPUB_REQUEST)
|
||||
if passphrase is not None:
|
||||
result = session.call_raw(messages.PassphraseAck(passphrase=passphrase))
|
||||
@ -441,7 +441,7 @@ def test_hide_passphrase_from_host(client: Client):
|
||||
|
||||
passphrase = "abc"
|
||||
session = _get_session(client)
|
||||
with session:
|
||||
with client:
|
||||
|
||||
def input_flow():
|
||||
yield
|
||||
@ -457,8 +457,8 @@ def test_hide_passphrase_from_host(client: Client):
|
||||
raise KeyError
|
||||
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(input_flow)
|
||||
session.set_expected_responses(
|
||||
client.set_input_flow(input_flow)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.PassphraseRequest,
|
||||
messages.ButtonRequest,
|
||||
@ -477,7 +477,7 @@ def test_hide_passphrase_from_host(client: Client):
|
||||
# Starting new session, otherwise the passphrase would be cached
|
||||
session = _get_session(client)
|
||||
|
||||
with session:
|
||||
with client:
|
||||
|
||||
def input_flow():
|
||||
yield
|
||||
@ -493,8 +493,8 @@ def test_hide_passphrase_from_host(client: Client):
|
||||
client.debug.press_yes()
|
||||
|
||||
session.client.watch_layout()
|
||||
session.set_input_flow(input_flow)
|
||||
session.set_expected_responses(
|
||||
client.set_input_flow(input_flow)
|
||||
client.set_expected_responses(
|
||||
[
|
||||
messages.PassphraseRequest,
|
||||
messages.ButtonRequest,
|
||||
|
@ -44,9 +44,9 @@ def test_tezos_get_address(session: Session, path: str, expected_address: str):
|
||||
def test_tezos_get_address_chunkify_details(
|
||||
session: Session, path: str, expected_address: str
|
||||
):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowShowAddressQRCode(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
address = get_address(
|
||||
session, parse_path(path), show_display=True, chunkify=True
|
||||
)
|
||||
|
@ -33,7 +33,7 @@ pytestmark = [
|
||||
|
||||
|
||||
def test_tezos_sign_tx_proposal(session: Session):
|
||||
with session:
|
||||
with session.client:
|
||||
resp = tezos.sign_tx(
|
||||
session,
|
||||
TEZOS_PATH_10,
|
||||
@ -64,7 +64,7 @@ def test_tezos_sign_tx_proposal(session: Session):
|
||||
|
||||
|
||||
def test_tezos_sign_tx_multiple_proposals(session: Session):
|
||||
with session:
|
||||
with session.client:
|
||||
resp = tezos.sign_tx(
|
||||
session,
|
||||
TEZOS_PATH_10,
|
||||
|
@ -31,9 +31,9 @@ RK_CAPACITY = 100
|
||||
@pytest.mark.altcoin
|
||||
@pytest.mark.setup_client(mnemonic=MNEMONIC12)
|
||||
def test_add_remove(session: Session):
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowFidoConfirm(session.client)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
|
||||
# Remove index 0 should fail.
|
||||
with pytest.raises(TrezorFailure):
|
||||
|
@ -95,8 +95,8 @@ def test_spend_v4_input(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -143,8 +143,8 @@ def test_send_to_multisig(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOSCRIPTHASH,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -190,8 +190,8 @@ def test_spend_v5_input(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -243,8 +243,8 @@ def test_one_two(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -301,8 +301,8 @@ def test_unified_address(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_output(0),
|
||||
@ -365,8 +365,8 @@ def test_external_presigned(session: Session):
|
||||
script_type=messages.OutputScriptType.PAYTOADDRESS,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(
|
||||
with session.client as client:
|
||||
client.set_expected_responses(
|
||||
[
|
||||
request_input(0),
|
||||
request_input(1),
|
||||
@ -489,8 +489,8 @@ def test_spend_multisig(session: Session):
|
||||
request_finished(),
|
||||
]
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
signatures1, _ = btc.sign_tx(
|
||||
session,
|
||||
"Zcash Testnet",
|
||||
@ -529,8 +529,8 @@ def test_spend_multisig(session: Session):
|
||||
multisig=multisig,
|
||||
)
|
||||
|
||||
with session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
with session.client as client:
|
||||
client.set_expected_responses(expected_responses)
|
||||
signatures2, serialized_tx = btc.sign_tx(
|
||||
session,
|
||||
"Zcash Testnet",
|
||||
|
@ -23,7 +23,7 @@ def setup_device_legacy(client: Client, pin: str, wipe_code: str) -> None:
|
||||
label="WIPECODE",
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN, WIPE_CODE, WIPE_CODE])
|
||||
device.change_wipe_code(client.get_seedless_session())
|
||||
|
||||
@ -41,7 +41,7 @@ def setup_device_core(client: Client, pin: str, wipe_code: str) -> None:
|
||||
label="WIPECODE",
|
||||
)
|
||||
|
||||
with session:
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([pin, wipe_code, wipe_code])
|
||||
device.change_wipe_code(client.get_seedless_session())
|
||||
|
||||
|
@ -69,7 +69,7 @@ def set_language(session: Session, lang: str, *, force: bool = True):
|
||||
language_data = b""
|
||||
else:
|
||||
language_data = build_and_sign_blob(lang, session)
|
||||
with session:
|
||||
with session.client:
|
||||
if not session.features.language.startswith(lang) or force:
|
||||
device.change_language(session, language_data) # type: ignore
|
||||
_CURRENT_TRANSLATION.TR = TRANSLATIONS[lang]
|
||||
|
@ -96,7 +96,7 @@ def test_upgrade_load_pin(gen: str, tag: str) -> None:
|
||||
assert client.features.initialized
|
||||
assert client.features.label == LABEL
|
||||
session = client.get_session()
|
||||
with session:
|
||||
with session.client as client:
|
||||
client.use_pin_sequence([PIN])
|
||||
assert btc.get_address(session, "Bitcoin", PATH) == ADDRESS
|
||||
|
||||
@ -396,9 +396,9 @@ def test_upgrade_shamir_backup(gen: str, tag: Optional[str]):
|
||||
# Create a backup of the encrypted master secret.
|
||||
assert emu.client.features.backup_availability == BackupAvailability.Required
|
||||
session = emu.client.get_session()
|
||||
with session:
|
||||
with session.client as client:
|
||||
IF = InputFlowSlip39BasicBackup(emu.client, False)
|
||||
session.set_input_flow(IF.get())
|
||||
client.set_input_flow(IF.get())
|
||||
device.backup(session)
|
||||
assert (
|
||||
emu.client.features.backup_availability == BackupAvailability.NotAvailable
|
||||
|
@ -91,9 +91,9 @@ def test_passphrase_works(emulator: Emulator):
|
||||
messages.ButtonRequest,
|
||||
messages.Address,
|
||||
]
|
||||
emu_session = emulator.client.get_session(passphrase="TREZOR")
|
||||
with emu_session as session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
session = emulator.client.get_session(passphrase="TREZOR")
|
||||
with emulator.client:
|
||||
emulator.client.set_expected_responses(expected_responses)
|
||||
btc.get_address(session, "Testnet", parse_path("44h/1h/0h/0/0"))
|
||||
|
||||
|
||||
@ -134,9 +134,9 @@ def test_init_device(emulator: Emulator):
|
||||
messages.Address,
|
||||
]
|
||||
|
||||
emu_session = emulator.client.get_session(passphrase="TREZOR")
|
||||
with emu_session as session:
|
||||
session.set_expected_responses(expected_responses)
|
||||
session = emulator.client.get_session(passphrase="TREZOR")
|
||||
with emulator.client:
|
||||
emulator.client.set_expected_responses(expected_responses)
|
||||
|
||||
btc.get_address(session, "Testnet", parse_path("44h/1h/0h/0/0"))
|
||||
# in TT < 2.3.0 session_id will only be available after PassphraseStateRequest
|
||||
|
Loading…
Reference in New Issue
Block a user