From 7576a1ebd03e1d7e68bd1701b8bff8159230fe19 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 8 Dec 2021 09:55:37 +0100 Subject: add tooling for signing There's tools for key generation and conversion and there's tools for signing and verifying a tree leaf. Note that the leaf signing tools use the yet to be decided about SSH signing format, with message (ie signers checksum) being hashed with SHA-512 to match SSH tooling (ssh-keygen -Y). --- tools/sigsum-sign-leaf.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100755 tools/sigsum-sign-leaf.py (limited to 'tools/sigsum-sign-leaf.py') diff --git a/tools/sigsum-sign-leaf.py b/tools/sigsum-sign-leaf.py new file mode 100755 index 0000000..19d7f5c --- /dev/null +++ b/tools/sigsum-sign-leaf.py @@ -0,0 +1,61 @@ +#! /usr/bin/env python3 + +# Input: skeyfile shard_hint [checksum] +# Output: tree_leaf signature +# Example: echo foo | ./sigsum-sign-leaf.py nacl.sk 1633039200 +# be70f92465c27bf412008f26fa953d06899c53fa9867f40d9c0a1d657b188c9631699954728c719cf6b3819c1343c6e9e454cd9d519a9bf96dad3cf4cd959c0a + +import struct, sys, binascii +from base64 import b64encode +from nacl.signing import VerifyKey, SigningKey +from nacl.encoding import HexEncoder +from libsigntools import checksum_stdin, ssh_to_sign + +alg = 'sha512' + +def ssh_blob(vk, sig, namespace): + vkdata = struct.pack('!I11sI32s', + 11, bytes('ssh-ed25519', 'ascii'), + 32, vk.encode()) + assert(len(vkdata) == 51) + + assert(len(sig) == 64) + sigdata = struct.pack('!I11sI64s', + 11, bytes('ssh-ed25519', 'ascii'), + 64, sig) + assert(len(sigdata) == 83) + + s = "-----BEGIN SSH SIGNATURE-----\n" + b = b64encode(struct.pack('!6sII51sI{}sII6sI83s'.format(len(namespace)), + b'SSHSIG', + 1, + 51, vkdata, + len(namespace), bytes(namespace, 'ascii'), + 0, + 6, bytes(alg, 'ascii'), + 83, sigdata)).decode('ascii') + while len(b) > 0: + s += b[:72] + '\n' + b = b[72:] + s += "-----END SSH SIGNATURE-----\n" + return s + +def main(): + keyfile = sys.argv[1] + shard_hint = int(sys.argv[2]) + if len(sys.argv) > 3: + checksum = bytes.fromhex(sys.argv[3]) + else: + checksum = checksum_stdin(hashalg=alg) + + with open(keyfile, 'r') as f: + signing_key = SigningKey(f.readline().strip(), encoder=HexEncoder) + namespace = 'tree_leaf:v0:{}@sigsum.org'.format(shard_hint) + signature = signing_key.sign(ssh_to_sign(namespace, alg, checksum)).signature + + print(binascii.hexlify(signature).decode('ascii')) + if False: + print(ssh_blob(signing_key.verify_key, signature, namespace)) + +if __name__ == '__main__': + main() -- cgit v1.2.3