2016-04-16 18:21:12 +00:00
|
|
|
#!/usr/bin/env python
|
2016-04-24 10:04:53 +00:00
|
|
|
"""Create signatures and export public keys for GPG using TREZOR."""
|
2016-04-16 18:21:12 +00:00
|
|
|
import argparse
|
2016-05-21 14:21:16 +00:00
|
|
|
import contextlib
|
2016-04-16 18:21:12 +00:00
|
|
|
import logging
|
2016-05-28 20:02:45 +00:00
|
|
|
import os
|
2016-04-24 11:23:16 +00:00
|
|
|
import sys
|
2016-04-16 18:21:12 +00:00
|
|
|
import time
|
|
|
|
|
2016-07-26 16:37:42 +00:00
|
|
|
from . import agent, encode, keyring, protocol
|
2016-06-04 06:36:48 +00:00
|
|
|
from .. import server
|
2016-04-16 18:21:12 +00:00
|
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2016-05-06 19:16:03 +00:00
|
|
|
def run_create(args):
|
|
|
|
"""Generate a new pubkey for a new/existing GPG identity."""
|
2016-05-07 06:41:58 +00:00
|
|
|
user_id = os.environ['TREZOR_GPG_USER_ID']
|
2016-08-15 18:39:34 +00:00
|
|
|
log.warning('NOTE: in order to re-generate the exact same GPG key later, '
|
|
|
|
'run this command with "--time=%d" commandline flag (to set '
|
|
|
|
'the timestamp of the GPG key manually).', args.time)
|
2016-06-11 11:38:11 +00:00
|
|
|
conn = encode.HardwareSigner(user_id=user_id,
|
|
|
|
curve_name=args.ecdsa_curve)
|
2016-06-17 06:34:05 +00:00
|
|
|
verifying_key = conn.pubkey(ecdh=False)
|
|
|
|
decryption_key = conn.pubkey(ecdh=True)
|
2016-05-21 14:21:16 +00:00
|
|
|
|
2016-06-11 11:38:11 +00:00
|
|
|
if args.subkey:
|
|
|
|
primary_bytes = keyring.export_public_key(user_id=user_id)
|
|
|
|
# subkey for signing
|
2016-07-26 16:37:42 +00:00
|
|
|
signing_key = protocol.PublicKey(
|
2016-06-11 11:38:11 +00:00
|
|
|
curve_name=args.ecdsa_curve, created=args.time,
|
|
|
|
verifying_key=verifying_key, ecdh=False)
|
|
|
|
# subkey for encryption
|
2016-07-26 16:37:42 +00:00
|
|
|
encryption_key = protocol.PublicKey(
|
2016-06-11 11:38:11 +00:00
|
|
|
curve_name=args.ecdsa_curve, created=args.time,
|
2016-06-17 06:34:05 +00:00
|
|
|
verifying_key=decryption_key, ecdh=True)
|
2016-06-11 11:38:11 +00:00
|
|
|
result = encode.create_subkey(primary_bytes=primary_bytes,
|
|
|
|
pubkey=signing_key,
|
|
|
|
signer_func=conn.sign)
|
|
|
|
result = encode.create_subkey(primary_bytes=result,
|
|
|
|
pubkey=encryption_key,
|
|
|
|
signer_func=conn.sign)
|
|
|
|
else:
|
|
|
|
# primary key for signing
|
2016-07-26 16:37:42 +00:00
|
|
|
primary = protocol.PublicKey(
|
2016-06-11 11:38:11 +00:00
|
|
|
curve_name=args.ecdsa_curve, created=args.time,
|
|
|
|
verifying_key=verifying_key, ecdh=False)
|
|
|
|
# subkey for encryption
|
2016-07-26 16:37:42 +00:00
|
|
|
subkey = protocol.PublicKey(
|
2016-06-11 11:38:11 +00:00
|
|
|
curve_name=args.ecdsa_curve, created=args.time,
|
2016-06-17 06:34:05 +00:00
|
|
|
verifying_key=decryption_key, ecdh=True)
|
2016-06-11 11:38:11 +00:00
|
|
|
|
|
|
|
result = encode.create_primary(user_id=user_id,
|
|
|
|
pubkey=primary,
|
|
|
|
signer_func=conn.sign)
|
|
|
|
result = encode.create_subkey(primary_bytes=result,
|
|
|
|
pubkey=subkey,
|
|
|
|
signer_func=conn.sign)
|
2016-05-06 19:16:03 +00:00
|
|
|
|
2016-07-26 16:37:42 +00:00
|
|
|
sys.stdout.write(protocol.armor(result, 'PUBLIC KEY BLOCK'))
|
2016-05-06 19:16:03 +00:00
|
|
|
|
2016-04-24 11:23:16 +00:00
|
|
|
|
2016-08-15 18:51:32 +00:00
|
|
|
def run_agent(args): # pylint: disable=unused-argument
|
2016-06-04 06:36:48 +00:00
|
|
|
"""Run a simple GPG-agent server."""
|
2016-08-15 18:51:32 +00:00
|
|
|
sock_path = keyring.get_agent_sock_path()
|
2016-06-04 06:36:48 +00:00
|
|
|
with server.unix_domain_socket_server(sock_path) as sock:
|
|
|
|
for conn in agent.yield_connections(sock):
|
|
|
|
with contextlib.closing(conn):
|
|
|
|
agent.handle_connection(conn)
|
|
|
|
|
|
|
|
|
2016-04-16 18:21:12 +00:00
|
|
|
def main():
|
2016-04-24 09:22:02 +00:00
|
|
|
"""Main function."""
|
2016-04-16 18:21:12 +00:00
|
|
|
p = argparse.ArgumentParser()
|
|
|
|
p.add_argument('-v', '--verbose', action='store_true', default=False)
|
2016-05-06 19:16:03 +00:00
|
|
|
subparsers = p.add_subparsers()
|
2016-05-22 19:28:07 +00:00
|
|
|
subparsers.required = True
|
|
|
|
subparsers.dest = 'command'
|
2016-05-06 19:16:03 +00:00
|
|
|
|
2016-06-04 06:36:48 +00:00
|
|
|
create_cmd = subparsers.add_parser('create')
|
|
|
|
create_cmd.add_argument('-s', '--subkey', action='store_true', default=False)
|
|
|
|
create_cmd.add_argument('-e', '--ecdsa-curve', default='nist256p1')
|
|
|
|
create_cmd.add_argument('-t', '--time', type=int, default=int(time.time()))
|
|
|
|
create_cmd.set_defaults(run=run_create)
|
|
|
|
|
|
|
|
agent_cmd = subparsers.add_parser('agent')
|
|
|
|
agent_cmd.set_defaults(run=run_agent)
|
2016-05-06 19:16:03 +00:00
|
|
|
|
2016-04-16 18:21:12 +00:00
|
|
|
args = p.parse_args()
|
|
|
|
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO,
|
|
|
|
format='%(asctime)s %(levelname)-10s %(message)s')
|
2016-05-07 06:41:58 +00:00
|
|
|
args.run(args)
|
2016-04-16 18:21:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|