From 016e8645034c7dadf9b8cf0b44b6c7389c0ed884 Mon Sep 17 00:00:00 2001 From: Nicolas Pouillard Date: Mon, 5 Sep 2016 23:47:01 +0200 Subject: [PATCH 01/15] Attempt at fixing issue #32 --- trezor_agent/gpg/protocol.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/trezor_agent/gpg/protocol.py b/trezor_agent/gpg/protocol.py index e0f0709..4785bbc 100644 --- a/trezor_agent/gpg/protocol.py +++ b/trezor_agent/gpg/protocol.py @@ -47,9 +47,22 @@ def subpacket_byte(subpacket_type, value): return subpacket(subpacket_type, '>B', value) +def subpacket_prefix_len(blob): + """Prefix GPG subpacket with the encoding of it's length.""" + if len(blob) < 2**8: + length_type = 0 + elif len(blob) < 2**16: + length_type = 1 + else: + length_type = 2 + fmt = ['>B', '>H', '>L'][length_type] + prefix = [b'', b'', struct.pack('>B', 255)][length_type] + return prefix + struct.pack(fmt, len(blob)) + blob + + def subpackets(*items): """Serialize several GPG subpackets.""" - prefixed = [util.prefix_len('>B', item) for item in items] + prefixed = [subpacket_prefix_len(item) for item in items] return util.prefix_len('>H', b''.join(prefixed)) From 17c8bd0e923fac3fe04408eadcfe526fd525cbe3 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sun, 11 Sep 2016 23:06:47 +0300 Subject: [PATCH 02/15] gpg: add experimental warning --- trezor_agent/gpg/__main__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/trezor_agent/gpg/__main__.py b/trezor_agent/gpg/__main__.py index dd50309..6dbee00 100755 --- a/trezor_agent/gpg/__main__.py +++ b/trezor_agent/gpg/__main__.py @@ -89,6 +89,9 @@ def main(): args = p.parse_args() logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO, format='%(asctime)s %(levelname)-10s %(message)s') + log.warning('This GPG tool is still in EXPERIMENTAL mode, ' + 'so please note that the API and features may ' + 'change without backwards compatibility!') args.run(args) From 5c5c6f9cbb17f09ff115a296c991bd82b10e9f4b Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sun, 11 Sep 2016 23:08:11 +0300 Subject: [PATCH 03/15] bump version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f131768..73746fc 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup setup( name='trezor_agent', - version='0.6.5', + version='0.6.6', description='Using Trezor as hardware SSH agent', author='Roman Zeyde', author_email='roman.zeyde@gmail.com', From 23c37cf1e3df3e437e653569f3caf6fe7cf7ed18 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sun, 11 Sep 2016 23:17:47 +0300 Subject: [PATCH 04/15] README: update TREZOR's required version --- README-SSH.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README-SSH.md b/README-SSH.md index 71f5de8..5731113 100644 --- a/README-SSH.md +++ b/README-SSH.md @@ -21,13 +21,13 @@ Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agen $ pip install trezor_agent -Finally, verify that you are running the latest [TREZOR firmware](https://mytrezor.com/data/firmware/releases.json) version (at least v1.3.4): +Finally, verify that you are running the latest [TREZOR firmware](https://mytrezor.com/data/firmware/releases.json) version (at least v1.4.0): $ trezorctl get_features vendor: "bitcointrezor.com" major_version: 1 - minor_version: 3 - patch_version: 4 + minor_version: 4 + patch_version: 0 ... # Public key generation From 282e91ace3a14f16b3e82d1cbb07798736742a3a Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sun, 11 Sep 2016 23:21:58 +0300 Subject: [PATCH 05/15] update README about protobuf issueOF --- README-SSH.md | 21 --------------------- README.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/README-SSH.md b/README-SSH.md index 5731113..97807ea 100644 --- a/README-SSH.md +++ b/README-SSH.md @@ -9,27 +9,6 @@ ## Using for GitHub SSH authentication (via `trezor-git` utility) [![GitHub](https://asciinema.org/a/38337.png)](https://asciinema.org/a/38337) -# Installation - -First, make sure that the latest [trezorlib](https://pypi.python.org/pypi/trezor) Python package -is installed correctly (at least v0.6.6): - - $ apt-get install python-dev libusb-1.0-0-dev libudev-dev - $ pip install Cython trezor - -Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agent) package: - - $ pip install trezor_agent - -Finally, verify that you are running the latest [TREZOR firmware](https://mytrezor.com/data/firmware/releases.json) version (at least v1.4.0): - - $ trezorctl get_features - vendor: "bitcointrezor.com" - major_version: 1 - minor_version: 4 - patch_version: 0 - ... - # Public key generation Run: diff --git a/README.md b/README.md index 35af86c..c53d50c 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,36 @@ See SatoshiLabs' blog posts about this feature: - [TREZOR Firmware 1.3.4 enables SSH login](https://medium.com/@satoshilabs/trezor-firmware-1-3-4-enables-ssh-login-86a622d7e609) - [TREZOR Firmware 1.3.6 — GPG Signing, SSH Login Updates and Advanced Transaction Features for Segwit](https://medium.com/@satoshilabs/trezor-firmware-1-3-6-20a7df6e692) +## Installation + +First, make sure that the latest [trezorlib](https://pypi.python.org/pypi/trezor) Python package +is installed correctly (at least v0.6.6): + + $ apt-get install python-dev libusb-1.0-0-dev libudev-dev + $ pip install Cython trezor + +Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agent) package: + + $ pip install trezor_agent + +Finally, verify that you are running the latest [TREZOR firmware](https://mytrezor.com/data/firmware/releases.json) version (at least v1.4.0): + + $ trezorctl get_features + vendor: "bitcointrezor.com" + major_version: 1 + minor_version: 4 + patch_version: 0 + ... + +## Usage + For usage with SSH, see the [following instructions](README-SSH.md). For usage with GPG, see the [following instructions](README-GPG.md). Questions, suggestions and discussions are welcome: [![Chat](https://badges.gitter.im/romanz/trezor-agent.svg)](https://gitter.im/romanz/trezor-agent) + +## Troubleshooting + +If there is an import problem with the installed `protobuf` package, +see [this issue](https://github.com/romanz/trezor-agent/issues/28) for fixing it. From d408a592aa0fe3ca89579cde76d69828dcaa6168 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sun, 11 Sep 2016 23:35:10 +0300 Subject: [PATCH 06/15] README: get only the first lines of 'trezorctl get_features' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c53d50c..39a0ea5 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agen Finally, verify that you are running the latest [TREZOR firmware](https://mytrezor.com/data/firmware/releases.json) version (at least v1.4.0): - $ trezorctl get_features + $ trezorctl get_features | head vendor: "bitcointrezor.com" major_version: 1 minor_version: 4 From 998c9ee9588bc5f68e29494367177d94160506d1 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Sun, 11 Sep 2016 23:38:21 +0300 Subject: [PATCH 07/15] README: update usage section --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 39a0ea5..639f78b 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,9 @@ Finally, verify that you are running the latest [TREZOR firmware](https://mytrez ## Usage -For usage with SSH, see the [following instructions](README-SSH.md). +For SSH, see the [following instructions](README-SSH.md). -For usage with GPG, see the [following instructions](README-GPG.md). +For GPG, see the [following instructions](README-GPG.md). Questions, suggestions and discussions are welcome: [![Chat](https://badges.gitter.im/romanz/trezor-agent.svg)](https://gitter.im/romanz/trezor-agent) From bf598435fb3a4075d7ff0de7d69c6137cb96b374 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Mon, 26 Sep 2016 22:27:47 +0300 Subject: [PATCH 08/15] client: keep the session open (doesn't forget PIN) --- trezor_agent/client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/trezor_agent/client.py b/trezor_agent/client.py index eea90a7..dd7ec6a 100644 --- a/trezor_agent/client.py +++ b/trezor_agent/client.py @@ -33,9 +33,8 @@ class Client(object): return self def __exit__(self, *args): - """Forget PIN, shutdown screen and disconnect.""" + """Keep the session open (doesn't forget PIN).""" log.info('disconnected from %s', self.device_name) - self.client.clear_session() self.client.close() def get_identity(self, label, index=0): From 91146303a3dbf6286f4b35cbadc6aafb25904428 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Wed, 28 Sep 2016 17:23:11 +0300 Subject: [PATCH 09/15] Follow GPG implementation for subpacket prefix encoding. Conflicts: trezor_agent/gpg/protocol.py --- trezor_agent/gpg/protocol.py | 20 ++++++++++---------- trezor_agent/gpg/tests/test_decode.py | 11 ++++++++++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/trezor_agent/gpg/protocol.py b/trezor_agent/gpg/protocol.py index 4785bbc..b4d4e01 100644 --- a/trezor_agent/gpg/protocol.py +++ b/trezor_agent/gpg/protocol.py @@ -47,17 +47,17 @@ def subpacket_byte(subpacket_type, value): return subpacket(subpacket_type, '>B', value) -def subpacket_prefix_len(blob): - """Prefix GPG subpacket with the encoding of it's length.""" - if len(blob) < 2**8: - length_type = 0 - elif len(blob) < 2**16: - length_type = 1 +def subpacket_prefix_len(item): + """Prefix subpacket length according to RFC 4880 section-5.2.3.1.""" + n = len(item) + if n >= 8384: + prefix = b'\xFF' + struct.pack('>L', n) + elif n >= 192: + n = n - 192 + prefix = struct.pack('BB', (n // 256) + 192, n % 256) else: - length_type = 2 - fmt = ['>B', '>H', '>L'][length_type] - prefix = [b'', b'', struct.pack('>B', 255)][length_type] - return prefix + struct.pack(fmt, len(blob)) + blob + prefix = struct.pack('B', n) + return prefix + item def subpackets(*items): diff --git a/trezor_agent/gpg/tests/test_decode.py b/trezor_agent/gpg/tests/test_decode.py index 00d5eec..5480f80 100644 --- a/trezor_agent/gpg/tests/test_decode.py +++ b/trezor_agent/gpg/tests/test_decode.py @@ -5,7 +5,7 @@ import os import pytest -from .. import decode +from .. import decode, protocol from ... import util @@ -14,6 +14,15 @@ def test_subpackets(): assert decode.parse_subpackets(util.Reader(s)) == [b'\xAB\xCD', b'\xEF'] +def test_subpackets_prefix(): + for n in [0, 1, 2, 4, 5, 10, 191, 192, 193, + 255, 256, 257, 8383, 8384, 65530]: + item = b'?' * n # create dummy subpacket + prefixed = protocol.subpackets(item) + result = decode.parse_subpackets(util.Reader(io.BytesIO(prefixed))) + assert [item] == result + + def test_mpi(): s = io.BytesIO(b'\x00\x09\x01\x23') assert decode.parse_mpi(util.Reader(s)) == 0x123 From f7b07070dab510ff1eec41496957ef8c8a1389a9 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Wed, 28 Sep 2016 18:08:09 +0300 Subject: [PATCH 10/15] README: update setuptools to the latest version --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 639f78b..45112bc 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ is installed correctly (at least v0.6.6): $ apt-get install python-dev libusb-1.0-0-dev libudev-dev $ pip install Cython trezor + $ pip install -U setuptools Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agent) package: From 03650550dd6b41035b48d6d10a9339019a2005f0 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Wed, 28 Sep 2016 18:18:09 +0300 Subject: [PATCH 11/15] Use latest protobuf library (for native Python 3 support) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 73746fc..b32cb21 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( author_email='roman.zeyde@gmail.com', url='http://github.com/romanz/trezor-agent', packages=['trezor_agent', 'trezor_agent.gpg'], - install_requires=['ecdsa>=0.13', 'ed25519>=1.4', 'Cython>=0.23.4', 'protobuf>=2.6.1', 'trezor>=0.6.12', 'semver>=2.2'], + install_requires=['ecdsa>=0.13', 'ed25519>=1.4', 'Cython>=0.23.4', 'protobuf>=3.0.0', 'trezor>=0.6.12', 'semver>=2.2'], platforms=['POSIX'], classifiers=[ 'Environment :: Console', From e41206b3506ced67cd9d84c8b4355964925ce9e8 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Wed, 28 Sep 2016 18:31:13 +0300 Subject: [PATCH 12/15] setup: update trezorlib version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b32cb21..ed6c874 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( author_email='roman.zeyde@gmail.com', url='http://github.com/romanz/trezor-agent', packages=['trezor_agent', 'trezor_agent.gpg'], - install_requires=['ecdsa>=0.13', 'ed25519>=1.4', 'Cython>=0.23.4', 'protobuf>=3.0.0', 'trezor>=0.6.12', 'semver>=2.2'], + install_requires=['ecdsa>=0.13', 'ed25519>=1.4', 'Cython>=0.23.4', 'protobuf>=3.0.0', 'trezor>=0.7.4', 'semver>=2.2'], platforms=['POSIX'], classifiers=[ 'Environment :: Console', From aeda85275dcd16a0e8ca807fb8f1c64943f2885c Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Wed, 28 Sep 2016 18:32:19 +0300 Subject: [PATCH 13/15] bump version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ed6c874..1b134e3 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup setup( name='trezor_agent', - version='0.6.6', + version='0.7.0', description='Using Trezor as hardware SSH agent', author='Roman Zeyde', author_email='roman.zeyde@gmail.com', From 1fa35e7f1a673ccbc94320ed3cb2416a3ac45626 Mon Sep 17 00:00:00 2001 From: Nicolas Pouillard Date: Fri, 30 Sep 2016 12:18:30 +0200 Subject: [PATCH 14/15] Fix the URL for the TREZOR firmware --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45112bc..aaf1113 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agen $ pip install trezor_agent -Finally, verify that you are running the latest [TREZOR firmware](https://mytrezor.com/data/firmware/releases.json) version (at least v1.4.0): +Finally, verify that you are running the latest [TREZOR firmware](https://wallet.mytrezor.com/data/firmware/releases.json) version (at least v1.4.0): $ trezorctl get_features | head vendor: "bitcointrezor.com" From 3aebd137b0f4c41e0dc4048a56b297a9fc94ee75 Mon Sep 17 00:00:00 2001 From: Dominik Kozaczko Date: Sat, 1 Oct 2016 09:50:03 +0200 Subject: [PATCH 15/15] removed .decode('ascii') and added missing bytestrings --- setup.py | 3 ++- tox.ini | 2 +- trezor_agent/factory.py | 1 + trezor_agent/gpg/keyring.py | 9 +++++---- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index 1b134e3..1501fdc 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,8 @@ setup( author_email='roman.zeyde@gmail.com', url='http://github.com/romanz/trezor-agent', packages=['trezor_agent', 'trezor_agent.gpg'], - install_requires=['ecdsa>=0.13', 'ed25519>=1.4', 'Cython>=0.23.4', 'protobuf>=3.0.0', 'trezor>=0.7.4', 'semver>=2.2'], + install_requires=['ecdsa>=0.13', 'ed25519>=1.4', 'Cython>=0.23.4', 'protobuf>=3.0.0', 'trezor>=0.7.4', 'semver>=2.2', + 'keepkey>=0.7.3'], platforms=['POSIX'], classifiers=[ 'Environment :: Console', diff --git a/tox.ini b/tox.ini index 7cd753f..83fd3bb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,py34 +envlist = py27,py3 [pep8] max-line-length = 100 [testenv] diff --git a/trezor_agent/factory.py b/trezor_agent/factory.py index d000812..50da0f3 100644 --- a/trezor_agent/factory.py +++ b/trezor_agent/factory.py @@ -1,4 +1,5 @@ """Thin wrapper around trezor/keepkey libraries.""" +from __future__ import absolute_import import binascii import collections import logging diff --git a/trezor_agent/gpg/keyring.py b/trezor_agent/gpg/keyring.py index f420fa2..eeea055 100644 --- a/trezor_agent/gpg/keyring.py +++ b/trezor_agent/gpg/keyring.py @@ -1,4 +1,5 @@ """Tools for doing signature using gpg-agent.""" +from __future__ import unicode_literals, absolute_import, print_function import binascii import io @@ -15,8 +16,8 @@ log = logging.getLogger(__name__) def get_agent_sock_path(sp=subprocess): """Parse gpgconf output to find out GPG agent UNIX socket path.""" - lines = sp.check_output(['gpgconf', '--list-dirs']).strip().split('\n') - dirs = dict(line.split(':', 1) for line in lines) + lines = sp.check_output(['gpgconf', '--list-dirs']).strip().split(b'\n') + dirs = dict(line.split(b':', 1) for line in lines) return dirs['agent-socket'] @@ -183,14 +184,14 @@ def gpg_command(args, env=None): def get_keygrip(user_id, sp=subprocess): """Get a keygrip of the primary GPG key of the specified user.""" args = gpg_command(['--list-keys', '--with-keygrip', user_id]) - output = sp.check_output(args).decode('ascii') + output = sp.check_output(args) return re.findall(r'Keygrip = (\w+)', output)[0] def gpg_version(sp=subprocess): """Get a keygrip of the primary GPG key of the specified user.""" args = gpg_command(['--version']) - output = sp.check_output(args).decode('ascii') + output = sp.check_output(args) line = output.split(b'\n')[0] # b'gpg (GnuPG) 2.1.11' return line.split(b' ')[-1] # b'2.1.11'