def test_apply_minimal_auto_lock_delay(client): """ Verify that the delay is not below the minimal auto-lock delay (10 secs) otherwise the device may auto-lock before any user interaction. """ set_autolock_delay(client, 1 * 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) # sleep more than specified auto-lock delay (1s) but less than minimal allowed (10s) time.sleep(3) with client: # No PIN protection is required. client.set_expected_responses([messages.Address()]) get_test_address(client) time.sleep(10.1) # sleep more than the minimal 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_passphrase_works(emulator): """Check that passphrase handling in trezorlib works correctly in all versions.""" if emulator.client.features.model == "T" and emulator.client.version < ( 2, 3, 0): expected_responses = [ messages.PassphraseRequest(), messages.Deprecated_PassphraseStateRequest(), messages.Address(), ] elif (emulator.client.features.model == "T" and emulator.client.version < (2, 3, 3)) or (emulator.client.features.model == "1" and emulator.client.version < (1, 9, 3)): expected_responses = [ messages.PassphraseRequest(), messages.Address(), ] else: expected_responses = [ messages.PassphraseRequest(), messages.ButtonRequest(), messages.ButtonRequest(), messages.Address(), ] with emulator.client: emulator.client.use_passphrase("TREZOR") emulator.client.set_expected_responses(expected_responses) btc.get_address(emulator.client, "Testnet", parse_path("44h/1h/0h/0/0"))
def test_init_device(emulator): """Check that passphrase caching and session_id retaining works correctly across supported versions. """ if emulator.client.features.model == "T" and emulator.client.version < ( 2, 3, 0): expected_responses = [ messages.PassphraseRequest(), messages.Deprecated_PassphraseStateRequest(), messages.Address(), messages.Features(), messages.Address(), ] else: expected_responses = [ messages.PassphraseRequest(), messages.Address(), messages.Features(), messages.Address(), ] with emulator.client: emulator.client.use_passphrase("TREZOR") emulator.client.set_expected_responses(expected_responses) btc.get_address(emulator.client, "Testnet", parse_path("44h/1h/0h/0/0")) # in TT < 2.3.0 session_id will only be available after PassphraseStateRequest session_id = emulator.client.session_id emulator.client.init_device() btc.get_address(emulator.client, "Testnet", parse_path("44h/1h/0h/0/0")) assert session_id == emulator.client.session_id
def test_end_session(client): # client instance starts out not initialized # XXX do we want to change this? assert client.session_id is not None # get_address will succeed with client: client.set_expected_responses([messages.Address()]) get_test_address(client) client.end_session() assert client.session_id is None with pytest.raises(TrezorFailure) as exc: get_test_address(client) assert exc.value.code == messages.FailureType.InvalidSession assert exc.value.message.endswith("Invalid session") client.init_device() assert client.session_id is not None with client: client.set_expected_responses([messages.Address()]) get_test_address(client) with client: # end_session should succeed on empty session too client.set_expected_responses([messages.Success()] * 2) client.end_session() client.end_session()
def test_session_recycling(client): session_id_orig = client.session_id with client: client.set_expected_responses([ messages.PassphraseRequest(), messages.ButtonRequest(), messages.ButtonRequest(), messages.Address(), ]) client.use_passphrase("TREZOR") address = get_test_address(client) # create and close 100 sessions - more than the session limit for _ in range(100): client.init_device(new_session=True) client.end_session() # it should still be possible to resume the original session with client: # passphrase should still be cached client.set_expected_responses( [messages.Features(), messages.Address()]) client.use_passphrase("TREZOR") client.init_device(session_id=session_id_orig) assert address == get_test_address(client)
def test_apply_minimal_auto_lock_delay(self, client): """ Verify that the delay is not below the minimal auto-lock delay (10 secs) otherwise the device may auto-lock before any user interaction. """ with client: client.set_expected_responses(EXPECTED_RESPONSES_PIN) # Note: the actual delay will be 10 secs (see above). device.apply_settings(client, auto_lock_delay_ms=int(1e3)) time.sleep(0.1) # sleep less than auto-lock delay with client: # No PIN protection is required. client.set_expected_responses([proto.Address()]) btc.get_address(client, "Testnet", [0]) time.sleep(2) # sleep less than the minimal auto-lock delay with client: # No PIN protection is required. client.set_expected_responses([proto.Address()]) btc.get_address(client, "Testnet", [0]) time.sleep(10.1) # sleep more than the minimal auto-lock delay with client: client.set_expected_responses( [proto.PinMatrixRequest(), proto.Address()]) btc.get_address(client, "Testnet", [0])
def test_passphrase_cached(self, client): with client: client.set_expected_responses([proto.PassphraseRequest(), proto.Address()]) btc.get_address(client, "Testnet", [0]) with client: client.set_expected_responses([proto.Address()]) btc.get_address(client, "Testnet", [0])
def test_safety_checks(self, client): def get_bad_address(): btc.get_address(client, "Bitcoin", parse_path("m/0")) assert client.features.safety_checks == messages.SafetyCheckLevel.Strict with pytest.raises( exceptions.TrezorFailure, match="Forbidden key path" ), client: client.set_expected_responses([messages.Failure()]) get_bad_address() with client: client.set_expected_responses(EXPECTED_RESPONSES_NOPIN) device.apply_settings( client, safety_checks=messages.SafetyCheckLevel.PromptAlways ) assert client.features.safety_checks == messages.SafetyCheckLevel.PromptAlways with client: client.set_expected_responses( [messages.ButtonRequest(), messages.Address()] ) get_bad_address() with client: client.set_expected_responses(EXPECTED_RESPONSES_NOPIN) device.apply_settings( client, safety_checks=messages.SafetyCheckLevel.Strict ) assert client.features.safety_checks == messages.SafetyCheckLevel.Strict with pytest.raises( exceptions.TrezorFailure, match="Forbidden key path" ), client: client.set_expected_responses([messages.Failure()]) get_bad_address() with client: client.set_expected_responses(EXPECTED_RESPONSES_NOPIN) device.apply_settings( client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily ) assert ( client.features.safety_checks == messages.SafetyCheckLevel.PromptTemporarily ) with client: client.set_expected_responses( [messages.ButtonRequest(), messages.Address()] ) get_bad_address()
def test_unlocked(self, client): assert client.features.unlocked is False with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([proto.PinMatrixRequest(), proto.Address()]) btc.get_address(client, "Testnet", [0]) client.init_device() assert client.features.unlocked is True with client: client.set_expected_responses([proto.Address()]) btc.get_address(client, "Testnet", [0])
def test_apply_auto_lock_delay(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.1) # 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_apply_auto_lock_delay(self, client): with client: client.set_expected_responses(EXPECTED_RESPONSES_PIN) device.apply_settings(client, auto_lock_delay_ms=int(10e3)) # 10 secs time.sleep(0.1) # sleep less than auto-lock delay with client: # No PIN protection is required. client.set_expected_responses([proto.Address()]) btc.get_address(client, "Testnet", [0]) time.sleep(10.1) # sleep more than auto-lock delay with client: client.set_expected_responses([proto.PinMatrixRequest(), proto.Address()]) btc.get_address(client, "Testnet", [0])
def _check_no_pin(client): client.clear_session() assert client.features.pin_protection is False with client: client.set_expected_responses([messages.Address()]) btc.get_address(client, "Testnet", PASSPHRASE_TEST_PATH)
def test_safety_checks(self, client): BAD_ADDRESS = parse_path("m/0") with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client: client.set_expected_responses([messages.Failure()]) btc.get_address(client, "Bitcoin", BAD_ADDRESS) with client: client.set_expected_responses(EXPECTED_RESPONSES_NOPIN) device.apply_settings( client, safety_checks=messages.SafetyCheckLevel.Prompt) with client: client.set_expected_responses( [messages.ButtonRequest(), messages.Address()]) btc.get_address(client, "Bitcoin", BAD_ADDRESS) with client: client.set_expected_responses(EXPECTED_RESPONSES_NOPIN) device.apply_settings( client, safety_checks=messages.SafetyCheckLevel.Strict) with pytest.raises(exceptions.TrezorFailure, match="Forbidden key path"), client: client.set_expected_responses([messages.Failure()]) btc.get_address(client, "Bitcoin", BAD_ADDRESS)
def test_get_address(self, client): with client: client.use_pin_sequence([PIN4]) client.set_expected_responses( [proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Address()] ) btc.get_address(client, "Bitcoin", [])
def test_pin(self, client): with client: assert client.debug.read_pin()[0] == "1234" client.set_expected_responses( [proto.PinMatrixRequest(), proto.Address()]) self._some_protected_call(client)
def _check_pin(client, pin): client.lock() with client: client.use_pin_sequence([pin]) client.set_expected_responses( [messages.PinMatrixRequest(), messages.Address()]) client.call(messages.GetAddress())
def test_unknown_path(client): with client: client.set_expected_responses([ messages.ButtonRequest( code=messages.ButtonRequestType.UnknownDerivationPath), messages.Address(), ]) # account number is too high btc.get_address(client, "Bitcoin", parse_path("m/44'/0'/21'/0/0"))
def test_get_address(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.set_expected_responses([ proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Address() ]) self.client.get_address('Bitcoin', [])
def _check_pin(client, pin): client.clear_session() assert client.features.pin_protection is True assert client.features.pin_cached 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 test_no_protection(self, client): with client: assert client.debug.read_pin()[0] is None client.set_expected_responses([proto.Address()]) self._some_protected_call(client)
def _check_no_pin(client): client.lock() with client: client.set_expected_responses([messages.Address()]) client.call(messages.GetAddress())
def test_no_protection(self, client): with client: client.set_expected_responses([proto.Address()]) self._some_protected_call(client)
def test_pin(self, client): with client: client.use_pin_sequence(["1234"]) client.set_expected_responses([proto.PinMatrixRequest(), proto.Address()]) self._some_protected_call(client)