core/tools: make keyctl remote signing more resilient

pull/785/head
matejcik 4 years ago committed by Pavol Rusnak
parent 611b734d21
commit 8a5242ed0f
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -64,14 +64,15 @@ def process_remote_signers(fw, addrs: List[str]) -> Tuple[int, List[bytes]]:
digest = fw.digest() digest = fw.digest()
name = fw.NAME name = fw.NAME
def mkproxy(addr):
return Pyro4.Proxy(f"PYRO:keyctl@{addr}:{PORT}")
sigmask = 0 sigmask = 0
proxies = []
pks, Rs = [], [] pks, Rs = [], []
for addr in addrs: for addr in addrs:
click.echo(f"Connecting to {addr}...") click.echo(f"Connecting to {addr}...")
proxy = Pyro4.Proxy(f"PYRO:keyctl@{addr}:{PORT}") with mkproxy(addr) as proxy:
proxies.append((addr, proxy)) pk, R = proxy.get_commit(name, digest)
pk, R = proxy.get_commit(name, digest)
if pk not in fw.public_keys: if pk not in fw.public_keys:
raise click.ClickException( raise click.ClickException(
f"Signer at {addr} commits with unknown public key {pk.hex()}" f"Signer at {addr} commits with unknown public key {pk.hex()}"
@ -88,14 +89,16 @@ def process_remote_signers(fw, addrs: List[str]) -> Tuple[int, List[bytes]]:
# collect signatures # collect signatures
sigs = [] sigs = []
for addr, proxy in proxies: for addr in addrs:
click.echo(f"Waiting for {addr} to sign... ", nl=False) click.echo(f"Waiting for {addr} to sign... ", nl=False)
sig = proxy.get_signature(name, digest, global_R, global_pk) with mkproxy(addr) as proxy:
sig = proxy.get_signature(name, digest, global_R, global_pk)
sigs.append(sig) sigs.append(sig)
click.echo("OK") click.echo("OK")
for _, proxy in proxies: for addr in addrs:
proxy.finish() with mkproxy(addr) as proxy:
proxy.finish()
# compute global signature # compute global signature
return sigmask, cosi.combine_sig(global_R, sigs) return sigmask, cosi.combine_sig(global_R, sigs)

@ -75,6 +75,8 @@ class KeyctlProxy:
self.address_n = parse_path(PATH.format(image_type.BIP32_INDEX)) self.address_n = parse_path(PATH.format(image_type.BIP32_INDEX))
self.digest = digest self.digest = digest
self.commit = commit self.commit = commit
self.signature = None
self.global_params = None
def _check_name_digest(self, name, digest): def _check_name_digest(self, name, digest):
if name != self.name or digest != self.digest: if name != self.name or digest != self.digest:
@ -87,21 +89,29 @@ class KeyctlProxy:
click.echo("Sending commitment!") click.echo("Sending commitment!")
return self.commit return self.commit
def get_signature(self, name, digest, global_R, global_pk): def _make_signature(self, global_R, global_pk):
self._check_name_digest(name, digest)
while True: while True:
try: try:
click.echo("\n\n\nSigning...") click.echo("\n\n\nSigning...")
signature = cosi.sign( signature = cosi.sign(
TREZOR, self.address_n, digest, global_R, global_pk TREZOR, self.address_n, self.digest, global_R, global_pk
) )
click.echo("Sending signature!")
return signature.signature return signature.signature
except Exception as e: except Exception as e:
click.echo(e) click.echo(e)
traceback.print_exc() traceback.print_exc()
click.echo("Trying again ...") click.echo("Trying again ...")
def get_signature(self, name, digest, global_R, global_pk):
self._check_name_digest(name, digest)
global_params = global_R, global_pk
if global_params != self.global_params:
self.signature = self._make_signature(global_R, global_pk)
self.global_params = global_params
click.echo("Sending signature!")
return self.signature
@Pyro4.oneway @Pyro4.oneway
def finish(self): def finish(self):
click.echo("Done! \\(^o^)/") click.echo("Done! \\(^o^)/")

Loading…
Cancel
Save