예제 #1
0
    def test_nopin_nopassphrase(self):
        mnemonic = self.mnemonic12.split(" ")
        ret = self.client.call_raw(
            proto.RecoveryDevice(
                passphrase_protection=False,
                pin_protection=False,
                label="label",
                enforce_wordlist=True,
            ))

        # Enter word count
        assert ret == proto.ButtonRequest(
            code=proto.ButtonRequestType.MnemonicWordCount)
        self.client.debug.input(str(len(mnemonic)))
        ret = self.client.call_raw(proto.ButtonAck())

        # Enter mnemonic words
        assert ret == proto.ButtonRequest(
            code=proto.ButtonRequestType.MnemonicInput)
        self.client.transport.write(proto.ButtonAck())
        for word in mnemonic:
            time.sleep(1)
            self.client.debug.input(word)
        ret = self.client.transport.read()

        # Workflow succesfully ended
        assert ret == proto.Success(message="Device recovered")

        # Mnemonic is the same
        self.client.init_device()
        assert self.client.debug.read_mnemonic() == self.mnemonic12

        assert self.client.features.pin_protection is False
        assert self.client.features.passphrase_protection is False
예제 #2
0
    def _nem_sign(self, num_of_swipes, test_suite):
        n = parse_path("m/44'/1'/0'/0'/0'")
        msg = nem.create_sign_tx(test_suite)
        assert msg.transaction is not None
        msg.transaction.address_n = n

        # Sending NEMSignTx message
        self.client.transport.write(msg)
        ret = self.client.transport.read()

        # Confirm action
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        self.client.transport.write(proto.ButtonAck())
        time.sleep(1)
        for i in range(num_of_swipes):
            self.client.debug.swipe_down()
            time.sleep(1)
        self.client.debug.press_yes()
        ret = self.client.transport.read()

        # Confirm action
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        self.client.transport.write(proto.ButtonAck())
        ret = self.client.transport.read()

        # Confirm tx
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        self.client.transport.write(proto.ButtonAck())
        return self.client.transport.read()
def test_passphrase_always_on_device(client):
    # Let's start the communication by calling Initialize.
    session_id = _init_session(client)

    # Force passphrase entry on Trezor.
    response = client.call(
        messages.ApplySettings(passphrase_always_on_device=True))
    assert isinstance(response, messages.Success)

    # Since we enabled the always_on_device setting, Trezor will send ButtonRequests and ask for it on the device.
    response = client.call_raw(XPUB_REQUEST)
    assert isinstance(response, messages.ButtonRequest)
    client.debug.input("")  # Input empty passphrase.
    response = client.call_raw(messages.ButtonAck())
    assert isinstance(response, messages.PublicKey)
    assert response.xpub == XPUB_PASSPHRASE_NONE

    # Passphrase will not be prompted. The session id stays the same and the passphrase is cached.
    _init_session(client, session_id=session_id)
    response = client.call_raw(XPUB_REQUEST)
    assert isinstance(response, messages.PublicKey)
    assert response.xpub == XPUB_PASSPHRASE_NONE

    # In case we want to add a new passphrase we need to send session_id = None.
    _init_session(client)
    response = client.call_raw(XPUB_REQUEST)
    assert isinstance(response, messages.ButtonRequest)
    client.debug.input("A")  # Input non-empty passphrase.
    response = client.call_raw(messages.ButtonAck())
    assert isinstance(response, messages.PublicKey)
    assert response.xpub == XPUB_PASSPHRASES["A"]
예제 #4
0
def test_cancel_on_paginated(client):
    """Check that device is responsive on paginated screen. See #1708."""
    # In #1708, the device would ignore USB (or UDP) events while waiting for the user
    # to page through the screen. This means that this testcase, instead of failing,
    # would get stuck waiting for the _raw_read result.
    # I'm not spending the effort to modify the testcase to cause a _failure_ if that
    # happens again. Just be advised that this should not get stuck.
    message = m.SignMessage(
        message=b"hello" * 64,
        address_n=TEST_ADDRESS_N,
        coin_name="Testnet",
    )
    resp = client.call_raw(message)
    assert isinstance(resp, m.ButtonRequest)
    client._raw_write(m.ButtonAck())
    client.debug.press_yes()

    resp = client._raw_read()
    assert isinstance(resp, m.ButtonRequest)
    assert resp.pages is not None
    client._raw_write(m.ButtonAck())

    client._raw_write(m.Cancel())
    resp = client._raw_read()
    assert isinstance(resp, m.Failure)
    assert resp.code == m.FailureType.ActionCancelled
