예제 #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
    def test_recovery_device(self, client):
        client.set_mnemonic(MNEMONIC12)
        with client:
            client.set_expected_responses(
                [proto.ButtonRequest()]
                + [proto.WordRequest()] * 24
                + [proto.Success(), proto.Features()]
            )

            device.recover(
                client, 12, False, False, "label", "english", client.mnemonic_callback
            )

        with pytest.raises(TrezorFailure):
            # This must fail, because device is already initialized
            # Using direct call because `device.reset` has its own check
            client.call(
                proto.RecoveryDevice(
                    word_count=12,
                    passphrase_protection=False,
                    pin_protection=False,
                    label="label",
                    language="english",
                )
            )
예제 #3
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))
예제 #4
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)
예제 #5
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_recovery_device(client: Client):
    assert client.features.pin_protection is False
    assert client.features.passphrase_protection is False
    client.use_mnemonic(MNEMONIC12)
    with client:
        client.set_expected_responses(
            [messages.ButtonRequest]
            + [messages.WordRequest] * 24
            + [messages.Success, messages.Features]
        )

        device.recover(
            client, 12, False, False, "label", "en-US", client.mnemonic_callback
        )

    with pytest.raises(TrezorFailure):
        # This must fail, because device is already initialized
        # Using direct call because `device.recover` has its own check
        client.call(
            messages.RecoveryDevice(
                word_count=12,
                passphrase_protection=False,
                pin_protection=False,
                label="label",
                language="en-US",
            )
        )
예제 #7
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_pin_passphrase(self):
        mnemonic = self.mnemonic12.split(' ')
        ret = self.client.call_raw(
            proto.RecoveryDevice(word_count=12,
                                 passphrase_protection=True,
                                 pin_protection=True,
                                 label='label',
                                 language='english',
                                 enforce_wordlist=True))

        assert isinstance(ret, proto.PinMatrixRequest)

        # Enter PIN for first time
        pin_encoded = self.client.debug.encode_pin(self.pin6)
        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))

        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() == self.mnemonic12

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

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

        # Do PIN-protected action, PinRequest should be raised
        resp = self.client.call_raw(proto.Ping(pin_protection=True))
        assert isinstance(resp, proto.PinMatrixRequest)
        self.client.call_raw(proto.Cancel())
예제 #9
0
    def test_already_initialized(self, client):
        with pytest.raises(RuntimeError):
            device.recover(client, 12, False, False, "label", "en-US",
                           client.mnemonic_callback)

        ret = client.call_raw(
            proto.RecoveryDevice(word_count=12,
                                 type=proto.RecoveryDeviceType.ScrambledWords))
        assert isinstance(ret, proto.Failure)
        assert "Device is already initialized" in ret.message
예제 #10
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())

        # Confirm success
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        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
예제 #11
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)
def test_bad_parameters(client, field_name, field_value):
    msg = messages.RecoveryDevice(
        dry_run=True,
        word_count=12,
        enforce_wordlist=True,
        type=messages.RecoveryDeviceType.ScrambledWords,
    )
    setattr(msg, field_name, field_value)
    with pytest.raises(exceptions.TrezorFailure,
                       match="Forbidden field set in dry-run"):
        client.call(msg)
    def test_nopin_nopassphrase(self, client):
        mnemonic = MNEMONIC12.split(" ")
        ret = client.call_raw(
            proto.RecoveryDevice(
                passphrase_protection=False,
                pin_protection=False,
                label="label",
                enforce_wordlist=True,
            ))

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

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

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

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

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

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

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

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

        assert client.features.pin_protection is False
        assert client.features.passphrase_protection is False
        assert client.features.backup_type is proto.BackupType.Bip39
예제 #14
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)
    def test_word_fail(self):
        ret = self.client.call_raw(
            proto.RecoveryDevice(word_count=12,
                                 passphrase_protection=False,
                                 pin_protection=False,
                                 label='label',
                                 language='english',
                                 enforce_wordlist=True))

        assert isinstance(ret, proto.WordRequest)
        for _ in range(int(12 * 2)):
            (word, pos) = self.client.debug.read_recovery_word()
            if pos != 0:
                ret = self.client.call_raw(proto.WordAck(word='kwyjibo'))
                assert isinstance(ret, proto.Failure)
                break
            else:
                self.client.call_raw(proto.WordAck(word=word))
    def test_pin_fail(self):
        ret = self.client.call_raw(
            proto.RecoveryDevice(word_count=12,
                                 passphrase_protection=True,
                                 pin_protection=True,
                                 label='label',
                                 language='english',
                                 enforce_wordlist=True))

        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, but different one
        pin_encoded = self.client.debug.encode_pin(self.pin6)
        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        # Failure should be raised
        assert isinstance(ret, proto.Failure)
예제 #17
0
    def test_abort(self):
        ret = self.client.call_raw(
            proto.RecoveryDevice(passphrase_protection=False,
                                 pin_protection=False,
                                 label="label"))

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

        # Homescreen - abort process
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_no()
        ret = self.client.call_raw(proto.ButtonAck())

        # Homescreen - yup, really
        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        ret = self.client.call_raw(proto.ButtonAck())

        # check that the device is wiped
        features = self.client.call_raw(proto.Initialize())
        assert features.initialized is False
