parent
5ede6864d5
commit
81ff60c3e1
@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
TOOLDIR=$(dirname $0)
|
||||
|
||||
TYPE=$1
|
||||
FILE=$2
|
||||
shift
|
||||
shift
|
||||
SECKEYS=$*
|
||||
|
||||
COMMITS=""
|
||||
|
||||
for seckey in $SECKEYS; do
|
||||
commit=$( $TOOLDIR/keyctl commit $TYPE $FILE $seckey )
|
||||
COMMITS="$COMMITS $commit"
|
||||
done
|
||||
|
||||
global_commit=$( $TOOLDIR/keyctl global_commit $COMMITS )
|
||||
|
||||
SIGS=""
|
||||
|
||||
for seckey in $SECKEYS; do
|
||||
sig=$( $TOOLDIR/keyctl sign $TYPE $FILE $global_commit $seckey )
|
||||
SIGS="$SIGS $sig"
|
||||
done
|
||||
|
||||
$TOOLDIR/keyctl global_sign $TYPE $FILE $global_commit $SIGS
|
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
import binascii
|
||||
import struct
|
||||
import click
|
||||
import pyblake2
|
||||
import Pyro4
|
||||
import serpent
|
||||
from trezorlib import ed25519raw, ed25519cosi
|
||||
|
||||
PORT = 5001
|
||||
indexmap = {
|
||||
'bootloader': 0,
|
||||
'vendorheader': 1,
|
||||
'firmware': 2,
|
||||
}
|
||||
|
||||
|
||||
def header_digest(index, filename):
|
||||
data = open(filename, 'rb').read()
|
||||
z = bytes(65 * [0x00])
|
||||
if index == 'bootloader':
|
||||
header = data[:0x03BF] + z
|
||||
elif index == 'vendorheader':
|
||||
header = data[:-65] + z
|
||||
elif index == 'firmware':
|
||||
vhdrlen = struct.unpack('<I', data[4:8])[0]
|
||||
header = data[vhdrlen:vhdrlen + 0x03BF] + z
|
||||
else:
|
||||
raise ValueError('Unknown index "%s"' % index)
|
||||
return pyblake2.blake2s(header).digest()
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli():
|
||||
pass
|
||||
|
||||
|
||||
@cli.command(help='')
|
||||
@click.argument('index', type=click.Choice(indexmap.keys()))
|
||||
@click.argument('filename')
|
||||
@click.argument('participants', nargs=-1)
|
||||
def sign(index, filename, participants):
|
||||
# compute header digest
|
||||
digest = header_digest(index, filename)
|
||||
# create participant proxies
|
||||
if len(participants) < 1:
|
||||
raise ValueError('Not enough participants')
|
||||
print('connecting to %d participants:' % len(participants))
|
||||
proxy = []
|
||||
for p in participants:
|
||||
uri = 'PYRO:keyctl@%s:%d' % (p, PORT)
|
||||
proxy.append(Pyro4.Proxy(uri))
|
||||
# collect commits
|
||||
pks, Rs = [], []
|
||||
for p in proxy:
|
||||
pk, R = p.get_commit(index, digest)
|
||||
pk, R = serpent.tobytes(pk), serpent.tobytes(R)
|
||||
pks.append(pk)
|
||||
Rs.append(R)
|
||||
# compute global commit
|
||||
global_pk = ed25519cosi.combine_keys(pks)
|
||||
global_R = ed25519cosi.combine_keys(Rs)
|
||||
# collect signatures
|
||||
sigs = []
|
||||
for p in proxy:
|
||||
sig = p.get_signature(index, digest, global_R, global_pk)
|
||||
sig = serpent.tobytes(sig)
|
||||
sigs.append(sig)
|
||||
# compute global signature
|
||||
sig = ed25519cosi.combine_sig(global_R, sigs)
|
||||
ed25519raw.checkvalid(sig, digest, global_pk)
|
||||
print(binascii.hexlify(sig).decode())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
import binascii
|
||||
import sys
|
||||
import netifaces
|
||||
import Pyro4
|
||||
import serpent
|
||||
|
||||
PORT = 5001
|
||||
indexmap = {
|
||||
'bootloader': 0,
|
||||
'vendorheader': 1,
|
||||
'firmware': 2,
|
||||
}
|
||||
|
||||
|
||||
def get_trezor():
|
||||
from trezorlib.client import TrezorClient
|
||||
from trezorlib.transport_hid import HidTransport
|
||||
devices = HidTransport.enumerate()
|
||||
if len(devices) > 0:
|
||||
return TrezorClient(devices[0])
|
||||
else:
|
||||
raise Exception('No TREZOR found')
|
||||
|
||||
|
||||
def get_path(index):
|
||||
return "10018'/%d'" % indexmap[index]
|
||||
|
||||
|
||||
@Pyro4.expose
|
||||
class KeyctlProxy(object):
|
||||
|
||||
def __init__(self):
|
||||
super(KeyctlProxy, self).__init__()
|
||||
|
||||
def get_commit(self, index, digest):
|
||||
digest = serpent.tobytes(digest)
|
||||
t = get_trezor()
|
||||
path = get_path(index)
|
||||
print('commiting to hash %s with path %s' % (binascii.hexlify(digest).decode(), path))
|
||||
commit = t.cosi_commit(t.expand_path(path), digest)
|
||||
pk = commit.pubkey
|
||||
R = commit.commitment
|
||||
return (pk, R)
|
||||
|
||||
def get_signature(self, index, digest, global_R, global_pk):
|
||||
digest, global_R, global_pk = serpent.tobytes(digest), serpent.tobytes(global_R), serpent.tobytes(global_pk)
|
||||
t = get_trezor()
|
||||
path = get_path(index)
|
||||
print('signing hash %s with path %s' % (binascii.hexlify(digest).decode(), path))
|
||||
signature = t.cosi_sign(t.expand_path(path), digest, global_R, global_pk)
|
||||
sig = signature.signature
|
||||
return sig
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 1:
|
||||
iface = sys.argv[1]
|
||||
else:
|
||||
print('Usage: keyctl-proxy interface')
|
||||
sys.exit(1)
|
||||
host = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr']
|
||||
daemon = Pyro4.Daemon(host=host, port=PORT)
|
||||
proxy = KeyctlProxy()
|
||||
uri = daemon.register(proxy, 'keyctl')
|
||||
print('keyctl-proxy running at URI: "%s"' % uri)
|
||||
daemon.requestLoop()
|
Loading…
Reference in new issue