예제 #5
0
def test_wipe_code_activate_core():
    with EmulatorWrapper("core") as emu:
        # set up device
        setup_device_core(emu.client, PIN, WIPE_CODE)

        emu.client.init_device()
        device_id = emu.client.features.device_id

        # Initiate Change pin process
        ret = emu.client.call_raw(messages.ChangePin(remove=False))
        assert isinstance(ret, messages.ButtonRequest)
        emu.client.debug.press_yes()
        ret = emu.client.call_raw(messages.ButtonAck())

        # Enter the wipe code instead of the current PIN
        assert ret == messages.ButtonRequest(
            code=messages.ButtonRequestType.PinEntry)
        emu.client._raw_write(messages.ButtonAck())
        emu.client.debug.input(WIPE_CODE)

        # wait 30 seconds for emulator to shut down
        # this will raise a TimeoutError if the emulator doesn't die.
        emu.wait(30)

        emu.start()
        assert emu.client.features.initialized is False
        assert emu.client.features.pin_protection is False
        assert emu.client.features.wipe_code_protection is False
        assert emu.client.features.device_id != device_id
    def test_failed_pin(self):
        # external_entropy = b'zlutoucky kun upel divoke ody' * 2
        strength = 128

        ret = self.client.call_raw(
            proto.ResetDevice(
                display_random=True,
                strength=strength,
                passphrase_protection=True,
                pin_protection=True,
                language="english",
                label="test",
            )
        )

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

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

        assert isinstance(ret, proto.PinMatrixRequest)

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

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

        assert isinstance(ret, proto.Failure)
예제 #7
0
    def test_pin_passphrase(self):
        mnemonic = self.mnemonic12.split(" ")
        ret = self.client.call_raw(
            proto.RecoveryDevice(
                passphrase_protection=True,
                pin_protection=True,
                label="label",
                enforce_wordlist=True,
            ))

        # Confirm Recovery
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        ret = self.client.call_raw(proto.ButtonAck())

        # Enter word count
        assert ret == proto.ButtonRequest(
            code=proto.ButtonRequestType.MnemonicWordCount)
        self.client.debug.input(str(len(mnemonic)))
        ret = self.client.call_raw(proto.ButtonAck())

        # Enter mnemonic words
        assert ret == proto.ButtonRequest(
            code=proto.ButtonRequestType.MnemonicInput)
        self.client.transport.write(proto.ButtonAck())
        for word in mnemonic:
            time.sleep(1)
            self.client.debug.input(word)
        ret = self.client.transport.read()

        # Enter PIN for first time
        assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other)
        self.client.debug.input("654")
        ret = self.client.call_raw(proto.ButtonAck())

        # Enter PIN for second time
        assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.Other)
        self.client.debug.input("654")
        ret = self.client.call_raw(proto.ButtonAck())

        # Workflow succesfully ended
        assert ret == proto.Success(message="Device recovered")

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

        assert self.client.features.pin_protection is True
        assert self.client.features.passphrase_protection is True
    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.Ping(pin_protection=True))
        assert isinstance(ret, proto.Success)

        # 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(self.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(self.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, self.pin6)
예제 #9
0
def _check_wipe_code(client, wipe_code):
    # Try to change the PIN to the current wipe code value. The operation should fail.
    ret = client.call_raw(messages.ChangePin())
    assert isinstance(ret, messages.ButtonRequest)

    # Confirm intent to change PIN.
    client.debug.press_yes()
    ret = client.call_raw(messages.ButtonAck())

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

    # Send the new wipe code for the first time.
    assert isinstance(ret, messages.PinMatrixRequest)
    wipe_code_encoded = client.debug.encode_pin(wipe_code)
    ret = client.call_raw(messages.PinMatrixAck(pin=wipe_code_encoded))

    # Send the new wipe code for the second time.
    assert isinstance(ret, messages.PinMatrixRequest)
    wipe_code_encoded = client.debug.encode_pin(wipe_code)
    ret = client.call_raw(messages.PinMatrixAck(pin=wipe_code_encoded))

    # Expect failure.
    assert isinstance(ret, messages.Failure)
