Merge branch 'master' into python3

Conflicts:
	setup.py
nistp521
Roman Zeyde 8 years ago
commit ad8eafe6f8

@ -8,7 +8,8 @@ setup(
author='Roman Zeyde',
author_email='roman.zeyde@gmail.com',
url='http://github.com/romanz/trezor-agent',
packages=['trezor_agent'],
packages=['trezor_agent', 'trezor_agent.gpg'],
scripts=['trezor_agent/gpg/trezor-git-gpg-wrapper.sh'],
install_requires=['ecdsa>=0.13', 'ed25519>=1.4', 'Cython>=0.23.4', 'protobuf>=3.0.0b2.post2', 'trezor>=0.6.12', 'semver>=2.2'],
platforms=['POSIX'],
classifiers=[

@ -1,22 +1,56 @@
# Generate new stand-alone GPG identity
# Using TREZOR as hardware GPG agent
## Generate new GPG signing key:
First, verify that you have GPG 2.1+ [installed](https://gist.github.com/vt0r/a2f8c0bcb1400131ff51):
```
$ USER_ID="Satoshi Nakamoto <satoshi@nakamoto.bit>"
$ trezor-gpg create "${USER_ID}" > identity.pub # create new TREZOR-based GPG identity
$ gpg2 --import identity.pub # import into local GPG public keyring
$ gpg2 --edit "${USER_ID}" trust # OPTIONAL: mark the key as trusted
$ gpg2 --version | head -n1
gpg (GnuPG) 2.1.11
```
# Generate new subkey for existing GPG identity
Install the latest development version of `trezor-agent`:
```
$ USER_ID="Satoshi Nakamoto <satoshi@nakamoto.bit>"
$ gpg2 --list-keys "${USER_ID}" # make sure this identity already exists
$ trezor-gpg create --subkey "${USER_ID}" > identity.pub # create new TREZOR-based GPG public key
$ gpg2 --import identity.pub # append it to existing identity
$ pip install git+https://github.com/romanz/trezor-agent.git@master
```
# Generate signatures using the TREZOR device
Define your GPG user ID as an environment variable:
```
$ trezor-gpg sign EXAMPLE > EXAMPLE.sig # confirm signature using the device
$ gpg2 --verify EXAMPLE.sig # verify using standard GPG binary
$ export TREZOR_GPG_USER_ID="John Doe <john@doe.bit>"
```
There are two ways to generate TREZOR-based GPG public keys, as described below.
### (1) create new GPG identity:
```
$ trezor-gpg create > identity.pub # create new TREZOR-based GPG identity
$ gpg2 --import identity.pub # import into local GPG public keyring
$ gpg2 --list-keys # verify that the new identity is created correctly
$ gpg2 --edit "${TREZOR_GPG_USER_ID}" trust # OPTIONAL: mark the key as trusted
```
[![asciicast](https://asciinema.org/a/44880.png)](https://asciinema.org/a/44880)
### (2) create new subkey for an existing GPG identity:
```
$ gpg2 --list-keys "${TREZOR_GPG_USER_ID}" # make sure this identity already exists
$ trezor-gpg create --subkey > identity.pub # create new TREZOR-based GPG subkey
$ gpg2 --import identity.pub # append it to an existing identity
$ gpg2 --list-keys "${TREZOR_GPG_USER_ID}" # verify that the new subkey is added to keyring
```
[![subkey](https://asciinema.org/a/8t78s6pqo5yocisaiolqnjp63.png)](https://asciinema.org/a/8t78s6pqo5yocisaiolqnjp63)
## Generate GPG signatures using a TREZOR device:
```
$ trezor-gpg sign EXAMPLE # confirm signature using the device
$ gpg2 --verify EXAMPLE.asc # verify using standard GPG binary
```
[![sign](https://asciinema.org/a/f1unkptesb7anq09i8wugoko6.png)](https://asciinema.org/a/f1unkptesb7anq09i8wugoko6)
## Git commit & tag signatures:
Git can use GPG to sign and verify commits and tags (see [here](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)):
```
$ git config --local gpg.program "trezor-git-gpg-wrapper.sh"
$ git commit --gpg-sign # create GPG-signed commit
$ git log --show-signature -1 # verify commit signature
$ git tag --sign "TAG" # create GPG-signed tag
$ git verify-tag "TAG" # verify tag signature
```
[![asciicast](https://asciinema.org/a/44879.png)](https://asciinema.org/a/44879)

@ -123,10 +123,11 @@ def sign(sock, keygrip, digest):
line = _unescape(line)
log.debug('line: %r', line)
prefix, sig = line.split(' ', 1)
assert prefix == 'D'
if prefix != 'D':
raise ValueError(line)
sig, leftover = _parse(sig)
assert not leftover
assert not leftover, leftover
return _parse_sig(sig)

@ -1,43 +0,0 @@
#!/usr/bin/env python
"""Check GPG v2 signature for a given public key."""
import argparse
import logging
from . import decode
from .. import util
log = logging.getLogger(__name__)
def main():
"""Main function."""
p = argparse.ArgumentParser()
p.add_argument('pubkey')
p.add_argument('-v', '--verbose', action='store_true', default=False)
args = p.parse_args()
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO,
format='%(asctime)s %(levelname)-10s %(message)s')
stream = open(args.pubkey, 'rb')
parser = decode.parse_packets(util.Reader(stream))
pubkey, userid, sig1, subkey, sig2 = parser
digest = decode.digest_packets([pubkey, userid, sig1])
assert sig1['hash_prefix'] == digest[:2]
decode.verify_digest(
pubkey=pubkey, digest=digest,
signature=sig1['sig'], label='GPG public key (self sig)')
digest = decode.digest_packets([pubkey, subkey, sig2])
assert sig2['hash_prefix'] == digest[:2]
decode.verify_digest(
pubkey=pubkey, digest=digest,
signature=sig2['sig'], label='GPG subkey (1st sig)')
sig3, = sig2['embedded']
digest = decode.digest_packets([pubkey, subkey, sig3])
decode.verify_digest(
pubkey=subkey, digest=digest,
signature=sig3['sig'], label='GPG subkey (2nd sig)')
if __name__ == '__main__':
main()

@ -1,19 +0,0 @@
#!/bin/bash
set -x
CREATED=1460731897 # needed for consistent public key creation
NAME="trezor_demo" # will be used as GPG user id and public key name
echo "Hello GPG World!" > EXAMPLE
# Create, sign and export the public key
trezor-gpg $NAME --time $CREATED -o $NAME.pub
# Install GPG v2.1 (modern) and import the public key
gpg2 --import $NAME.pub
gpg2 --list-keys $NAME
# gpg2 --edit-key $NAME trust # optional: mark it as trusted
# Perform actual GPG signature using TREZOR device
trezor-gpg $NAME EXAMPLE
# Verify signature using GPG2 binary
gpg2 --verify EXAMPLE.sig

@ -251,7 +251,7 @@ def _make_signature(signer_func, data_to_sign, public_algo,
log.debug('hashing %d bytes', len(data_to_hash))
digest = hashlib.sha256(data_to_hash).digest()
log.info('SHA256 digest to sign: %s', util.hexlify(digest))
log.info('signing digest: %s', util.hexlify(digest))
sig = signer_func(digest=digest)
return bytes(header + hashed + unhashed +

@ -1,35 +0,0 @@
#!/usr/bin/env python
"""A simple wrapper for Git commit/tag GPG signing."""
import logging
import subprocess as sp
import sys
from . import decode, encode
log = logging.getLogger(__name__)
def main():
"""Main function."""
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)-10s %(message)s')
log.debug('sys.argv: %s', sys.argv)
args = sys.argv[1:]
if '--verify' in args:
return sp.call(['gpg2'] + args)
else:
command = args[0]
user_id = ' '.join(args[1:])
assert command == '-bsau' # --detach-sign --sign --armor --local-user
pubkey = decode.load_from_gpg(user_id, use_custom=True)
s = encode.Signer.from_public_key(user_id=user_id, pubkey=pubkey)
data = sys.stdin.read()
sig = s.sign(data)
sig = encode.armor(sig, 'SIGNATURE')
sys.stdout.write(sig)
s.close()
if __name__ == '__main__':
main()

@ -5,6 +5,7 @@ import logging
import subprocess as sp
import sys
import time
import os
from . import decode, encode
@ -13,17 +14,18 @@ log = logging.getLogger(__name__)
def run_create(args):
"""Generate a new pubkey for a new/existing GPG identity."""
s = encode.Signer(user_id=args.user_id, created=args.time,
user_id = os.environ['TREZOR_GPG_USER_ID']
s = encode.Signer(user_id=user_id, created=args.time,
curve_name=args.ecdsa_curve)
if args.subkey:
subkey = s.subkey()
primary = sp.check_output(['gpg2', '--export', args.user_id])
primary = sp.check_output(['gpg2', '--export', user_id])
result = primary + subkey
else:
result = s.export()
s.close()
return encode.armor(result, 'PUBLIC KEY BLOCK')
sys.stdout.write(encode.armor(result, 'PUBLIC KEY BLOCK'))
def run_sign(args):
@ -39,7 +41,19 @@ def run_sign(args):
sig = encode.armor(sig, 'SIGNATURE')
decode.verify(pubkey=pubkey, signature=sig, original_data=data)
return sig
filename = '-' # write to stdout
if args.output:
filename = args.output
elif args.filename:
filename = args.filename + '.asc'
if filename == '-':
output = sys.stdout
else:
output = open(filename, 'wb')
output.write(sig)
def main():
@ -49,8 +63,6 @@ def main():
subparsers = p.add_subparsers()
create = subparsers.add_parser('create')
create.add_argument('user_id', help='e.g. '
'"Satoshi Nakamoto <satoshi@nakamoto.bit>"')
create.add_argument('-s', '--subkey', action='store_true', default=False)
create.add_argument('-e', '--ecdsa-curve', default='nist256p1')
create.add_argument('-t', '--time', type=int, default=int(time.time()))
@ -58,13 +70,13 @@ def main():
sign = subparsers.add_parser('sign')
sign.add_argument('filename', nargs='?')
sign.add_argument('-o', '--output', default=None)
sign.set_defaults(run=run_sign)
args = p.parse_args()
logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO,
format='%(asctime)s %(levelname)-10s %(message)s')
result = args.run(args)
sys.stdout.write(result)
args.run(args)
if __name__ == '__main__':

@ -1,16 +0,0 @@
# NEVER RUN ON YOUR OWN REAL GPG KEYS!!!!! THEY WILL BE DELETED!!!!!
set -x -e -u
CURVE=ed25519
#CURVE=nist256p1
(cd ~/.gnupg && rm -rf openpgp-revocs.d/ private-keys-v1.d/ pubring.kbx* trustdb.gpg /tmp/log *.gpg; killall gpg-agent || true)
gpg2 --full-gen-key --expert
gpg2 --export > romanz.pub
NOW=`date +%s`
USERID="Roman Zeyde <roman.zeyde@gmail.com>"
trezor-gpg -t $NOW -e $CURVE --subkey "$USERID" -o subkey.pub
gpg2 -K
gpg2 -v --import <(cat romanz.pub subkey.pub)
gpg2 -K
trezor-gpg -t $NOW -e $CURVE "$USERID" EXAMPLE
gpg2 --verify EXAMPLE.sig

@ -3,5 +3,5 @@ if [[ "$*" == *"--verify"* ]]
then
gpg2 $* # verify using GPG2 (for ECDSA and EdDSA keys)
else
python -m trezor_agent.gpg.git_wrapper $* # sign using TREZOR
trezor-gpg sign -o- # sign using TREZOR and write the signature to stdout
fi

Loading…
Cancel
Save