Implement signmessage for the Coldcard with a simple test
This commit is contained in:
parent
cd0dd7d529
commit
14a1345ad1
@ -110,6 +110,8 @@ def signmessage(args, client):
|
||||
return client.sign_message(args.message, args.path)
|
||||
except NotImplementedError as e:
|
||||
return {'error': str(e), 'code': NOT_IMPLEMENTED}
|
||||
except ValueError as e:
|
||||
return {'error': str(e), 'code': BAD_ARGUMENT}
|
||||
|
||||
def getkeypool(args, client):
|
||||
# args[0]; start index (e.g. 0)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
from ..hwwclient import HardwareWalletClient, UnavailableActionError
|
||||
from ckcc.client import ColdcardDevice, COINKITE_VID, CKCC_PID
|
||||
from ckcc.protocol import CCProtocolPacker
|
||||
from ckcc.protocol import CCProtocolPacker, CCProtoError
|
||||
from ckcc.constants import MAX_BLK_LEN, AF_P2WPKH, AF_CLASSIC, AF_P2WPKH_P2SH
|
||||
from ..base58 import xpub_main_2_test, get_xpub_fingerprint_hex
|
||||
from hashlib import sha256
|
||||
@ -95,7 +95,31 @@ class ColdcardClient(HardwareWalletClient):
|
||||
# Must return a base64 encoded string with the signed message
|
||||
# The message can be any string. keypath is the bip 32 derivation path for the key to sign with
|
||||
def sign_message(self, message, keypath):
|
||||
raise NotImplementedError('The Coldcard does not currently implement signmessage')
|
||||
self.device.check_mitm()
|
||||
keypath = keypath.replace('h', '\'')
|
||||
keypath = keypath.replace('H', '\'')
|
||||
|
||||
try:
|
||||
ok = self.device.send_recv(CCProtocolPacker.sign_message(message.encode(), keypath, AF_CLASSIC), timeout=None)
|
||||
assert ok == None
|
||||
except CCProtoError as e:
|
||||
raise ValueError(str(e))
|
||||
|
||||
while 1:
|
||||
time.sleep(0.250)
|
||||
done = self.device.send_recv(CCProtocolPacker.get_signed_msg(), timeout=None)
|
||||
if done == None:
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
if len(done) != 2:
|
||||
raise ValueError('Failed: %r' % done)
|
||||
|
||||
addr, raw = done
|
||||
|
||||
sig = str(base64.b64encode(raw), 'ascii').replace('\n', '')
|
||||
return {"signature": sig}
|
||||
|
||||
# Display address of specified type on the device. Only supports single-key based addresses.
|
||||
def display_address(self, keypath, p2sh_p2wpkh, bech32):
|
||||
|
||||
@ -10,7 +10,7 @@ import unittest
|
||||
from hwilib.commands import process_commands
|
||||
from ckcc.protocol import CCProtocolPacker
|
||||
from ckcc.client import ColdcardDevice
|
||||
from test_device import DeviceTestCase, start_bitcoind, TestDeviceConnect, TestDisplayAddress, TestGetKeypool, TestSignTx
|
||||
from test_device import DeviceTestCase, start_bitcoind, TestDeviceConnect, TestDisplayAddress, TestGetKeypool, TestSignMessage, TestSignTx
|
||||
|
||||
def coldcard_test_suite(simulator, rpc, userpass):
|
||||
# Start the Coldcard simulator
|
||||
@ -49,6 +49,7 @@ def coldcard_test_suite(simulator, rpc, userpass):
|
||||
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'))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestDisplayAddress, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd'))
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignMessage, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd'))
|
||||
# HACK: Skip this in headless simulator because it requires user input
|
||||
if not simulator.endswith('headless.py'):
|
||||
suite.addTest(DeviceTestCase.parameterize(TestSignTx, rpc, userpass, 'coldcard', '/tmp/ckcc-simulator.sock', '0f056943', 'tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd'))
|
||||
|
||||
@ -237,3 +237,8 @@ class TestDisplayAddress(DeviceTestCase):
|
||||
process_commands(self.dev_args + ['displayaddress', 'm/44h/1h/0h/0/0'])
|
||||
process_commands(self.dev_args + ['displayaddress', '--sh_wpkh', 'm/49h/1h/0h/0/0'])
|
||||
process_commands(self.dev_args + ['displayaddress', '--wpkh', 'm/84h/1h/0h/0/0'])
|
||||
|
||||
class TestSignMessage(DeviceTestCase):
|
||||
|
||||
def test_sign_msg(self):
|
||||
process_commands(self.dev_args + ['signmessage', 'Message signing test', 'm/44h/1h/0h/0/0'])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user