def test_clear_session(client: Client): is_trezor1 = client.features.model == "1" init_responses = [ messages.PinMatrixRequest if is_trezor1 else messages.ButtonRequest, messages.PassphraseRequest, ] cached_responses = [messages.PublicKey] with client: client.use_pin_sequence([PIN4]) client.set_expected_responses(init_responses + cached_responses) assert get_public_node(client, ADDRESS_N).xpub == XPUB with client: # pin and passphrase are cached client.set_expected_responses(cached_responses) assert get_public_node(client, ADDRESS_N).xpub == XPUB client.clear_session() # session cache is cleared with client: client.use_pin_sequence([PIN4]) client.set_expected_responses(init_responses + cached_responses) assert get_public_node(client, ADDRESS_N).xpub == XPUB with client: # pin and passphrase are cached client.set_expected_responses(cached_responses) assert get_public_node(client, ADDRESS_N).xpub == XPUB
def test_set_remove_wipe_code(client: Client): # Check that wipe code protection status is not revealed in locked state. assert client.features.wipe_code_protection is None # Test set wipe code. _set_wipe_code(client, PIN4, WIPE_CODE_MAX) # Check that there's wipe code protection now. client.init_device() assert client.features.wipe_code_protection is True # Check that the wipe code is correct. _check_wipe_code(client, PIN4, WIPE_CODE_MAX) # Test change wipe code. _set_wipe_code(client, PIN4, WIPE_CODE6) # Check that there's still wipe code protection now. client.init_device() assert client.features.wipe_code_protection is True # Check that the wipe code is correct. _check_wipe_code(client, PIN4, WIPE_CODE6) # Test remove wipe code. with client: client.use_pin_sequence([PIN4]) device.change_wipe_code(client, remove=True) # Check that there's no wipe code protection now. client.init_device() assert client.features.wipe_code_protection is False
def test_autolock_default_value(client: Client): assert client.features.auto_lock_delay_ms is None with client: client.use_pin_sequence([PIN4]) device.apply_settings(client, label="pls unlock") client.refresh_features() assert client.features.auto_lock_delay_ms == 60 * 10 * 1000
def _check_pin(client: Client, pin): client.lock() with client: client.use_pin_sequence([pin]) client.set_expected_responses( [messages.PinMatrixRequest, messages.Address]) get_test_address(client)
def test_exponential_backoff_t1(client: Client): for attempt in range(3): start = time.time() with client, pytest.raises(PinException): client.use_pin_sequence([BAD_PIN]) get_test_address(client) _check_backoff_time(attempt, start)
def _change_pin(client: Client, old_pin, new_pin): assert client.features.pin_protection is True with client: client.use_pin_sequence([old_pin, new_pin, new_pin]) try: return device.change_pin(client) except exceptions.TrezorFailure as f: return f.failure
def setup_device_legacy(client: Client, pin: str, wipe_code: str) -> None: device.wipe(client) debuglink.load_device( client, MNEMONIC12, pin, passphrase_protection=False, label="WIPECODE" ) with client: client.use_pin_sequence([PIN, WIPE_CODE, WIPE_CODE]) device.change_wipe_code(client)
def _check_pin(client: Client, pin): client.lock() assert client.features.pin_protection is True assert client.features.unlocked is False with client: client.use_pin_sequence([pin]) client.set_expected_responses( [messages.ButtonRequest, messages.Address]) btc.get_address(client, "Testnet", PASSPHRASE_TEST_PATH)
def _assert_protection(client: Client, pin: bool = True, passphrase: bool = True) -> None: """Make sure PIN and passphrase protection have expected values""" with client: client.use_pin_sequence([PIN4]) client.ensure_unlocked() assert client.features.pin_protection is pin assert client.features.passphrase_protection is passphrase client.clear_session()
def test_incorrect_pin_t2(client: Client): with client: # After first incorrect attempt, TT will not raise an error, but instead ask for another attempt client.use_pin_sequence([BAD_PIN, PIN4]) client.set_expected_responses([ messages.ButtonRequest(code=messages.ButtonRequestType.PinEntry), messages.ButtonRequest(code=messages.ButtonRequestType.PinEntry), messages.Address, ]) get_test_address(client)
def test_get_entropy_t2(client: Client): _assert_protection(client) with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ _pin_request(client), messages.ButtonRequest(code=B.ProtectCall), messages.Entropy, ]) misc.get_entropy(client, 10)
def test_get_address(client: Client): _assert_protection(client) with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ _pin_request(client), messages.PassphraseRequest, messages.Address, ]) get_test_address(client)
def test_get_public_key(client: Client): _assert_protection(client) with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ _pin_request(client), messages.PassphraseRequest, messages.PublicKey, ]) btc.get_public_node(client, [])
def set_autolock_delay(client: Client, delay): with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ pin_request(client), messages.ButtonRequest, messages.Success, messages.Features, ]) device.apply_settings(client, auto_lock_delay_ms=delay)
def test_apply_settings(client: Client): _assert_protection(client) with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ _pin_request(client), messages.ButtonRequest, messages.Success, messages.Features, ]) # TrezorClient reinitializes device device.apply_settings(client, label="nazdar")
def test_apply_auto_lock_delay_out_of_range(client: Client, seconds): with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ pin_request(client), messages.Failure(code=messages.FailureType.ProcessError), ]) delay = seconds * 1000 with pytest.raises(TrezorFailure): device.apply_settings(client, auto_lock_delay_ms=delay)
def _check_wipe_code(client: Client, pin, wipe_code): client.init_device() assert client.features.wipe_code_protection is True # Try to change the PIN to the current wipe code value. The operation should fail. with client, pytest.raises(TrezorFailure): client.use_pin_sequence([pin, wipe_code, wipe_code]) client.set_expected_responses( [messages.ButtonRequest()] * 5 + [messages.Failure(code=messages.FailureType.PinInvalid)]) device.change_pin(client)
def test_set_wipe_code_to_pin(client: Client): _ensure_unlocked(client, PIN4) with client: client.set_expected_responses([messages.ButtonRequest()] * 6 + [messages.Success, messages.Features]) client.use_pin_sequence([PIN4, PIN4, WIPE_CODE4, WIPE_CODE4]) device.change_wipe_code(client) client.init_device() assert client.features.wipe_code_protection is True _check_wipe_code(client, PIN4, WIPE_CODE4)
def test_experimental_features(client: Client): def experimental_call(): btc.authorize_coinjoin( client, coordinator="www.example.com", max_rounds=10, max_coordinator_fee_rate=50_000_000, # 0.5 % max_fee_per_kvbyte=3500, n=parse_path("m/84h/1h/0h"), coin_name="Testnet", script_type=messages.InputScriptType.SPENDWITNESS, ) assert client.features.experimental_features is None # unlock with client: _set_expected_responses(client) device.apply_settings(client, label="new label") assert client.features.experimental_features with client: client.set_expected_responses( [messages.ButtonRequest, messages.ButtonRequest, messages.Success] ) experimental_call() # relock and try again client.lock() with client: client.use_pin_sequence([PIN4]) client.set_expected_responses( [ messages.ButtonRequest, messages.ButtonRequest, messages.ButtonRequest, messages.Success, ] ) experimental_call() # unset experimental features with client: client.set_expected_responses([messages.Success, messages.Features]) device.apply_settings(client, experimental_features=False) assert not client.features.experimental_features with pytest.raises(exceptions.TrezorFailure, match="DataError"), client: client.set_expected_responses([messages.Failure]) experimental_call()
def test_sign_message(client: Client): _assert_protection(client) with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ _pin_request(client), messages.PassphraseRequest, messages.ButtonRequest, messages.ButtonRequest, messages.MessageSignature, ]) btc.sign_message(client, "Bitcoin", parse_path("m/44h/0h/0h/0/0"), "testing message")
def test_change_pin_t1(client: Client): _assert_protection(client) with client: client.use_pin_sequence([PIN4, PIN4, PIN4]) client.set_expected_responses([ messages.ButtonRequest, _pin_request(client), _pin_request(client), _pin_request(client), messages.Success, messages.Features, ]) device.change_pin(client)
def test_unlocked(client: Client): assert client.features.unlocked is False _assert_protection(client, passphrase=False) with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([_pin_request(client), messages.Address]) get_test_address(client) client.init_device() assert client.features.unlocked is True with client: client.set_expected_responses([messages.Address]) get_test_address(client)
def test_apply_auto_lock_delay(client: Client): set_autolock_delay(client, 10 * 1000) time.sleep(0.1) # sleep less than auto-lock delay with client: # No PIN protection is required. client.set_expected_responses([messages.Address]) get_test_address(client) time.sleep(10.5) # sleep more than auto-lock delay with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([pin_request(client), messages.Address]) get_test_address(client)
def test_set_pin_to_wipe_code(client: Client): # Set wipe code. with client: client.set_expected_responses([messages.ButtonRequest()] * 4 + [messages.Success, messages.Features]) client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4]) device.change_wipe_code(client) # Try to set the PIN to the current wipe code value. with client, pytest.raises(TrezorFailure): client.set_expected_responses( [messages.ButtonRequest()] * 4 + [messages.Failure(code=messages.FailureType.PinInvalid)]) client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4]) device.change_pin(client)
def test_correct_pin(client: Client): with client: client.use_pin_sequence([PIN4]) # Expected responses differ between T1 and TT is_t1 = client.features.model == "1" client.set_expected_responses([ (is_t1, messages.PinMatrixRequest), ( not is_t1, messages.ButtonRequest( code=messages.ButtonRequestType.PinEntry), ), messages.Address, ]) # client.set_expected_responses([messages.ButtonRequest, messages.Address]) get_test_address(client)
def test_set_pin(client: Client): assert client.features.pin_protection is False # Check that there's no PIN protection _check_no_pin(client) # Let's set new PIN with client: client.use_pin_sequence([PIN_MAX, PIN_MAX]) client.set_expected_responses([messages.ButtonRequest] * 4 + [messages.Success, messages.Features]) device.change_pin(client) client.init_device() assert client.features.pin_protection is True _check_pin(client, PIN_MAX)
def test_remove_pin(client: Client): assert client.features.pin_protection is True # Check current PIN value _check_pin(client, PIN4) # Let's remove PIN with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([messages.ButtonRequest] * 3 + [messages.Success, messages.Features]) device.change_pin(client, remove=True) # Check that there's no PIN protection now client.init_device() assert client.features.pin_protection is False _check_no_pin(client)
def test_change_pin(client: Client): assert client.features.pin_protection is True # Check current PIN value _check_pin(client, PIN4) # Let's change PIN with client: client.use_pin_sequence([PIN4, PIN_MAX, PIN_MAX]) client.set_expected_responses([messages.ButtonRequest] * 5 + [messages.Success, messages.Features]) device.change_pin(client) # Check that there's still PIN protection now client.init_device() assert client.features.pin_protection is True # Check that the PIN is correct _check_pin(client, PIN_MAX)
def test_set_wipe_code_to_pin(client: Client): # Check that wipe code protection status is not revealed in locked state. assert client.features.wipe_code_protection is None # Let's try setting the wipe code to the curent PIN value. with client: client.use_pin_sequence([PIN4, PIN4]) client.set_expected_responses([ messages.ButtonRequest(), messages.PinMatrixRequest(type=PinType.Current), messages.PinMatrixRequest(type=PinType.WipeCodeFirst), messages.Failure(code=messages.FailureType.ProcessError), ]) with pytest.raises(exceptions.TrezorFailure): device.change_wipe_code(client) # Check that there is no wipe code protection. client.init_device() assert client.features.wipe_code_protection is False
def test_autolock_not_retained(client: Client): with client: client.use_pin_sequence([PIN4]) device.apply_settings(client, auto_lock_delay_ms=10_000) assert client.features.auto_lock_delay_ms == 10_000 device.wipe(client) assert client.features.auto_lock_delay_ms > 10_000 with client: client.use_pin_sequence([PIN4, PIN4]) device.reset(client, skip_backup=True, pin_protection=True) time.sleep(10.5) with client: # after sleeping for the pre-wipe autolock amount, Trezor must still be unlocked client.set_expected_responses([messages.Address]) get_test_address(client)