def test_set_mismatch(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
        ret = client.call_raw(proto.ChangePin())
        assert isinstance(ret, proto.ButtonRequest)

        # Press button
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        # 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(PIN4)
        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 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_remove_pin(self, client):
        features = client.call_raw(proto.Initialize())
        assert features.pin_protection is True

        # Check that there's PIN protection
        ret = client.call_raw(proto.GetAddress())
        assert isinstance(ret, proto.PinMatrixRequest)
        client.call_raw(proto.Cancel())

        # Let's remove 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())

        # Send current PIN
        assert isinstance(ret, proto.PinMatrixRequest)
        pin_encoded = client.debug.read_pin_encoded()
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        # Now we're done
        assert isinstance(ret, proto.Success)

        # 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 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)
Esempio n. 4
0
    def test_pin_passphrase(self, client):
        mnemonic = MNEMONIC12.split(" ")
        ret = client.call_raw(
            proto.RecoveryDevice(
                word_count=12,
                passphrase_protection=True,
                pin_protection=True,
                label="label",
                language="en-US",
                enforce_wordlist=True,
            ))

        # click through confirmation
        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        assert isinstance(ret, proto.PinMatrixRequest)

        # Enter PIN for first time
        pin_encoded = client.debug.encode_pin(PIN6)
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
        assert isinstance(ret, proto.PinMatrixRequest)

        # Enter PIN for second time
        pin_encoded = client.debug.encode_pin(PIN6)
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        fakes = 0
        for _ in range(int(12 * 2)):
            assert isinstance(ret, proto.WordRequest)
            (word, pos) = client.debug.read_recovery_word()

            if pos != 0:
                ret = client.call_raw(proto.WordAck(word=mnemonic[pos - 1]))
                mnemonic[pos - 1] = None
            else:
                ret = client.call_raw(proto.WordAck(word=word))
                fakes += 1

            print(mnemonic)

        # Workflow succesfully ended
        assert isinstance(ret, proto.Success)

        # 12 expected fake words and all words of mnemonic are used
        assert fakes == 12
        assert mnemonic == [None] * 12

        # Mnemonic is the same
        client.init_device()
        assert client.debug.read_mnemonic_secret() == MNEMONIC12.encode()

        assert client.features.pin_protection is True
        assert client.features.passphrase_protection is True

        # Do passphrase-protected action, PassphraseRequest should be raised
        resp = client.call_raw(proto.GetAddress())
        assert isinstance(resp, proto.PassphraseRequest)
        client.call_raw(proto.Cancel())
    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
        ret = client.call_raw(proto.ChangePin())
        assert isinstance(ret, proto.ButtonRequest)

        # Press button
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        # 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
        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
        assert isinstance(ret, proto.Success)

        # Check that there's PIN protection now
        features = client.call_raw(proto.Initialize())
        assert features.pin_protection is True

        # Check that the PIN is correct
        self.check_pin(client, PIN6)
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_enter_invalid(client, invalid_pin):
    assert client.features.pin_protection is True

    # use an invalid PIN
    ret = client.call_raw(messages.GetAddress())

    # Send a PIN containing an invalid digit
    assert isinstance(ret, messages.PinMatrixRequest)
    ret = client.call_raw(messages.PinMatrixAck(pin=invalid_pin))

    # Ensure the invalid PIN is detected
    assert isinstance(ret, messages.Failure)
Esempio n. 8
0
    def test_pin(self, client):
        resp = client.call_raw(messages.GetAddress())
        assert isinstance(resp, messages.PinMatrixRequest)

        state = client.debug.state()
        assert state.pin == "1234"
        assert state.matrix != ""

        pin_encoded = client.debug.encode_pin("1234")
        resp = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
        assert isinstance(resp, messages.PassphraseRequest)

        resp = client.call_raw(messages.PassphraseAck(passphrase=""))
        assert isinstance(resp, messages.Address)
Esempio n. 9
0
    def test_pin(self, client):
        resp = client.call_raw(messages.GetAddress())
        assert isinstance(resp, messages.PinMatrixRequest)

        pin, matrix = client.debug.read_pin()
        assert pin == "1234"
        assert matrix != ""

        pin_encoded = client.debug.read_pin_encoded()
        resp = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))
        assert isinstance(resp, messages.PassphraseRequest)

        resp = client.call_raw(messages.PassphraseAck(passphrase=""))
        assert isinstance(resp, messages.Address)
