Skip to content

Commit

Permalink
tests: added device tests for dry run and warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
ciny committed Jul 24, 2019
1 parent 5eb0cdf commit 0943624
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 0 deletions.
137 changes: 137 additions & 0 deletions python/trezorlib/tests/device_tests/test_msg_recoverydevice_shamir.py
Expand Up @@ -221,3 +221,140 @@ def test_abort(self):
# check that the device is wiped
features = self.client.call_raw(proto.Initialize())
assert features.initialized is False

def test_warnings(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())

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

# Homescreen - but then bail out in the warning
assert isinstance(ret, proto.ButtonRequest)
self.client.debug.press_no()
ret = self.client.call_raw(proto.ButtonAck())

# Homescreen - click Enter
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 first share
assert ret == proto.ButtonRequest(code=proto.ButtonRequestType.MnemonicInput)
self.client.transport.write(proto.ButtonAck())
for word in mnemonics[0].split(" "):
time.sleep(1)
self.client.debug.input(word)
ret = self.client.transport.read()

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

for i in range(5):
assert ret == proto.ButtonRequest(
code=proto.ButtonRequestType.MnemonicInput
)
self.client.transport.write(proto.ButtonAck())
time.sleep(1)
if i == 0:
# enter first word wrong (different from previous share)
self.client.debug.input(mnemonics[0].split(" ")[-1])
elif i == 1:
# enter second word wrong (different from previous share)
self.client.debug.input(mnemonics[0].split(" ")[0])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[-1])
elif i == 2:
# enter third word wrong (different from previous share)
self.client.debug.input(mnemonics[0].split(" ")[0])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[1])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[-1])
elif i == 3:
# enter fourth word wrong (same as previous share)
self.client.debug.input(mnemonics[0].split(" ")[0])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[1])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[2])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[3])
elif i == 4:
# enter an invalid share
self.client.debug.input(mnemonics[0].split(" ")[0])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[1])
time.sleep(1)
self.client.debug.input(mnemonics[0].split(" ")[2])
time.sleep(1)
for _ in range(17):
self.client.debug.input("academic")
time.sleep(1)
ret = self.client.transport.read()

# Confirm warning message
assert isinstance(ret, proto.ButtonRequest)
assert ret == proto.ButtonRequest(proto.ButtonRequestType.Warning)
self.client.debug.press_yes()
ret = self.client.call_raw(proto.ButtonAck())

# TODO: do we want to do this? it will add 40s+ to testing time in case of 3of6
# enter rest of shares properly
mnemonics.pop(0)
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")
@@ -0,0 +1,81 @@
import time

import pytest

from trezorlib import debuglink, messages as proto

from .common import TrezorTest


@pytest.mark.skip_t1
# @pytest.mark.skip(reason="waiting for shamir load_device support")
class TestMsgRecoveryDeviceShamirDryRun(TrezorTest):
def test_2of3_dryrun(self):
# TODO: load device with these (or any other valid) mnemonics
mnemonics = [
"crush merchant academic acid dream decision orbit smug trend trust painting slice glad crunch veteran lunch friar satoshi engage aquatic",
"crush merchant academic agency devote eyebrow disaster island deploy flip toxic budget numerous airport loyalty fitness resident learn sympathy daughter",
"crush merchant academic always course verdict rescue paces fridge museum energy solution space ladybug junction national biology game fawn coal",
]
debuglink.load_device_by_mnemonic(
self.client,
mnemonic=mnemonics[0:2],
pin="",
passphrase_protection=True,
label="test",
language="english",
skip_checksum=True,
)

ret = self.client.call_raw(
proto.RecoveryDevice(
passphrase_protection=False,
pin_protection=False,
label="label",
language="english",
dry_run=True,
type=proto.ResetDeviceBackupType.Slip39_Single_Group,
)
)

# Confirm Dryrun
assert isinstance(ret, proto.ButtonRequest)
self.client.debug.press_yes()
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(20))
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())

# Check 2 of 3 shares
# TODO: check all shares when #276 is implemented
for mnemonic in mnemonics[1:3]:
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()

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

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

0 comments on commit 0943624

Please sign in to comment.