예제 #10
0
def _set_wipe_code(client, wipe_code):
    # Set/change wipe code.
    ret = client.call_raw(messages.ChangeWipeCode())
    assert isinstance(ret, messages.ButtonRequest)

    # Confirm intent to set/change wipe code.
    client.debug.press_yes()
    ret = client.call_raw(messages.ButtonAck())

    if client.features.pin_protection:
        # Send current PIN.
        assert isinstance(ret, messages.PinMatrixRequest)
        pin_encoded = client.debug.read_pin_encoded()
        ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))

    # Send the new wipe code for the first time.
    assert isinstance(ret, messages.PinMatrixRequest)
    wipe_code_encoded = client.debug.encode_pin(wipe_code)
    ret = client.call_raw(messages.PinMatrixAck(pin=wipe_code_encoded))

    # Send the new wipe code for the second time.
    assert isinstance(ret, messages.PinMatrixRequest)
    wipe_code_encoded = client.debug.encode_pin(wipe_code)
    ret = client.call_raw(messages.PinMatrixAck(pin=wipe_code_encoded))

    # Now we're done.
    assert isinstance(ret, messages.Success)
예제 #11
0
def test_set_pin_to_wipe_code(client):
    # Set wipe code.
    _set_wipe_code(client, WIPE_CODE4)

    # Try to set the PIN to the current wipe code value.
    ret = client.call_raw(messages.ChangePin())
    assert isinstance(ret, messages.ButtonRequest)

    # Confirm intent to set PIN.
    client.debug.press_yes()
    ret = client.call_raw(messages.ButtonAck())

    # Send the new PIN for the first time.
    assert isinstance(ret, messages.PinMatrixRequest)
    pin_encoded = client.debug.encode_pin(WIPE_CODE4)
    ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))

    # Send the new PIN for the second time.
    assert isinstance(ret, messages.PinMatrixRequest)
    pin_encoded = client.debug.encode_pin(WIPE_CODE4)
    ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))

    # The operation should fail, because the PIN must be different from the wipe code.
    assert isinstance(ret, messages.Failure)
    assert ret.code == messages.FailureType.ProcessError

    # Check that there is no PIN protection.
    client.init_device()
    assert client.features.pin_protection is False
    ret = client.call_raw(messages.Ping(pin_protection=True))
    assert isinstance(ret, messages.Success)
예제 #12
0
def test_set_wipe_code_to_pin(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.
    ret = client.call_raw(messages.ChangeWipeCode())
    assert isinstance(ret, messages.ButtonRequest)

    # Confirm intent to set wipe code.
    client.debug.press_yes()
    ret = client.call_raw(messages.ButtonAck())

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

    # Send the new wipe code.
    assert isinstance(ret, messages.PinMatrixRequest)
    pin_encoded = client.debug.read_pin_encoded()
    ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded))

    # The operation should fail, because the wipe code must be different from the PIN.
    assert isinstance(ret, messages.Failure)
    assert ret.code == messages.FailureType.ProcessError

    # Check that there is no wipe code protection.
    client.init_device()
    assert client.features.wipe_code_protection is False
예제 #13
0
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.
    ret = client.call_raw(messages.ChangeWipeCode())
    assert isinstance(ret, messages.ButtonRequest)

    # Confirm intent to set wipe code.
    client.debug.press_yes()
    ret = client.call_raw(messages.ButtonAck())

    # Send the new wipe code for the first time.
    assert isinstance(ret, messages.PinMatrixRequest)
    wipe_code_encoded = client.debug.encode_pin(WIPE_CODE4)
    ret = client.call_raw(messages.PinMatrixAck(pin=wipe_code_encoded))

    # Send the new wipe code for the second time, but different.
    assert isinstance(ret, messages.PinMatrixRequest)
    wipe_code_encoded = client.debug.encode_pin(WIPE_CODE6)
    ret = client.call_raw(messages.PinMatrixAck(pin=wipe_code_encoded))

    # The operation should fail, because the wipe codes are different.
    assert isinstance(ret, messages.Failure)
    assert ret.code == messages.FailureType.WipeCodeMismatch

    # Check that there is no wipe code protection.
    client.init_device()
    assert client.features.wipe_code_protection is False
    def test_reset_device_no_backup(self):

        ret = self.client.call_raw(
            proto.ResetDevice(
                display_random=False,
                strength=self.strength,
                passphrase_protection=False,
                pin_protection=False,
                language="english",
                label="test",
                no_backup=True,
            ))

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

        # Provide entropy
        assert isinstance(ret, proto.EntropyRequest)
        ret = self.client.call_raw(
            proto.EntropyAck(entropy=self.external_entropy))
        assert isinstance(ret, proto.Success)

        # Check if device is properly initialized
        ret = self.client.call_raw(proto.Initialize())
        assert ret.initialized is True
        assert ret.needs_backup is False
        assert ret.unfinished_backup is False
        assert ret.no_backup is True

        # start backup - should fail
        ret = self.client.call_raw(proto.BackupDevice())
        assert isinstance(ret, proto.Failure)
    def test_change_mismatch(self, client):
        features = client.call_raw(proto.Initialize())
        assert features.pin_protection is True

        # 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 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)
    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)