Esempio n. 10
0
def test_nopin_nopassphrase(client: Client):
    mnemonic = MNEMONIC12.split(" ")
    ret = client.call_raw(
        messages.RecoveryDevice(
            word_count=12,
            passphrase_protection=False,
            pin_protection=False,
            label="label",
            language="en-US",
            enforce_wordlist=True,
        )
    )

    # click through confirmation
    assert isinstance(ret, messages.ButtonRequest)
    client.debug.press_yes()
    ret = client.call_raw(messages.ButtonAck())

    fakes = 0
    for _ in range(int(12 * 2)):
        assert isinstance(ret, messages.WordRequest)
        (word, pos) = client.debug.read_recovery_word()

        if pos != 0:
            ret = client.call_raw(messages.WordAck(word=mnemonic[pos - 1]))
            mnemonic[pos - 1] = None
        else:
            ret = client.call_raw(messages.WordAck(word=word))
            fakes += 1

    # Workflow succesfully ended
    assert isinstance(ret, messages.Success)

    # 12 expected fake words and all words of mnemonic are used
    assert fakes == 12
    assert mnemonic == [None] * 12

    # Mnemonic is the same
    client.init_device()
    assert client.debug.state().mnemonic_secret == MNEMONIC12.encode()

    assert client.features.pin_protection is False
    assert client.features.passphrase_protection is False

    # Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
    resp = client.call_raw(messages.GetAddress(address_n=parse_path("m/44'/0'/0'/0/0")))
    assert isinstance(resp, messages.Address)
Esempio n. 11
0
def test_autolock_cancels_ui(client):
    set_autolock_delay(client, 10 * 1000)

    resp = client.call_raw(
        messages.GetAddress(
            coin_name="Testnet",
            address_n=TEST_ADDRESS_N,
            show_display=True,
            script_type=messages.InputScriptType.SPENDADDRESS,
        ))
    assert isinstance(resp, messages.ButtonRequest)

    # send an ack, do not read response
    client._raw_write(messages.ButtonAck())
    # sleep more than auto-lock delay
    time.sleep(10.1)
    resp = client._raw_read()

    assert isinstance(resp, messages.Failure)
    assert resp.code == messages.FailureType.ActionCancelled
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_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)
Esempio n. 14
0
import pytest

import trezorlib.messages as m
from trezorlib.exceptions import Cancelled

from ..common import TEST_ADDRESS_N


@pytest.mark.parametrize(
    "message",
    [
        m.Ping(message="hello", button_protection=True),
        m.GetAddress(
            address_n=TEST_ADDRESS_N,
            coin_name="Testnet",
            script_type=m.InputScriptType.SPENDADDRESS,
            show_display=True,
        ),
    ],
)
def test_cancel_message_via_cancel(client, message):
    def input_flow():
        yield
        client.cancel()

    with client, pytest.raises(Cancelled):
        client.set_expected_responses([m.ButtonRequest(), m.Failure()])
        client.set_input_flow(input_flow)
        client.call(message)

def _check_no_pin(client):
    client.lock()
    with client:
        client.set_expected_responses([messages.Address()])
        client.call(messages.GetAddress())
