trezor-agent/trezor_agent/gpg/signer.py
2016-04-29 22:46:02 +03:00

80 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python
"""Create signatures and export public keys for GPG using TREZOR."""
import argparse
import logging
import subprocess as sp
import sys
import time
from . import check, decode, encode
log = logging.getLogger(__name__)
def _open_output(filename):
return sys.stdout if filename == '-' else open(filename, 'wb')
def _call_with_input(args, blob):
p = sp.Popen(args=args, stdin=sp.PIPE)
p.stdin.write(blob)
p.stdin.close()
exit_code = p.wait()
assert exit_code == 0, exit_code
def main():
"""Main function."""
p = argparse.ArgumentParser()
p.add_argument('user_id')
p.add_argument('filename', nargs='?')
p.add_argument('-t', '--time', type=int, default=int(time.time()))
p.add_argument('-a', '--armor', action='store_true', default=False)
p.add_argument('-v', '--verbose', action='store_true', default=False)
p.add_argument('-s', '--subkey', action='store_true', default=False)
p.add_argument('-e', '--ecdsa-curve', default='nist256p1')
p.add_argument('-o', '--output',
help='Output file name for the results. '
'Use "-" to write the results to stdout or "GPG" '
'to import a public key into the local keyring.')
args = p.parse_args()
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO,
format='%(asctime)s %(levelname)-10s %(message)s')
user_id = args.user_id.encode('ascii')
if not args.filename:
s = encode.Signer(user_id=user_id, created=args.time,
curve_name=args.ecdsa_curve)
if args.subkey:
pubkey = s.subkey()
else:
pubkey = s.export()
ext = '.pub'
if args.armor:
pubkey = encode.armor(pubkey, 'PUBLIC KEY BLOCK')
ext = '.asc'
filename = args.output or '-' # use stdout if no file specified
if filename == 'GPG':
log.info('importing public key to local keyring')
_call_with_input(['gpg2', '--import'], pubkey)
else:
_open_output(filename).write(pubkey)
else:
pubkey = decode.load_from_gpg(user_id)
s = encode.Signer.from_public_key(pubkey=pubkey, user_id=user_id)
data = open(args.filename, 'rb').read()
sig, ext = s.sign(data), '.sig'
if args.armor:
sig = encode.armor(sig, 'SIGNATURE')
ext = '.asc'
filename = args.output or (args.filename + ext)
_open_output(filename).write(sig)
check.verify(pubkey=pubkey, sig_file=filename)
s.close()
if __name__ == '__main__':
main()