예제 #17
0
    def derive(cls, set_address=False, hdpath=None):
        logging.info("Attempting to derive %s/%s", hdpath_base, hdpath_index)

        address_n = tools.parse_path(hdpath)
        call_obj = proto.EthereumGetAddress(address_n=address_n,
                                            show_display=False)
        try:
            response = cls.call_raw(call_obj)

            while response.__class__.__name__ == 'ButtonRequest':
                response = cls.call_raw(proto.ButtonAck())
            if response.__class__.__name__ == 'PinMatrixRequest':
                cls.matrix_request_window()
            elif response.__class__.__name__ == 'PassphraseRequest':
                cls.passphrase_request_window()
            elif response.__class__.__name__ == 'Failure':
                raise DeriveCredstickAddressError
            else:
                logging.info("trezor response address: 0x%s", response)
                address = response.address
                if set_address is True:
                    cls.address = address
                cls.hdpath = hdpath
                cls.config.hdpath = hdpath

                return address

        except TransportException:
            raise DeriveCredstickAddressError
예제 #18
0
    def recovery_loop(self, client, mnemonic, result):
        ret = client.call_raw(
            proto.RecoveryDevice(
                word_count=12,
                passphrase_protection=False,
                pin_protection=False,
                label="label",
                language="english",
                enforce_wordlist=True,
                dry_run=True,
            ))

        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)

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

        ret = client.call_raw(proto.ButtonAck())
        assert isinstance(ret, result)
def test_passphrase_on_device(client):
    _init_session(client)

    # try to get xpub with passphrase on host:
    response = client.call_raw(XPUB_REQUEST)
    assert isinstance(response, messages.PassphraseRequest)
    response = client.call_raw(
        messages.PassphraseAck(passphrase="A", on_device=False))
    assert isinstance(response, messages.PublicKey)
    assert response.xpub == XPUB_PASSPHRASES["A"]

    # try to get xpub again, passphrase should be cached
    response = client.call_raw(XPUB_REQUEST)
    assert isinstance(response, messages.PublicKey)
    assert response.xpub == XPUB_PASSPHRASES["A"]

    # make a new session
    _init_session(client)

    # try to get xpub with passphrase on device:
    response = client.call_raw(XPUB_REQUEST)
    assert isinstance(response, messages.PassphraseRequest)
    response = client.call_raw(messages.PassphraseAck(on_device=True))
    assert isinstance(response, messages.ButtonRequest)
    client.debug.input("A")
    response = client.call_raw(messages.ButtonAck())
    assert isinstance(response, messages.PublicKey)
    assert response.xpub == XPUB_PASSPHRASES["A"]

    # try to get xpub again, passphrase should be cached
    response = client.call_raw(XPUB_REQUEST)
    assert isinstance(response, messages.PublicKey)
    assert response.xpub == XPUB_PASSPHRASES["A"]
예제 #20
0
    def test_pin_fail(self, client):
        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(PIN4)
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
        assert isinstance(ret, proto.PinMatrixRequest)

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

        # Failure should be raised
        assert isinstance(ret, proto.Failure)