Esempio n. 16
0
    def test_reset_device_256_pin(self, client):
        external_entropy = b"zlutoucky kun upel divoke ody" * 2
        strength = 256

        ret = client.call_raw(
            proto.ResetDevice(
                display_random=True,
                strength=strength,
                passphrase_protection=True,
                pin_protection=True,
                language="en-US",
                label="test",
            ))

        # Do you want ... ?
        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        # Entropy screen #1
        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        # Entropy screen #2
        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        assert isinstance(ret, proto.PinMatrixRequest)

        # Enter PIN for first time
        pin_encoded = client.debug.encode_pin("654")
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
        assert isinstance(ret, proto.PinMatrixRequest)

        # Enter PIN for second time
        pin_encoded = client.debug.encode_pin("654")
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        # Provide entropy
        assert isinstance(ret, proto.EntropyRequest)
        internal_entropy = client.debug.state().reset_entropy
        ret = client.call_raw(proto.EntropyAck(entropy=external_entropy))

        # Generate mnemonic locally
        entropy = generate_entropy(strength, internal_entropy,
                                   external_entropy)
        expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

        mnemonic = []
        for _ in range(strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(client.debug.read_reset_word())
            client.debug.press_yes()
            client.call_raw(proto.ButtonAck())

        mnemonic = " ".join(mnemonic)

        # Compare that device generated proper mnemonic for given entropies
        assert mnemonic == expected_mnemonic

        mnemonic = []
        for _ in range(strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(client.debug.read_reset_word())
            client.debug.press_yes()
            resp = client.call_raw(proto.ButtonAck())

        assert isinstance(resp, proto.Success)

        mnemonic = " ".join(mnemonic)

        # Compare that second pass printed out the same mnemonic once again
        assert mnemonic == expected_mnemonic

        # Check if device is properly initialized
        resp = client.call_raw(proto.Initialize())
        assert resp.initialized is True
        assert resp.needs_backup is False
        assert resp.pin_protection is True
        assert resp.passphrase_protection is True

        # Do passphrase-protected action, PassphraseRequest should be raised
        resp = client.call_raw(proto.GetAddress())
        assert isinstance(resp, proto.PassphraseRequest)
        client.call_raw(proto.Cancel())
Esempio n. 17
0
def reset_device(client, strength):
    # No PIN, no passphrase
    external_entropy = b"zlutoucky kun upel divoke ody" * 2

    ret = client.call_raw(
        proto.ResetDevice(
            display_random=False,
            strength=strength,
            passphrase_protection=False,
            pin_protection=False,
            language="en-US",
            label="test",
        ))

    assert isinstance(ret, proto.ButtonRequest)
    client.debug.press_yes()
    ret = client.call_raw(proto.ButtonAck())

    # Provide entropy
    assert isinstance(ret, proto.EntropyRequest)
    internal_entropy = client.debug.state().reset_entropy
    ret = client.call_raw(proto.EntropyAck(entropy=external_entropy))

    # Generate mnemonic locally
    entropy = generate_entropy(strength, internal_entropy, external_entropy)
    expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

    mnemonic = []
    for _ in range(strength // 32 * 3):
        assert isinstance(ret, proto.ButtonRequest)
        mnemonic.append(client.debug.read_reset_word())
        client.debug.press_yes()
        client.call_raw(proto.ButtonAck())

    mnemonic = " ".join(mnemonic)

    # Compare that device generated proper mnemonic for given entropies
    assert mnemonic == expected_mnemonic

    mnemonic = []
    for _ in range(strength // 32 * 3):
        assert isinstance(ret, proto.ButtonRequest)
        mnemonic.append(client.debug.read_reset_word())
        client.debug.press_yes()
        resp = client.call_raw(proto.ButtonAck())

    assert isinstance(resp, proto.Success)

    mnemonic = " ".join(mnemonic)

    # Compare that second pass printed out the same mnemonic once again
    assert mnemonic == expected_mnemonic

    # Check if device is properly initialized
    resp = client.call_raw(proto.Initialize())
    assert resp.initialized is True
    assert resp.needs_backup is False
    assert resp.pin_protection is False
    assert resp.passphrase_protection is False

    # Do pin & passphrase-protected action, PassphraseRequest should NOT be raised
    resp = client.call_raw(proto.GetAddress())
    assert isinstance(resp, proto.Address)
Esempio n. 18
0
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.

import pytest

import trezorlib.messages as m
from trezorlib.exceptions import Cancelled


@pytest.mark.parametrize(
    "message",
    [
        m.Ping(message="hello", button_protection=True),
        m.GetAddress(
            address_n=[0],
            coin_name="Bitcoin",
            script_type=m.InputScriptType.SPENDADDRESS,
            show_display=True,
        ),
    ],
)
def test_cancel_message_via_cancel(client, message):
    def input_flow():
        yield
        client.cancel()

    with client, pytest.raises(Cancelled):
        client.set_expected_responses([m.ButtonRequest(), m.Failure()])
        client.set_input_flow(input_flow)
        client.call(message)