From 54e7ffb6a57a05618965a3e14424514b1ebe3ca0 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Fri, 27 Jan 2023 11:53:06 +0200 Subject: [PATCH] Allow prehashing for Minisign support See https://github.com/jedisct1/minisign --- libagent/signify/__init__.py | 43 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/libagent/signify/__init__.py b/libagent/signify/__init__.py index f7ad7ab..aa0ab5d 100644 --- a/libagent/signify/__init__.py +++ b/libagent/signify/__init__.py @@ -1,4 +1,4 @@ -"""TREZOR support for Ed25519 signify signatures.""" +"""TREZOR support for Ed25519 signify/minisign signatures.""" import argparse import binascii @@ -53,10 +53,14 @@ class Client: return sig, pubkey[1:] -def format_payload(pubkey, data): +ALG_SIGNIFY = b'Ed' +ALG_MINISIGN = b'ED' # prehashes the data before signing + + +def format_payload(pubkey, data, sig_alg): """See http://www.openbsd.org/papers/bsdcan-signify.html for details.""" keynum = hashlib.sha256(pubkey).digest()[:8] - return binascii.b2a_base64(b"Ed" + keynum + data).decode("ascii") + return binascii.b2a_base64(sig_alg + keynum + data).decode("ascii") def run_pubkey(device_type, args): @@ -69,20 +73,33 @@ def run_pubkey(device_type, args): identity = _create_identity(user_id=args.user_id) pubkey = Client(device=device_type()).pubkey(identity=identity) comment = f'untrusted comment: identity {identity.to_string()}\n' - result = comment + format_payload(pubkey=pubkey, data=pubkey) - print(result, end="") + payload = format_payload(pubkey=pubkey, data=pubkey, sig_alg=ALG_SIGNIFY) + print(comment + payload, end="") def run_sign(device_type, args): - """Sign an input blob using Ed25519.""" + """Prehash & sign an input blob using Ed25519.""" util.setup_logging(verbosity=args.verbose) identity = _create_identity(user_id=args.user_id) - data = sys.stdin.buffer.read() - sig, pubkey = Client(device=device_type()).sign_with_pubkey(identity, data) - pubkey_str = format_payload(pubkey=pubkey, data=pubkey) - comment = f'untrusted comment: pubkey {pubkey_str}' - result = comment + format_payload(pubkey=pubkey, data=sig) - print(result, end="") + + data_to_sign = sys.stdin.buffer.read() + sig_alg = ALG_SIGNIFY + if args.prehash: + # See https://github.com/jedisct1/minisign/commit/6e1023d20758b6fdb2a4b697213b0bf608ba4020 + # Released in https://github.com/jedisct1/minisign/releases/tag/0.6 + sig_alg = ALG_MINISIGN + data_to_sign = hashlib.blake2b(data_to_sign).digest() + + sig, pubkey = Client(device=device_type()).sign_with_pubkey(identity, data_to_sign) + pubkey_str = format_payload(pubkey=pubkey, data=pubkey, sig_alg=sig_alg) + sig_str = format_payload(pubkey=pubkey, data=sig, sig_alg=sig_alg) + untrusted_comment = f'untrusted comment: pubkey {pubkey_str}' + print(untrusted_comment + sig_str, end="") + + comment_to_sign = sig + args.comment.encode() + sig, _ = Client(device=device_type()).sign_with_pubkey(identity, comment_to_sign) + sig_str = binascii.b2a_base64(sig).decode("ascii") + print(f'trusted comment: {args.comment}\n' + sig_str, end="") def main(device_type): @@ -100,6 +117,8 @@ def main(device_type): p = subparsers.add_parser('sign') p.add_argument('user_id') p.add_argument('-v', '--verbose', default=0, action='count') + p.add_argument('-c', '--comment', default=time.asctime()) + p.add_argument('-H', '--prehash', default=False, action='store_true') p.set_defaults(func=run_sign) args = parser.parse_args()