예제 #21
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())
예제 #22
0
    def test_word_fail(self, client):
        ret = client.call_raw(
            proto.RecoveryDevice(
                word_count=12,
                passphrase_protection=False,
                pin_protection=False,
                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.WordRequest)
        for _ in range(int(12 * 2)):
            (word, pos) = client.debug.read_recovery_word()
            if pos != 0:
                ret = client.call_raw(proto.WordAck(word="kwyjibo"))
                assert isinstance(ret, proto.Failure)
                break
            else:
                client.call_raw(proto.WordAck(word=word))
예제 #23
0
    def test_set_failed_2(self):
        self.setup_mnemonic_pin_passphrase()
        features = self.client.call_raw(proto.Initialize())
        assert features.pin_protection is True

        # Let's set new PIN
        ret = self.client.call_raw(proto.ChangePin())
        assert isinstance(ret, proto.ButtonRequest)

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

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

        # Send the PIN for first time
        assert isinstance(ret, proto.PinMatrixRequest)
        pin_encoded = self.client.debug.encode_pin(self.pin6)
        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        # Send the PIN for second time, but with typo
        assert isinstance(ret, proto.PinMatrixRequest)
        pin_encoded = self.client.debug.encode_pin(self.pin6 + '3')
        ret = self.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 = self.client.call_raw(proto.Initialize())
        assert features.pin_protection is True
        assert self.client.debug.read_pin()[0] == self.pin4
예제 #24
0
    def test_set_failed(self):
        self.setup_mnemonic_nopin_nopassphrase()
        features = self.client.call_raw(proto.Initialize())
        assert features.pin_protection is False

        # Check that there's no PIN protection
        ret = self.client.call_raw(proto.Ping(pin_protection=True))
        assert isinstance(ret, proto.Success)

        # Let's set new PIN
        ret = self.client.call_raw(proto.ChangePin())
        assert isinstance(ret, proto.ButtonRequest)

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

        # Send the PIN for first time
        assert isinstance(ret, proto.PinMatrixRequest)
        pin_encoded = self.client.debug.encode_pin(self.pin6)
        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        # Send the PIN for second time, but with typo
        assert isinstance(ret, proto.PinMatrixRequest)
        pin_encoded = self.client.debug.encode_pin(self.pin4)
        ret = self.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 = self.client.call_raw(proto.Initialize())
        assert features.pin_protection is False
        ret = self.client.call_raw(proto.Ping(pin_protection=True))
        assert isinstance(ret, proto.Success)
예제 #25
0
    def test_remove_pin(self):
        self.setup_mnemonic_pin_passphrase()
        features = self.client.call_raw(proto.Initialize())
        assert features.pin_protection is True

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

        # Let's remove PIN
        ret = self.client.call_raw(proto.ChangePin(remove=True))
        assert isinstance(ret, proto.ButtonRequest)

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

        # Send current PIN
        assert isinstance(ret, proto.PinMatrixRequest)
        pin_encoded = self.client.debug.read_pin_encoded()
        ret = self.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 = self.client.call_raw(proto.Initialize())
        assert features.pin_protection is False
        ret = self.client.call_raw(proto.Ping(pin_protection=True))
        assert isinstance(ret, proto.Success)
예제 #26
0
    def test_failed_pin(self):
        # external_entropy = b'zlutoucky kun upel divoke ody' * 2
        strength = 128
        ret = self.client.call_raw(
            proto.ResetDevice(strength=strength, pin_protection=True, label="test")
        )

        # Enter PIN for first time
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.input("654")
        ret = self.client.call_raw(proto.ButtonAck())

        # Enter PIN for second time
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.input("456")
        ret = self.client.call_raw(proto.ButtonAck())

        assert isinstance(ret, proto.ButtonRequest)
예제 #27
0
def test_cancel_message_via_initialize(client, message):
    resp = client.call_raw(message)
    assert isinstance(resp, m.ButtonRequest)

    client._raw_write(m.ButtonAck())
    client._raw_write(m.Initialize())

    resp = client._raw_read()

    assert isinstance(resp, m.Features)
예제 #28
0
    def test_nopin_nopassphrase(self):
        mnemonic = self.mnemonic12.split(" ")
        ret = self.client.call_raw(
            proto.RecoveryDevice(
                word_count=12,
                passphrase_protection=False,
                pin_protection=False,
                label="label",
                language="english",
                enforce_wordlist=True,
            ))

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

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

            if pos != 0:
                ret = self.client.call_raw(
                    proto.WordAck(word=mnemonic[pos - 1]))
                mnemonic[pos - 1] = None
            else:
                ret = self.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
        self.client.init_device()
        assert self.client.debug.read_mnemonic_secret(
        ) == self.mnemonic12.encode()

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

        # Do passphrase-protected action, PassphraseRequest should NOT be raised
        resp = self.client.call_raw(proto.Ping(passphrase_protection=True))
        assert isinstance(resp, proto.Success)

        # Do PIN-protected action, PinRequest should NOT be raised
        resp = self.client.call_raw(proto.Ping(pin_protection=True))
        assert isinstance(resp, proto.Success)
예제 #29
0
def test_cancel_message_via_cancel(client, message):
    resp = client.call_raw(message)
    assert isinstance(resp, m.ButtonRequest)

    client.transport.write(m.ButtonAck())
    client.transport.write(m.Cancel())

    resp = client.transport.read()

    assert isinstance(resp, m.Failure)
    assert resp.code == m.FailureType.ActionCancelled
예제 #30
0
    def test_failed_pin(self, client):
        # external_entropy = b'zlutoucky kun upel divoke ody' * 2
        strength = 128

        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("1234")
        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("6789")
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        assert isinstance(ret, proto.Failure)