mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-11 16:00:57 +00:00
tests: refactor T1 changepin test
This commit is contained in:
parent
fc6c99c6f9
commit
2499a6d6da
@ -16,255 +16,193 @@
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from trezorlib import messages as proto
|
from trezorlib import device, messages
|
||||||
|
from trezorlib.exceptions import TrezorFailure
|
||||||
|
|
||||||
PIN4 = "1234"
|
PIN4 = "1234"
|
||||||
PIN6 = "789456"
|
PIN6 = "789456"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip_t2
|
pytestmark = pytest.mark.skip_t2
|
||||||
class TestMsgChangepin:
|
|
||||||
def test_set_pin(self, client):
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is False
|
|
||||||
|
|
||||||
# Check that there's no PIN protection
|
|
||||||
ret = client.call_raw(proto.GetAddress())
|
|
||||||
assert isinstance(ret, proto.Address)
|
|
||||||
|
|
||||||
# Let's set new PIN
|
def _check_pin(client, pin):
|
||||||
ret = client.call_raw(proto.ChangePin())
|
client.clear_session()
|
||||||
assert isinstance(ret, proto.ButtonRequest)
|
with client:
|
||||||
|
client.use_pin_sequence([pin])
|
||||||
|
client.set_expected_responses([messages.PinMatrixRequest(), messages.Address()])
|
||||||
|
client.call(messages.GetAddress())
|
||||||
|
|
||||||
# Press button
|
|
||||||
client.debug.press_yes()
|
|
||||||
ret = client.call_raw(proto.ButtonAck())
|
|
||||||
|
|
||||||
# Send the PIN for first time
|
def _check_no_pin(client):
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
client.clear_session()
|
||||||
pin_encoded = client.debug.encode_pin(PIN6)
|
with client:
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
client.set_expected_responses([messages.Address()])
|
||||||
|
client.call(messages.GetAddress())
|
||||||
|
|
||||||
# Send the PIN for second time
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
pin_encoded = client.debug.encode_pin(PIN6)
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
|
||||||
|
|
||||||
# Now we're done
|
def test_set_pin(client):
|
||||||
assert isinstance(ret, proto.Success)
|
assert client.features.pin_protection is False
|
||||||
|
|
||||||
# Check that there's PIN protection now
|
# Check that there's no PIN protection
|
||||||
features = client.call_raw(proto.Initialize())
|
_check_no_pin(client)
|
||||||
assert features.pin_protection is True
|
|
||||||
|
|
||||||
# Check that the PIN is correct
|
# Let's set new PIN
|
||||||
self.check_pin(client, PIN6)
|
with client:
|
||||||
|
client.use_pin_sequence([PIN6, PIN6])
|
||||||
|
client.set_expected_responses(
|
||||||
|
[
|
||||||
|
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.Success(),
|
||||||
|
messages.Features(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
device.change_pin(client)
|
||||||
|
|
||||||
@pytest.mark.setup_client(pin=True)
|
# Check that there's PIN protection now
|
||||||
def test_change_pin(self, client):
|
assert client.features.pin_protection is True
|
||||||
features = client.call_raw(proto.Initialize())
|
# Check that the PIN is correct
|
||||||
assert features.pin_protection is True
|
_check_pin(client, PIN6)
|
||||||
|
|
||||||
# Check that there's PIN protection
|
|
||||||
ret = client.call_raw(proto.GetAddress())
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
client.call_raw(proto.Cancel())
|
|
||||||
|
|
||||||
# Check current PIN value
|
@pytest.mark.setup_client(pin=PIN4)
|
||||||
self.check_pin(client, PIN4)
|
def test_change_pin(client):
|
||||||
|
assert client.features.pin_protection is True
|
||||||
|
# Check that there's PIN protection
|
||||||
|
_check_pin(client, PIN4)
|
||||||
|
|
||||||
# Let's change PIN
|
# Let's change PIN
|
||||||
ret = client.call_raw(proto.ChangePin())
|
with client:
|
||||||
assert isinstance(ret, proto.ButtonRequest)
|
client.use_pin_sequence([PIN4, PIN6, PIN6])
|
||||||
|
client.set_expected_responses(
|
||||||
|
[
|
||||||
|
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.Success(),
|
||||||
|
messages.Features(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
device.change_pin(client)
|
||||||
|
|
||||||
# Press button
|
# Check that there's still PIN protection now
|
||||||
client.debug.press_yes()
|
assert client.features.pin_protection is True
|
||||||
ret = client.call_raw(proto.ButtonAck())
|
# Check that the PIN is correct
|
||||||
|
_check_pin(client, PIN6)
|
||||||
|
|
||||||
# Send current PIN
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
pin_encoded = client.debug.read_pin_encoded()
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
|
||||||
|
|
||||||
# Send new PIN for first time
|
@pytest.mark.setup_client(pin=PIN4)
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
def test_remove_pin(client):
|
||||||
pin_encoded = client.debug.encode_pin(PIN6)
|
assert client.features.pin_protection is True
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
# Check that there's PIN protection
|
||||||
|
_check_pin(client, PIN4)
|
||||||
|
|
||||||
# Send the PIN for second time
|
# Let's remove PIN
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
with client:
|
||||||
pin_encoded = client.debug.encode_pin(PIN6)
|
client.use_pin_sequence([PIN4])
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
client.set_expected_responses(
|
||||||
|
[
|
||||||
|
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.Success(),
|
||||||
|
messages.Features(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
device.change_pin(client, remove=True)
|
||||||
|
|
||||||
# Now we're done
|
# Check that there's no PIN protection now
|
||||||
assert isinstance(ret, proto.Success)
|
assert client.features.pin_protection is False
|
||||||
|
_check_no_pin(client)
|
||||||
|
|
||||||
# Check that there's still PIN protection now
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is True
|
|
||||||
|
|
||||||
# Check that the PIN is correct
|
def test_set_mismatch(client):
|
||||||
self.check_pin(client, PIN6)
|
assert client.features.pin_protection is False
|
||||||
|
# Check that there's no PIN protection
|
||||||
|
_check_no_pin(client)
|
||||||
|
|
||||||
@pytest.mark.setup_client(pin=True)
|
# Let's set new PIN
|
||||||
def test_remove_pin(self, client):
|
with pytest.raises(TrezorFailure, match="PIN mismatch"), client:
|
||||||
features = client.call_raw(proto.Initialize())
|
# use different PINs for first and second attempt. This will fail.
|
||||||
assert features.pin_protection is True
|
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 PIN protection
|
# Check that there's still no PIN protection now
|
||||||
ret = client.call_raw(proto.GetAddress())
|
client.init_device()
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
assert client.features.pin_protection is False
|
||||||
client.call_raw(proto.Cancel())
|
_check_no_pin(client)
|
||||||
|
|
||||||
# Let's remove PIN
|
|
||||||
ret = client.call_raw(proto.ChangePin(remove=True))
|
|
||||||
assert isinstance(ret, proto.ButtonRequest)
|
|
||||||
|
|
||||||
# Press button
|
@pytest.mark.setup_client(pin=PIN4)
|
||||||
client.debug.press_yes()
|
def test_change_mismatch(client):
|
||||||
ret = client.call_raw(proto.ButtonAck())
|
assert client.features.pin_protection is True
|
||||||
|
|
||||||
# Send current PIN
|
# Let's set new PIN
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
with pytest.raises(TrezorFailure, match="PIN mismatch"), client:
|
||||||
pin_encoded = client.debug.read_pin_encoded()
|
client.use_pin_sequence([PIN4, PIN6, PIN6 + "3"])
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
client.set_expected_responses(
|
||||||
|
[
|
||||||
|
messages.ButtonRequest(code=messages.ButtonRequestType.ProtectCall),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.PinMatrixRequest(),
|
||||||
|
messages.Failure(),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
device.change_pin(client)
|
||||||
|
|
||||||
# Now we're done
|
# Check that there's still old PIN protection
|
||||||
assert isinstance(ret, proto.Success)
|
client.init_device()
|
||||||
|
assert client.features.pin_protection is True
|
||||||
|
_check_pin(client, PIN4)
|
||||||
|
|
||||||
# Check that there's no PIN protection now
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is False
|
|
||||||
ret = client.call_raw(proto.GetAddress())
|
|
||||||
assert isinstance(ret, proto.Address)
|
|
||||||
|
|
||||||
def test_set_mismatch(self, client):
|
@pytest.mark.parametrize("invalid_pin", ("1204", "", "1234567891"))
|
||||||
features = client.call_raw(proto.Initialize())
|
def test_set_invalid(client, invalid_pin):
|
||||||
assert features.pin_protection is False
|
assert client.features.pin_protection is False
|
||||||
|
|
||||||
# Check that there's no PIN protection
|
# Let's set an invalid PIN
|
||||||
ret = client.call_raw(proto.GetAddress())
|
ret = client.call_raw(messages.ChangePin())
|
||||||
assert isinstance(ret, proto.Address)
|
assert isinstance(ret, messages.ButtonRequest)
|
||||||
|
|
||||||
# Let's set new PIN
|
# Press button
|
||||||
ret = client.call_raw(proto.ChangePin())
|
client.debug.press_yes()
|
||||||
assert isinstance(ret, proto.ButtonRequest)
|
ret = client.call_raw(messages.ButtonAck())
|
||||||
|
|
||||||
# Press button
|
# Send a PIN containing an invalid digit
|
||||||
client.debug.press_yes()
|
assert isinstance(ret, messages.PinMatrixRequest)
|
||||||
ret = client.call_raw(proto.ButtonAck())
|
ret = client.call_raw(messages.PinMatrixAck(pin=invalid_pin))
|
||||||
|
|
||||||
# Send the PIN for first time
|
# Ensure the invalid PIN is detected
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
assert isinstance(ret, messages.Failure)
|
||||||
pin_encoded = client.debug.encode_pin(PIN6)
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
|
||||||
|
|
||||||
# Send the PIN for second time, but with typo
|
# Check that there's still no PIN protection now
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
client.init_device()
|
||||||
pin_encoded = client.debug.encode_pin(PIN4)
|
assert client.features.pin_protection is False
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
_check_no_pin(client)
|
||||||
|
|
||||||
# Now it should fail, because pins are different
|
|
||||||
assert isinstance(ret, proto.Failure)
|
|
||||||
|
|
||||||
# Check that there's still no PIN protection now
|
@pytest.mark.parametrize("invalid_pin", ("1204", "", "1234567891"))
|
||||||
features = client.call_raw(proto.Initialize())
|
@pytest.mark.setup_client(pin=PIN4)
|
||||||
assert features.pin_protection is False
|
def test_enter_invalid(client, invalid_pin):
|
||||||
ret = client.call_raw(proto.GetAddress())
|
assert client.features.pin_protection is True
|
||||||
assert isinstance(ret, proto.Address)
|
|
||||||
|
|
||||||
@pytest.mark.setup_client(pin=True)
|
# use an invalid PIN
|
||||||
def test_change_mismatch(self, client):
|
ret = client.call_raw(messages.GetAddress())
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is True
|
|
||||||
|
|
||||||
# Let's set new PIN
|
# Send a PIN containing an invalid digit
|
||||||
ret = client.call_raw(proto.ChangePin())
|
assert isinstance(ret, messages.PinMatrixRequest)
|
||||||
assert isinstance(ret, proto.ButtonRequest)
|
ret = client.call_raw(messages.PinMatrixAck(pin=invalid_pin))
|
||||||
|
|
||||||
# Press button
|
# Ensure the invalid PIN is detected
|
||||||
client.debug.press_yes()
|
assert isinstance(ret, messages.Failure)
|
||||||
ret = client.call_raw(proto.ButtonAck())
|
|
||||||
|
|
||||||
# Send current PIN
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
pin_encoded = client.debug.read_pin_encoded()
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
|
||||||
|
|
||||||
# Send the PIN for first time
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
pin_encoded = client.debug.encode_pin(PIN6)
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
|
||||||
|
|
||||||
# Send the PIN for second time, but with typo
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
pin_encoded = client.debug.encode_pin(PIN6 + "3")
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
|
||||||
|
|
||||||
# Now it should fail, because pins are different
|
|
||||||
assert isinstance(ret, proto.Failure)
|
|
||||||
|
|
||||||
# Check that there's still old PIN protection
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is True
|
|
||||||
self.check_pin(client, PIN4)
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("invalid_pin", ("1204", "", "1234567891"))
|
|
||||||
def test_set_invalid(self, client, invalid_pin):
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is False
|
|
||||||
|
|
||||||
# Let's set an invalid PIN
|
|
||||||
ret = client.call_raw(proto.ChangePin())
|
|
||||||
assert isinstance(ret, proto.ButtonRequest)
|
|
||||||
|
|
||||||
# Press button
|
|
||||||
client.debug.press_yes()
|
|
||||||
ret = client.call_raw(proto.ButtonAck())
|
|
||||||
|
|
||||||
# Send a PIN containing an invalid digit
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=invalid_pin))
|
|
||||||
|
|
||||||
# Ensure the invalid PIN is detected
|
|
||||||
assert isinstance(ret, proto.Failure)
|
|
||||||
|
|
||||||
# Check that there's still no PIN protection now
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is False
|
|
||||||
ret = client.call_raw(proto.GetAddress())
|
|
||||||
assert isinstance(ret, proto.Address)
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("invalid_pin", ("1204", "", "1234567891"))
|
|
||||||
@pytest.mark.setup_client(pin=True)
|
|
||||||
def test_remove_invalid(self, client, invalid_pin):
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is True
|
|
||||||
|
|
||||||
# Let's change the PIN
|
|
||||||
ret = client.call_raw(proto.ChangePin(remove=True))
|
|
||||||
assert isinstance(ret, proto.ButtonRequest)
|
|
||||||
|
|
||||||
# Press button
|
|
||||||
client.debug.press_yes()
|
|
||||||
ret = client.call_raw(proto.ButtonAck())
|
|
||||||
|
|
||||||
# Instead of the old PIN, send a PIN containing an invalid digit
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=invalid_pin))
|
|
||||||
|
|
||||||
# Ensure the invalid PIN is detected
|
|
||||||
assert isinstance(ret, proto.Failure)
|
|
||||||
|
|
||||||
# Check that there's still old PIN protection
|
|
||||||
features = client.call_raw(proto.Initialize())
|
|
||||||
assert features.pin_protection is True
|
|
||||||
self.check_pin(client, PIN4)
|
|
||||||
|
|
||||||
def check_pin(self, client, pin):
|
|
||||||
client.clear_session()
|
|
||||||
ret = client.call_raw(proto.GetAddress())
|
|
||||||
assert isinstance(ret, proto.PinMatrixRequest)
|
|
||||||
pin_encoded = client.debug.encode_pin(pin)
|
|
||||||
ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
|
|
||||||
assert isinstance(ret, proto.Address)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user