def test_get_public_key(self, client): with client: client.use_pin_sequence([PIN4]) client.set_expected_responses( [proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.PublicKey()] ) btc.get_public_node(client, [])
def test_clear_session(client): if client.features.model == "1": init_responses = [ messages.PinMatrixRequest(), messages.PassphraseRequest() ] else: init_responses = [messages.PassphraseRequest()] cached_responses = [messages.PublicKey()] with client: 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.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_signtx(self, client): inp1 = proto.TxInputType( address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e prev_hash=TXHASH_d5f65e, prev_index=0, ) out1 = proto.TxOutputType( address="1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1", amount=390000 - 10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with client: client.use_pin_sequence([PIN4]) client.set_expected_responses([ proto.PinMatrixRequest(), proto.PassphraseRequest(), request_input(0), request_meta(TXHASH_d5f65e), request_input(0, TXHASH_d5f65e), request_input(1, TXHASH_d5f65e), request_output(0, TXHASH_d5f65e), request_output(0), proto.ButtonRequest(code=B.ConfirmOutput), proto.ButtonRequest(code=B.SignTx), request_input(0), request_output(0), request_output(0), request_finished(), ]) btc.sign_tx(client, "Bitcoin", [inp1], [out1], prev_txes=TxCache("Bitcoin"))
def test_apply_settings_passphrase(self): self.setup_mnemonic_pin_nopassphrase() assert self.client.features.passphrase_protection is False with self.client: self.client.set_expected_responses([proto.PinMatrixRequest(), proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(use_passphrase=True) assert self.client.features.passphrase_protection is True with self.client: self.client.set_expected_responses([proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(use_passphrase=False) assert self.client.features.passphrase_protection is False with self.client: self.client.set_expected_responses([proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(use_passphrase=True) assert self.client.features.passphrase_protection is True
def test_ping_caching(self): self.setup_mnemonic_pin_passphrase() with self.client: self.client.set_expected_responses([ proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success(), ]) res = self.client.ping( "random data", button_protection=True, pin_protection=True, passphrase_protection=True, ) assert res == "random data" with self.client: # pin and passphrase are cached self.client.set_expected_responses([ proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.Success(), ]) res = self.client.ping( "random data", button_protection=True, pin_protection=True, passphrase_protection=True, ) assert res == "random data"
def test_apply_minimal_auto_lock_delay(self): """ Verify that the delay is not below the minimal auto-lock delay (10 secs) otherwise the device may auto-lock before any user interaction. """ self.setup_mnemonic_pin_passphrase() with self.client: self.client.set_expected_responses(EXPECTED_RESPONSES_PIN) # Note: the actual delay will be 10 secs (see above). device.apply_settings(self.client, auto_lock_delay_ms=int(1e3)) time.sleep(0.1) # sleep less than auto-lock delay with self.client: # No PIN protection is required. self.client.set_expected_responses([proto.Success()]) self.client.ping(msg="", pin_protection=True) time.sleep(2) # sleep less than the minimal auto-lock delay with self.client: # No PIN protection is required. self.client.set_expected_responses([proto.Success()]) self.client.ping(msg="", pin_protection=True) time.sleep(10.1) # sleep more than the minimal auto-lock delay with self.client: self.client.set_expected_responses( [proto.PinMatrixRequest(), proto.Success()]) self.client.ping(msg="", pin_protection=True)
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_ping(self, client): with client: client.set_expected_responses([proto.Success()]) res = client.ping("random data") assert res == "random data" with client: client.set_expected_responses( [ proto.ButtonRequest(code=proto.ButtonRequestType.ProtectCall), proto.Success(), ] ) res = client.ping("random data", button_protection=True) assert res == "random data" with client: client.set_expected_responses([proto.PinMatrixRequest(), proto.Success()]) res = client.ping("random data", pin_protection=True) assert res == "random data" with client: client.set_expected_responses([proto.PassphraseRequest(), proto.Success()]) res = client.ping("random data", passphrase_protection=True) assert res == "random data"
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_pin(self, client): with client: assert client.debug.read_pin()[0] == "1234" client.setup_debuglink(button=True, pin_correct=True) client.set_expected_responses( [proto.ButtonRequest(), proto.PinMatrixRequest(), proto.Success()] ) self._some_protected_call(client, True, True, False)
def test_ping(self, client): with client: client.set_expected_responses([ proto.ButtonRequest(), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success(), ]) client.ping("msg", True, True, True)
def test_apply_settings(self, client): with client: client.set_expected_responses([ proto.PinMatrixRequest(), proto.ButtonRequest(), proto.Success(), proto.Features(), ]) # TrezorClient reinitializes device device.apply_settings(client, label="nazdar")
def test_get_public_key(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.set_expected_responses([ proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.PublicKey() ]) self.client.get_public_node([])
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 test_sign_message(self, client): with client: client.set_expected_responses([ proto.ButtonRequest(), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.MessageSignature(), ]) btc.sign_message(client, "Bitcoin", [], "testing message")
def test_signtx(self): self.setup_mnemonic_pin_passphrase() inp1 = proto.TxInputType( address_n=[0], # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e prev_hash=TXHASH_d5f65e, prev_index=0, ) out1 = proto.TxOutputType( address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1', amount=390000 - 10000, script_type=proto.OutputScriptType.PAYTOADDRESS, ) with self.client: self.client.set_expected_responses([ proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)), proto.TxRequest( request_type=proto.RequestType.TXMETA, details=proto.TxRequestDetailsType(tx_hash=TXHASH_d5f65e)), proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType( request_index=0, tx_hash=TXHASH_d5f65e)), proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType( request_index=1, tx_hash=TXHASH_d5f65e)), proto.TxRequest(request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType( request_index=0, tx_hash=TXHASH_d5f65e)), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)), proto.ButtonRequest( code=proto.ButtonRequestType.ConfirmOutput), proto.ButtonRequest(code=proto.ButtonRequestType.SignTx), proto.TxRequest( request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)), proto.TxRequest( request_type=proto.RequestType.TXOUTPUT, details=proto.TxRequestDetailsType(request_index=0)), proto.TxRequest(request_type=proto.RequestType.TXFINISHED), ]) self.client.sign_tx('Bitcoin', [ inp1, ], [ out1, ])
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_ping(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.set_expected_responses([ proto.ButtonRequest(), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success() ]) self.client.ping('msg', True, True, True)
def test_sign_message(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.set_expected_responses([ proto.ButtonRequest(), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.MessageSignature() ]) self.client.sign_message('Bitcoin', [], 'testing message')
def test_pin(self): self.setup_mnemonic_pin_passphrase() with self.client: assert self.client.debug.read_pin()[0] == self.pin4 self.client.setup_debuglink(button=True, pin_correct=True) self.client.set_expected_responses( [proto.ButtonRequest(), proto.PinMatrixRequest(), proto.Success()] ) self._some_protected_call(True, True, False)
def test_set_wipe_code_mismatch(client): # Check that there is no wipe code protection. assert client.features.wipe_code_protection is False # Let's set a new wipe code. with client: client.use_pin_sequence([WIPE_CODE4, WIPE_CODE6]) client.set_expected_responses([ messages.ButtonRequest(), messages.PinMatrixRequest(type=PinType.WipeCodeFirst), messages.PinMatrixRequest(type=PinType.WipeCodeSecond), messages.Failure(code=messages.FailureType.WipeCodeMismatch), ]) 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_apply_settings(self): with self.client: self.setup_mnemonic_pin_passphrase() self.client.set_expected_responses([ proto.PinMatrixRequest(), proto.ButtonRequest(), proto.Success(), proto.Features() ]) # TrezorClient reinitializes device self.client.apply_settings(label='nazdar')
def test_change_mismatch(client): assert client.features.pin_protection is True # Let's set new PIN with pytest.raises(TrezorFailure, match="PIN mismatch"), client: client.use_pin_sequence([PIN4, PIN6, PIN6 + "3"]) client.set_expected_responses([ messages.ButtonRequest( code=messages.ButtonRequestType.ProtectCall), messages.PinMatrixRequest(), messages.PinMatrixRequest(), messages.PinMatrixRequest(), messages.Failure(), ]) device.change_pin(client) # Check that there's still old PIN protection client.init_device() assert client.features.pin_protection is True _check_pin(client, PIN4)
def test_apply_homescreen(self): self.setup_mnemonic_pin_passphrase() img = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x04\x88\x02\x00\x00\x00\x02\x91\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x90@\x00\x11@\x00\x00\x00\x00\x00\x00\x08\x00\x10\x92\x12\x04\x00\x00\x05\x12D\x00\x00\x00\x00\x00 \x00\x00\x08\x00Q\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x10\x02 \x01\x04J\x00)$\x00\x00\x00\x00\x80\x00\x00\x00\x00\x08\x10\xa1\x00\x00\x02\x81 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\tP\x00\x00\x00\x00\x00\x00 \x00\x00\xa0\x00\xa0R \x12\x84\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x08\x00\tP\x00\x00\x00\x00 \x00\x04 \x00\x80\x02\x00@\x02T\xc2 \x00\x00\x00\x00\x00\x00\x00\x10@\x00)\t@\n\xa0\x80\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x80@\x14\xa9H\x04\x00\x00\x88@\x00\x00\x00\x00\x00\x02\x02$\x00\x15B@\x00\nP\x00\x00\x00\x00\x00\x80\x00\x00\x91\x01UP\x00\x00 \x02\x00\x00\x00\x00\x00\x00\x02\x08@ Z\xa5 \x00\x00\x80\x00\x00\x00\x00\x00\x00\x08\xa1%\x14*\xa0\x00\x00\x02\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xaa\x91 \x00\x05E\x80\x00\x00\x00\x00\x00\x02*T\x05-D\x00\x00\x05 @\x00\x00\x00\x00\x00%@\x80\x11V\xa0\x88\x00\x05@\xb0\x00\x00\x00\x00\x00\x818$\x04\xabD \x00\x06\xa1T\x00\x00\x00\x00\x02\x03\xb8\x01R\xd5\x01\x00\x00\x05AP\x00\x00\x00\x00\x08\xadT\x00\x05j\xa4@\x00\x87ah\x00\x00\x00\x00\x02\x8d\xb8\x08\x00.\x01\x00\x00\x02\xa5\xa8\x10\x00\x00\x00*\xc1\xec \n\xaa\x88 \x02@\xf6\xd0\x02\x00\x00\x00\x0bB\xb6\x14@U"\x80\x00\x01{`\x00\x00\x00\x00M\xa3\xf8 \x15*\x00\x00\x00\x10n\xc0\x04\x00\x00\x02\x06\xc2\xa8)\x00\x96\x84\x80\x00\x00\x1b\x00\x00\x80@\x10\x87\xa7\xf0\x84\x10\xaa\x10\x00\x00D\x00\x00\x02 \x00\x8a\x06\xfa\xe0P\n-\x02@\x00\x12\x00\x00\x00\x00\x10@\x83\xdf\xa0\x00\x08\xaa@\x00\x00\x01H\x00\x05H\x04\x12\x01\xf7\x81P\x02T\t\x00\x00\x00 \x00\x00\x84\x10\x00\x00z\x00@)* \x00\x00\x01\n\xa0\x02 \x05\n\x00\x00\x05\x10\x84\xa8\x84\x80\x00\x00@\x14\x00\x92\x10\x80\x00\x04\x11@\tT\x00\x00\x00\x00\n@\x00\x08\x84@$\x00H\x00\x12Q\x02\x00\x00\x00\x00\x90\x02A\x12\xa8\n\xaa\x92\x10\x04\xa8\x10@\x00\x00\x04\x04\x00\x04I\x00\x04\x14H\x80"R\x01\x00\x00\x00!@\x00\x00$\xa0EB\x80\x08\x95hH\x00\x00\x00\x84\x10 \x05Z\x00\x00(\x00\x02\x00\xa1\x01\x00\x00\x04\x00@\x82\x00\xadH*\x92P\x00\xaaP\x00\x00\x00\x00\x11\x02\x01*\xad\x01\x00\x01\x01"\x11D\x08\x00\x00\x10\x80 \x00\x81W\x80J\x94\x04\x08\xa5 !\x00\x00\x00\x02\x00B*\xae\xa1\x00\x80\x10\x01\x08\xa4\x00\x00\x00\x00\x00\x84\x00\t[@"HA\x04E\x00\x84\x00\x00\x00\x10\x00\x01J\xd5\x82\x90\x02\x00!\x02\xa2\x00\x00\x00\x00\x00\x00\x00\x05~\xa0\x00 \x10\n)\x00\x11\x00\x00\x00\x00\x00\x00!U\x80\xa8\x88\x82\x80\x01\x00\x00\x00\x00\x00\x00H@\x11\xaa\xc0\x82\x00 *\n\x00\x00\x00\x00\x00\x00\x00\x00\n\xabb@ \x04\x00! \x84\x00\x00\x00\x00\x02@\xa5\x15A$\x04\x81(\n\x00\x00\x00\x00\x00\x00 \x01\x10\x02\xe0\x91\x02\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01 \xa9\tQH@\x91 P\x00\x00\x00\x00\x00\x00\x08\x00\x00\xa0T\xa5\x00@\x80\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00 T\xa0\t\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00@\x02\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10\x00\x00\x10\x02\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00@\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x08@\x10\x00\x00\x00\x00' with self.client: self.client.set_expected_responses([proto.PinMatrixRequest(), proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(homescreen=img)
def test_set_pin_to_wipe_code(client: Client): # Set wipe code. _set_wipe_code(client, None, WIPE_CODE4) # Try to set the PIN to the current wipe code value. with client: client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4]) client.set_expected_responses([ messages.ButtonRequest(), messages.PinMatrixRequest(type=PinType.NewFirst), messages.PinMatrixRequest(type=PinType.NewSecond), messages.Failure(code=messages.FailureType.ProcessError), ]) with pytest.raises(exceptions.TrezorFailure): device.change_pin(client) # Check that there is no PIN protection. client.init_device() assert client.features.pin_protection is False resp = client.call_raw(messages.GetAddress()) assert isinstance(resp, messages.Address)
def test_invalid_language(self): self.setup_mnemonic_pin_passphrase() assert self.client.features.language == 'english' with self.client: self.client.set_expected_responses([proto.PinMatrixRequest(), proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(language='nonexistent') assert self.client.features.language == 'english'
def test_apply_settings(self): self.setup_mnemonic_pin_passphrase() assert self.client.features.label == 'test' with self.client: self.client.set_expected_responses([proto.PinMatrixRequest(), proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(label='new label') assert self.client.features.label == 'new label'
def test_apply_auto_lock_delay(self): self.setup_mnemonic_pin_passphrase() with self.client: self.client.set_expected_responses([proto.PinMatrixRequest(), proto.ButtonRequest(), proto.Success(), proto.Features()]) self.client.apply_settings(auto_lock_delay_ms=int(10e3)) # 10 secs time.sleep(0.1) # sleep less than auto-lock delay with self.client: # No PIN protection is required. self.client.set_expected_responses([proto.Success()]) self.client.ping(msg='', pin_protection=True) time.sleep(10.1) # sleep more than auto-lock delay with self.client: self.client.set_expected_responses([proto.PinMatrixRequest(), proto.Success()]) self.client.ping(msg='', pin_protection=True)
def test_set_mismatch(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 pytest.raises(TrezorFailure, match="PIN mismatch"), client: # use different PINs for first and second attempt. This will fail. client.use_pin_sequence([PIN4, PIN6]) client.set_expected_responses([ messages.ButtonRequest( code=messages.ButtonRequestType.ProtectCall), messages.PinMatrixRequest(), messages.PinMatrixRequest(), messages.Failure(), ]) device.change_pin(client) # Check that there's still no PIN protection now client.init_device() assert client.features.pin_protection is False _check_no_pin(client)
def _set_wipe_code(client: Client, pin, wipe_code): # Set/change wipe code. with client: if client.features.pin_protection: pins = [pin, wipe_code, wipe_code] pin_matrices = [ messages.PinMatrixRequest(type=PinType.Current), messages.PinMatrixRequest(type=PinType.WipeCodeFirst), messages.PinMatrixRequest(type=PinType.WipeCodeSecond), ] else: pins = [wipe_code, wipe_code] pin_matrices = [ messages.PinMatrixRequest(type=PinType.WipeCodeFirst), messages.PinMatrixRequest(type=PinType.WipeCodeSecond), ] client.use_pin_sequence(pins) client.set_expected_responses([messages.ButtonRequest()] + pin_matrices + [messages.Success, messages.Features]) device.change_wipe_code(client)