예제 #18
0
    def test_2of5_pin_passphrase(self):
        # 256 bits security, 2 of 5
        mnemonics = [
            "hobo romp academic axis august founder knife legal recover alien expect emphasis loan kitchen involve teacher capture rebuild trial numb spider forward ladle lying voter typical security quantity hawk legs idle leaves gasoline",
            "hobo romp academic agency ancestor industry argue sister scene midst graduate profile numb paid headset airport daisy flame express scene usual welcome quick silent downtown oral critical step remove says rhythm venture aunt",
        ]
        # TODO: add incorrect mnemonic to test
        word_count = len(mnemonics[0].split(" "))

        ret = self.client.call_raw(
            proto.RecoveryDevice(passphrase_protection=True,
                                 pin_protection=True,
                                 label="label"))

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

        # 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())

        # Homescreen
        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(word_count))
        ret = self.client.call_raw(proto.ButtonAck())

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

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

            if mnemonic != mnemonics[-1]:
                # Homescreen
                assert isinstance(ret, proto.ButtonRequest)
                self.client.debug.press_yes()
                ret = self.client.call_raw(proto.ButtonAck())

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

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

        # Check mnemonic
        self.client.init_device()
        assert (
            self.client.debug.read_mnemonic_secret().hex() ==
            "b770e0da1363247652de97a39bdbf2463be087848d709ecbf28e84508e31202a")

        assert self.client.features.pin_protection is True
        assert self.client.features.passphrase_protection is True
def test_already_initialized(client):
    with pytest.raises(RuntimeError):
        device.recover(client)

    with pytest.raises(exceptions.TrezorFailure, match="Already initialized"):
        client.call(messages.RecoveryDevice())
예제 #20
0
    def test_3of6_nopin_nopassphrase(self):
        # 128 bits security, 3 of 6
        mnemonics = [
            "extra extend academic bishop cricket bundle tofu goat apart victim enlarge program behavior permit course armed jerky faint language modern",
            "extra extend academic acne away best indicate impact square oasis prospect painting voting guest either argue username racism enemy eclipse",
            "extra extend academic arcade born dive legal hush gross briefing talent drug much home firefly toxic analysis idea umbrella slice",
        ]
        word_count = len(mnemonics[0].split(" "))

        ret = self.client.call_raw(
            proto.RecoveryDevice(passphrase_protection=False,
                                 pin_protection=False,
                                 label="label"))

        # 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(word_count))
        ret = self.client.call_raw(proto.ButtonAck())

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

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

            if mnemonic != mnemonics[-1]:
                # Confirm status
                assert isinstance(ret, proto.ButtonRequest)
                self.client.debug.press_yes()
                ret = self.client.call_raw(proto.ButtonAck())

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

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

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

        # Check mnemonic
        assert (self.client.debug.read_mnemonic_secret().hex() ==
                "491b795b80fc21ccdf466c0fbc98c8fc")

        # BIP32 Root Key for empty passphrase
        # provided by Andrew, address calculated using T1
        # xprv9s21ZrQH143K3reExTJbGTHPu6mGuUx6yN1H1KkqoiAcw6j1t6hBiwwnXYxNQXxU8T7pANSv1rJYQPXn1LMQk1gbWes5BjSz3rJ5ZfH1cc3
        address = btc.get_address(self.client, "Bitcoin", [])
        assert address == "1G1MwH5sLVxKQ7yKYasfE5pxWaABLo7VK7"
예제 #21
0
    def test_2of5_pin_passphrase(self):
        # 256 bits security, 2 of 5
        mnemonics = [
            "hobo romp academic axis august founder knife legal recover alien expect emphasis loan kitchen involve teacher capture rebuild trial numb spider forward ladle lying voter typical security quantity hawk legs idle leaves gasoline",
            "hobo romp academic agency ancestor industry argue sister scene midst graduate profile numb paid headset airport daisy flame express scene usual welcome quick silent downtown oral critical step remove says rhythm venture aunt",
        ]
        word_count = len(mnemonics[0].split(" "))

        ret = self.client.call_raw(
            proto.RecoveryDevice(passphrase_protection=True,
                                 pin_protection=True,
                                 label="label"))

        # 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(word_count))
        ret = self.client.call_raw(proto.ButtonAck())

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

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

            if mnemonic != mnemonics[-1]:
                # Confirm status
                assert isinstance(ret, proto.ButtonRequest)
                self.client.debug.press_yes()
                ret = self.client.call_raw(proto.ButtonAck())

        # 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())

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

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

        # Check mnemonic
        self.client.init_device()
        assert (
            self.client.debug.read_mnemonic_secret().hex() ==
            "b770e0da1363247652de97a39bdbf2463be087848d709ecbf28e84508e31202a")

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

        device.apply_settings(self.client,
                              passphrase_source=PASSPHRASE_ON_HOST)

        # BIP32 Root Key for empty passphrase
        # provided by Andrew, address calculated using T1
        # xprv9s21ZrQH143K2kP9RYJE5AFggTHLs8PbDaaTYtvh238THxDyXqyqQV6H1QpFr3aaQ7CFusFMYyGZ6VcK7aLADyCaCJrszovxtzVZmnRfca4
        address = btc.get_address(self.client, "Bitcoin", [])
        assert address == "1BmqXKM8M1gWA4bgkbPeCtJruRnrY2qYKP"