def sign_message(self, message, keypath): 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 if self.device.is_simulator: self.device.send_recv(CCProtocolPacker.sim_keypress(b'y')) 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}
def sign_tx(self, tx): self.device.check_mitm() # Get psbt in hex and then make binary fd = io.BytesIO(base64.b64decode(tx.serialize())) # learn size (portable way) offset = 0 sz = fd.seek(0, 2) fd.seek(0) left = sz chk = sha256() for pos in range(0, sz, MAX_BLK_LEN): here = fd.read(min(MAX_BLK_LEN, left)) if not here: break left -= len(here) result = self.device.send_recv( CCProtocolPacker.upload(pos, sz, here)) assert result == pos chk.update(here) # do a verify expect = chk.digest() result = self.device.send_recv(CCProtocolPacker.sha256()) assert len(result) == 32 if result != expect: raise ValueError("Wrong checksum:\nexpect: %s\n got: %s" % (b2a_hex(expect).decode('ascii'), b2a_hex(result).decode('ascii'))) # start the signing process ok = self.device.send_recv(CCProtocolPacker.sign_transaction( sz, expect), timeout=None) assert ok == None if self.device.is_simulator: self.device.send_recv(CCProtocolPacker.sim_keypress(b'y')) print("Waiting for OK on the Coldcard...") while 1: time.sleep(0.250) done = self.device.send_recv(CCProtocolPacker.get_signed_txn(), 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=1) return {'psbt': base64.b64encode(result).decode()}
def doit(k): if hasattr(dev.dev, 'pipe'): # simulator has special USB command dev.send_recv(CCProtocolPacker.sim_keypress(k.encode('ascii'))) elif request.config.getoption("--manual"): # need actual user interaction print("==> NOW, on the Coldcard, press key: %r" % k, file=sys.stderr) else: # try to use debug interface to simulate the press # XXX for some reason, picocom must **already** be running for this to work. # - otherwise, this locks up devs = list(glob.glob('/dev/tty.usbmodem*')) if len(devs) == 1: with open(devs[0], 'wb', 0) as fd: fd.write(k.encode('ascii')) else: raise pytest.fail('need to provide keypresses')
def display_address(self, keypath, p2sh_p2wpkh, bech32): self.device.check_mitm() keypath = keypath.replace('h', '\'') keypath = keypath.replace('H', '\'') if p2sh_p2wpkh: format = AF_P2WPKH_P2SH elif bech32: format = AF_P2WPKH else: format = AF_CLASSIC address = self.device.send_recv(CCProtocolPacker.show_address( keypath, format), timeout=None) if self.device.is_simulator: self.device.send_recv(CCProtocolPacker.sim_keypress(b'y')) return {'address': address}