Implement setup, wipe, restore, and backup for Coldcard with tests

The Coldcard does not support setup, wipe, and restore via software, so just
raise errors for those.

Backup is supported, so implemented.
This commit is contained in:
Andrew Chow 2018-12-29 00:10:48 -05:00
parent ca17a85e7d
commit 6641c244f0
2 changed files with 42 additions and 5 deletions

View File

@ -1,6 +1,6 @@
# Trezor interaction script
from ..hwwclient import HardwareWalletClient
from ..hwwclient import HardwareWalletClient, UnavailableActionError
from ckcc.client import ColdcardDevice, COINKITE_VID, CKCC_PID
from ckcc.protocol import CCProtocolPacker
from ckcc.constants import MAX_BLK_LEN
@ -102,19 +102,39 @@ class ColdcardClient(HardwareWalletClient):
# Setup a new device
def setup_device(self, label='', passphrase=''):
raise NotImplementedError('The Coldcard does not currently implement setup')
raise UnavailableActionError('The Coldcard does not support software setup')
# Wipe this device
def wipe_device(self):
raise NotImplementedError('The Coldcard does not currently implement wipe')
raise UnavailableActionError('The Coldcard does not support wiping via software')
# Restore device from mnemonic or xprv
def restore_device(self, label=''):
raise NotImplementedError('The Coldcard does not implement device restoring')
raise UnavailableActionError('The Coldcard does not support restoring via software')
# Begin backup process
def backup_device(self, label='', passphrase=''):
raise NotImplementedError('The Coldcard does not implement this method')
self.device.check_mitm()
ok = self.device.send_recv(CCProtocolPacker.start_backup())
assert ok == None
while 1:
time.sleep(0.250)
done = self.device.send_recv(CCProtocolPacker.get_backup_file(), timeout=None)
if done == None:
continue
break
if len(done) != 2:
raise ValueError('Failed: %r' % done)
result_len, result_sha = done
result = self.device.download_file(result_len, result_sha, file_number=0)
filename = time.strftime('backup-%Y%m%d-%H%M.7z')
open(filename, 'wb').write(result)
return {'success': True, 'message': 'The backup has be written to {}'.format(filename)}
# Close the device
def close(self):

View File

@ -27,8 +27,25 @@ def coldcard_test_suite(simulator, rpc, userpass):
resp = dev.send_recv(CCProtocolPacker.logout())
atexit.register(cleanup_simulator)
# Coldcard specific setup and wipe tests
class TestColdcardSetupWipe(DeviceTestCase):
def test_setup(self):
result = process_commands(self.dev_args + ['setup'])
self.assertIn('error', result)
self.assertIn('code', result)
self.assertEqual(result['error'], 'The Coldcard does not support software setup')
self.assertEqual(result['code'], -9)
def test_wipe(self):
result = process_commands(self.dev_args + ['wipe'])
self.assertIn('error', result)
self.assertIn('code', result)
self.assertEqual(result['error'], 'The Coldcard does not support wiping via software')
self.assertEqual(result['code'], -9)
# Generic device tests
suite = unittest.TestSuite()
suite.addTest(DeviceTestCase.parameterize(TestColdcardSetupWipe, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', ''))
suite.addTest(DeviceTestCase.parameterize(TestDeviceConnect, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd'))
suite.addTest(DeviceTestCase.parameterize(TestGetKeypool, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd'))
# HACK: Skip this in headless simulator because it requires user input