Compare commits
206 Commits
Author | SHA1 | Date |
---|---|---|
Roman Zeyde | 71f357c1bf | 6 years ago |
Eli Boyarski | 8f1d008eb2 | 6 years ago |
Roman Zeyde | 7a351acf15 | 6 years ago |
Roman Zeyde | 7f9aa2b147 | 6 years ago |
Roman Zeyde | eed168341c | 6 years ago |
matejcik | 8b85090fba | 6 years ago |
matejcik | 8708b1e16d | 6 years ago |
Roman Zeyde | 03e7fc48e9 | 6 years ago |
Roman Zeyde | 4968ca7ff3 | 6 years ago |
Roman Zeyde | 6b6d9f5d20 | 6 years ago |
Roman Zeyde | c22109df24 | 6 years ago |
Roman Zeyde | 47ce035e79 | 6 years ago |
Roman Zeyde | 36cbba6c57 | 6 years ago |
Roman Zeyde | 6afe20350b | 6 years ago |
Roman Zeyde | fa171e8923 | 6 years ago |
Roman Zeyde | f0bda9a3e6 | 6 years ago |
Roman Zeyde | 71b56e15d7 | 6 years ago |
Roman Zeyde | 3b9c00e02a | 6 years ago |
Roman Zeyde | dcee59a19e | 6 years ago |
Roman Zeyde | a274de30b8 | 6 years ago |
Roman Zeyde | 4fe9e437ad | 6 years ago |
Roman Zeyde | d04527a8ed | 6 years ago |
Roman Zeyde | 3329c29cb4 | 6 years ago |
Roman Zeyde | df2cb52f8d | 6 years ago |
Roman Zeyde | f36ef4ffe0 | 6 years ago |
Roman Zeyde | f74de828fc | 6 years ago |
Roman Zeyde | 912b1cde7a | 6 years ago |
Roman Zeyde | b7a8c42893 | 6 years ago |
Roman Zeyde | 1e6c4e6930 | 6 years ago |
Roman Zeyde | a8f19e4150 | 6 years ago |
Roman Zeyde | 6a9fdf75e2 | 6 years ago |
Roman Zeyde | 6bc5b6af5e | 6 years ago |
Roman Zeyde | 8672a6901a | 6 years ago |
Roman Zeyde | 672af98ad7 | 6 years ago |
Roman Zeyde | ed531cfff8 | 6 years ago |
Bram | bd1ae0f091 | 6 years ago |
Roman Zeyde | 0c762e8998 | 6 years ago |
Roman Zeyde | bd0df4f801 | 6 years ago |
Roman Zeyde | 3d1639d271 | 6 years ago |
Roman Zeyde | bea899d1ef | 6 years ago |
Roman Zeyde | ccc2174775 | 6 years ago |
Roman Zeyde | afa3fdb89c | 6 years ago |
Roman Zeyde | 2ca3941cfa | 6 years ago |
Roman Zeyde | b1bd6cb690 | 6 years ago |
Roman Zeyde | 766536d2c4 | 6 years ago |
Roman Zeyde | 91f70e7a96 | 6 years ago |
Roman Zeyde | cf5bfd960a | 6 years ago |
pruflyos | 4bd769f138 | 6 years ago |
Bram | 91b850f184 | 6 years ago |
Roman Zeyde | c6bb090dfc | 6 years ago |
Timothy Hobbs | fef4fd06c9 | 6 years ago |
Roman Zeyde | bc691ae795 | 6 years ago |
Roman Zeyde | 61e516e200 | 6 years ago |
Roman Zeyde | 543ff7021d | 6 years ago |
Roman Zeyde | 2e0cfc8088 | 6 years ago |
Roman Zeyde | 18f33f8a08 | 6 years ago |
Roman Zeyde | 2973413995 | 6 years ago |
Jakub Vysoký | 2360693dc5 | 6 years ago |
Roman Zeyde | 7443fc6512 | 6 years ago |
Roman Zeyde | 5efb752979 | 6 years ago |
Roman Zeyde | 4546cd674b | 6 years ago |
Roman Zeyde | 5dba12f144 | 6 years ago |
Roman Zeyde | 887561de9f | 6 years ago |
Roman Zeyde | 6d730e0a5b | 6 years ago |
Roman Zeyde | d0732d16e8 | 6 years ago |
Roman Zeyde | dafb80ad7a | 6 years ago |
Roman Zeyde | df6249b071 | 6 years ago |
rendaw | 942f01418b | 6 years ago |
rendaw | 93b548b737 | 6 years ago |
rendaw | 329f07249a | 6 years ago |
rendaw | a1f7088d33 | 6 years ago |
rendaw | 25f066e113 | 6 years ago |
Roman Zeyde | 0699273d49 | 6 years ago |
Roman Zeyde | 92c352e860 | 6 years ago |
Roman Zeyde | 34c03a462c | 6 years ago |
Roman Zeyde | 51dbecd4c2 | 6 years ago |
Roman Zeyde | ceae65aa5a | 6 years ago |
Roman Zeyde | d0497b0137 | 6 years ago |
Roman Zeyde | 870152a7af | 6 years ago |
Roman Zeyde | cbdc52c0a4 | 6 years ago |
Roman Zeyde | 0c9fc33757 | 6 years ago |
Roman Zeyde | 17ea941add | 6 years ago |
Roman Zeyde | 64064b5ecc | 6 years ago |
Roman Zeyde | 601a2b1336 | 6 years ago |
Roman Zeyde | 2e688ccac9 | 6 years ago |
Roman Zeyde | b6181bb5b5 | 6 years ago |
Roman Zeyde | b6da299cb0 | 6 years ago |
Roman Zeyde | 04627f0899 | 6 years ago |
Roman Zeyde | 54ce6f2cec | 6 years ago |
Roman Zeyde | a1047ba7b1 | 6 years ago |
Roman Zeyde | e90bd0cd81 | 6 years ago |
slush | 66e3e60370 | 6 years ago |
slush | 3f1604d609 | 6 years ago |
slush | d0f4cccfd2 | 6 years ago |
Roman Zeyde | 08d81c992c | 6 years ago |
Roman Zeyde | 55a899f929 | 6 years ago |
Roman Zeyde | e7604dff68 | 6 years ago |
rendaw | 8849545700 | 6 years ago |
rendaw | d109cd73b5 | 6 years ago |
rendaw | 95e98d6eda | 6 years ago |
rendaw | 9e78d52721 | 6 years ago |
Roman Zeyde | 2a76ef6819 | 6 years ago |
Roman Zeyde | 654a3c465a | 6 years ago |
Roman Zeyde | 2168115b06 | 6 years ago |
Roman Zeyde | 4a9140c42d | 6 years ago |
Roman Zeyde | b20d98bf57 | 6 years ago |
Roman Zeyde | 199fb299c3 | 6 years ago |
rendaw | 06e169f141 | 6 years ago |
rendaw | 131111bc0e | 6 years ago |
Roman Zeyde | f4208009e0 | 6 years ago |
Roman Zeyde | 73d60dbec0 | 6 years ago |
Roman Zeyde | 34ea224290 | 6 years ago |
Roman Zeyde | 7803026f61 | 6 years ago |
Roman Zeyde | 34ce1005fd | 6 years ago |
Roman Zeyde | 8677c8ebaa | 6 years ago |
Serge Pokhodyaev | 6363eb0d4a | 6 years ago |
Serge Pokhodyaev | a32bfc749b | 6 years ago |
Roman Zeyde | 75d117ad0d | 6 years ago |
Roman Zeyde | cefc5f180a | 6 years ago |
Roman Zeyde | 0f5c71b748 | 6 years ago |
Roman Zeyde | d5f97b7efa | 6 years ago |
Roman Zeyde | 4a12bfa0b7 | 6 years ago |
Roman Zeyde | cac889ff7d | 6 years ago |
Roman Zeyde | 92c6e680ed | 6 years ago |
Roman Zeyde | bf294beb56 | 6 years ago |
Roman Zeyde | 713345918e | 6 years ago |
Roman Zeyde | eb60c2f475 | 6 years ago |
Roman Zeyde | 6d8d43db9b | 6 years ago |
Roman Zeyde | 3e67bc9f0e | 6 years ago |
Roman Zeyde | 38b50485de | 6 years ago |
Roman Zeyde | 9cba27b31a | 6 years ago |
Eli Boyarski | 00a65a9820 | 6 years ago |
Roman Zeyde | 52ad601e66 | 6 years ago |
Eli Boyarski | d96a2820ff | 6 years ago |
Roman Zeyde | 29aaf777ad | 6 years ago |
Roman Zeyde | 385fc9457b | 6 years ago |
Jonathan Roelofs | 9cf73f677a | 7 years ago |
Jonathan Roelofs | ec97cd0c44 | 7 years ago |
Jonathan Roelofs | 4cd7dc02eb | 7 years ago |
Roman Zeyde | 8fe9460ed6 | 7 years ago |
Roman Zeyde | db16aa3d1c | 7 years ago |
Roman Zeyde | 41ccd2f332 | 7 years ago |
Roman Zeyde | cb14d1e00b | 7 years ago |
Roman Zeyde | cc6ee31deb | 7 years ago |
Roman Zeyde | b1f302151b | 7 years ago |
Roman Zeyde | fde50f04ab | 7 years ago |
Roman Zeyde | 7e42e455a1 | 7 years ago |
Roman Zeyde | 13cd6be2d1 | 7 years ago |
Roman Zeyde | 40469c4100 | 7 years ago |
Roman Zeyde | 0d059587a7 | 7 years ago |
Roman Zeyde | 283cb3d7e8 | 7 years ago |
Roman Zeyde | 51cc716e3f | 7 years ago |
Roman Zeyde | 8b4850b0ce | 7 years ago |
Roman Zeyde | f22c07e970 | 7 years ago |
Roman Zeyde | 29c7234ef4 | 7 years ago |
Roman Zeyde | 1942e3999b | 7 years ago |
Roman Zeyde | f2e52a88be | 7 years ago |
Roman Zeyde | b26a4cc7b0 | 7 years ago |
Roman Zeyde | c4dfca04f2 | 7 years ago |
Roman Zeyde | a1ecbf447e | 7 years ago |
Roman Zeyde | 1f9d457e92 | 7 years ago |
Roman Zeyde | cb3477fc69 | 7 years ago |
Roman Zeyde | 9bbc66cc16 | 7 years ago |
Roman Zeyde | 06afc971db | 7 years ago |
Dirk-Willem van Gulik | 2b51a85c26 | 7 years ago |
Dirk-Willem van Gulik | 1906e6d9b0 | 7 years ago |
Dirk-Willem van Gulik | b3f6e39b48 | 7 years ago |
Aitor Pazos | 8b03b649d5 | 7 years ago |
Roman Zeyde | 90cbc41b17 | 7 years ago |
Roman Zeyde | 4926d4f4d3 | 7 years ago |
Roman Zeyde | d52f295326 | 7 years ago |
Max Pixel | 47a8a53247 | 7 years ago |
Roman Zeyde | 9530c4d7db | 7 years ago |
Roman Zeyde | a2d0c1067d | 7 years ago |
Roman Zeyde | 3d5717dca1 | 7 years ago |
Roman Zeyde | 08fef24e39 | 7 years ago |
Roman Zeyde | bab46dae5c | 7 years ago |
Roman Zeyde | e2625cc521 | 7 years ago |
Roman Zeyde | 7ed76fe472 | 7 years ago |
Roman Zeyde | a5929eed62 | 7 years ago |
Roman Zeyde | 5f722f8ae1 | 7 years ago |
Roman Zeyde | 7212b2fa37 | 7 years ago |
Avishaan | 55e1c614a7 | 7 years ago |
Roman Zeyde | 8cf1f0463a | 7 years ago |
Roman Zeyde | f177b0b55a | 7 years ago |
Roman Zeyde | b2450d448c | 7 years ago |
Roman Zeyde | 93e5f0cd8b | 7 years ago |
Roman Zeyde | 9998456fe0 | 7 years ago |
Roman Zeyde | 0f85ae6e2c | 7 years ago |
Roman Zeyde | 44cdeed024 | 7 years ago |
Roman Zeyde | 867e2cfd1b | 7 years ago |
Roman Zeyde | df6ddab2cf | 7 years ago |
Roman Zeyde | 5b9f03d198 | 7 years ago |
Roman Zeyde | 06ea890095 | 7 years ago |
Roman Zeyde | 0999a85529 | 7 years ago |
Roman Zeyde | 835f283ccf | 7 years ago |
Roman Zeyde | f57dbb553f | 7 years ago |
Roman Zeyde | a890dcc085 | 7 years ago |
Roman Zeyde | c8ed4a223a | 7 years ago |
Roman Zeyde | 1ef96bed03 | 7 years ago |
Roman Zeyde | e4fdca08e5 | 7 years ago |
Roman Zeyde | 51b297e93b | 7 years ago |
Roman Zeyde | c22c959cf9 | 7 years ago |
Roman Zeyde | 3199cb964a | 7 years ago |
Roman Zeyde | c5f245957d | 7 years ago |
Chris Cowan | fbb3059a0b | 7 years ago |
@ -0,0 +1,7 @@
|
||||
[bumpversion]
|
||||
commit = True
|
||||
tag = True
|
||||
current_version = 0.12.0
|
||||
|
||||
[bumpversion:file:setup.py]
|
||||
|
@ -1,2 +1,5 @@
|
||||
[MESSAGES CONTROL]
|
||||
disable=invalid-name, missing-docstring, locally-disabled, unbalanced-tuple-unpacking,no-else-return
|
||||
disable=invalid-name, missing-docstring, locally-disabled, unbalanced-tuple-unpacking,no-else-return,fixme,duplicate-code
|
||||
|
||||
[SIMILARITIES]
|
||||
min-similarity-lines=5
|
||||
|
@ -1,70 +0,0 @@
|
||||
# Installation
|
||||
|
||||
Install the following packages (depending on your distribution):
|
||||
|
||||
### Debian
|
||||
|
||||
$ apt update && apt upgrade
|
||||
$ apt install python-pip python-dev libusb-1.0-0-dev libudev-dev
|
||||
|
||||
### Fedora/RedHat
|
||||
|
||||
$ yum update
|
||||
$ yum install python-pip python-devel libusb-devel libudev-devel \
|
||||
gcc redhat-rpm-config
|
||||
|
||||
Also, update Python packages before starting the installation:
|
||||
|
||||
$ pip install -U setuptools pip
|
||||
|
||||
Make sure you are running the latest firmware version on your hardware device.
|
||||
Currently the following firmware versions are supported:
|
||||
|
||||
* [TREZOR](https://wallet.trezor.io/data/firmware/releases.json): `1.4.2+`
|
||||
* [KeepKey](https://github.com/keepkey/keepkey-firmware/releases): `3.0.17+`
|
||||
* [Ledger Nano S](https://github.com/LedgerHQ/blue-app-ssh-agent): `0.0.3+` (install [SSH/PGP Agent](https://www.ledgerwallet.com/images/apps/chrome-mngr-apps.png) app)
|
||||
|
||||
## TREZOR
|
||||
|
||||
Make sure that your `udev` rules are configured [correctly](https://doc.satoshilabs.com/trezor-user/settingupchromeonlinux.html#manual-configuration-of-udev-rules).
|
||||
Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agent) package:
|
||||
|
||||
$ pip install trezor_agent
|
||||
|
||||
Or, directly from the latest source code:
|
||||
|
||||
$ git clone https://github.com/romanz/trezor-agent
|
||||
$ pip install --user -e trezor-agent/agents/trezor
|
||||
|
||||
## KeepKey
|
||||
|
||||
Make sure that your `udev` rules are configured [correctly](https://support.keepkey.com/support/solutions/articles/6000037796-keepkey-wallet-is-not-being-recognized-by-linux).
|
||||
Then, install the latest [keepkey_agent](https://pypi.python.org/pypi/keepkey_agent) package:
|
||||
|
||||
$ pip install keepkey_agent
|
||||
|
||||
Or, directly from the latest source code:
|
||||
|
||||
$ git clone https://github.com/romanz/trezor-agent
|
||||
$ pip install --user -e trezor-agent/agents/keepkey
|
||||
|
||||
## Ledger Nano S
|
||||
|
||||
Make sure that your `udev` rules are configured [correctly](http://support.ledgerwallet.com/knowledge_base/topics/ledger-wallet-is-not-recognized-on-linux).
|
||||
Then, install the latest [ledger_agent](https://pypi.python.org/pypi/ledger_agent) package:
|
||||
|
||||
$ pip install ledger_agent
|
||||
|
||||
Or, directly from the latest source code:
|
||||
|
||||
$ git clone https://github.com/romanz/trezor-agent
|
||||
$ pip install --user -e trezor-agent/agents/ledger
|
||||
|
||||
## 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.
|
||||
|
||||
If you can't find the command-line utilities (after running `pip install --user`),
|
||||
please make sure that `~/.local/bin` is on your `PATH` variable
|
||||
(see a [relevant](https://github.com/pypa/pip/issues/3813) issue).
|
@ -1,105 +0,0 @@
|
||||
Note: the GPG-related code is still under development, so please try the current implementation
|
||||
and please let me [know](https://github.com/romanz/trezor-agent/issues/new) if something doesn't
|
||||
work well for you. If possible:
|
||||
|
||||
* record the session (e.g. using [asciinema](https://asciinema.org))
|
||||
* attach the GPG agent log from `~/.gnupg/{trezor,ledger}/gpg-agent.log`
|
||||
|
||||
Thanks!
|
||||
|
||||
# Installation
|
||||
|
||||
First, verify that you have GPG 2.1.11+ installed
|
||||
([Debian](https://gist.github.com/vt0r/a2f8c0bcb1400131ff51),
|
||||
[macOS](https://sourceforge.net/p/gpgosx/docu/Download/)):
|
||||
|
||||
```
|
||||
$ gpg2 --version | head -n1
|
||||
gpg (GnuPG) 2.1.15
|
||||
```
|
||||
|
||||
This GPG version is included in [Ubuntu 16.04](https://launchpad.net/ubuntu/+source/gnupg2)
|
||||
and [Linux Mint 18](https://community.linuxmint.com/software/view/gnupg2).
|
||||
|
||||
Update you device firmware to the latest version and install your specific `agent` package:
|
||||
|
||||
```
|
||||
$ pip install --user (trezor|keepkey|ledger)_agent
|
||||
```
|
||||
|
||||
# Quickstart
|
||||
|
||||
## Identity creation
|
||||
[![asciicast](https://asciinema.org/a/90416.png)](https://asciinema.org/a/90416)
|
||||
|
||||
In order to use specific device type for GPG indentity creation, use either command:
|
||||
```
|
||||
$ DEVICE=(trezor,ledger) ./scripts/gpg-init "John Doe <john@doe.bit>"
|
||||
```
|
||||
|
||||
## Sample usage (signature and decryption)
|
||||
[![asciicast](https://asciinema.org/a/120441.png)](https://asciinema.org/a/120441)
|
||||
|
||||
In order to use specific device type for GPG operations, set the following environment variable to either:
|
||||
```
|
||||
$ export GNUPGHOME=~/.gnupg/{trezor,ledger}
|
||||
```
|
||||
|
||||
You can use GNU Privacy Assistant (GPA) in order to inspect the created keys
|
||||
and perform signature and decryption operations using:
|
||||
|
||||
```
|
||||
$ sudo apt install gpa
|
||||
$ GNUPGHOME=~/.gnupg/trezor gpa
|
||||
```
|
||||
[![GPA](https://cloud.githubusercontent.com/assets/9900/20224804/053d7474-a849-11e6-87f3-ab07dc536158.png)](https://www.gnupg.org/related_software/swlist.html#gpa)
|
||||
|
||||
## 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 commit.gpgsign 1
|
||||
$ git config --local gpg.program $(which gpg2)
|
||||
$ git commit --gpg-sign # create GPG-signed commit
|
||||
$ git log --show-signature -1 # verify commit signature
|
||||
$ git tag v1.2.3 --sign # create GPG-signed tag
|
||||
$ git tag v1.2.3 --verify # verify tag signature
|
||||
```
|
||||
|
||||
## Password manager
|
||||
|
||||
First install `pass` from [passwordstore.org](https://www.passwordstore.org/) and initialize it to use your TREZOR-based GPG identity:
|
||||
```
|
||||
$ export GNUPGHOME=~/.gnupg/trezor
|
||||
$ pass init "Roman Zeyde <roman.zeyde@gmail.com>"
|
||||
Password store initialized for Roman Zeyde <roman.zeyde@gmail.com>
|
||||
```
|
||||
Then, you can generate truly random passwords and save them encrypted using your public key (as separate `.gpg` files under `~/.password-store/`):
|
||||
```
|
||||
$ pass generate Dev/github 32
|
||||
$ pass generate Social/hackernews 32
|
||||
$ pass generate Social/twitter 32
|
||||
$ pass generate VPS/linode 32
|
||||
$ pass
|
||||
Password Store
|
||||
├── Dev
|
||||
│ └── github
|
||||
├── Social
|
||||
│ ├── hackernews
|
||||
│ └── twitter
|
||||
└── VPS
|
||||
└── linode
|
||||
```
|
||||
In order to paste them into the browser, you'd need to decrypt the password using your hardware device:
|
||||
```
|
||||
$ pass --clip VPS/linode
|
||||
Copied VPS/linode to clipboard. Will clear in 45 seconds.
|
||||
```
|
||||
|
||||
You can also use the following [Qt-based UI](https://qtpass.org/) for `pass`:
|
||||
```
|
||||
$ sudo apt install qtpass
|
||||
$ GNUPGHOME=~/.gnupg/trezor qtpass
|
||||
```
|
||||
|
||||
## Re-generation of an existing GPG identity
|
||||
[![asciicast](https://asciinema.org/a/M4lRjEmGJ2RreQiHBGWT9pzp4.png)](https://asciinema.org/a/M4lRjEmGJ2RreQiHBGWT9pzp4)
|
@ -1,87 +0,0 @@
|
||||
# Screencast demo usage
|
||||
|
||||
## Simple usage (single SSH session)
|
||||
[![Demo](https://asciinema.org/a/22959.png)](https://asciinema.org/a/22959)
|
||||
|
||||
## Advanced usage (multiple SSH sessions from a sub-shell)
|
||||
[![Subshell](https://asciinema.org/a/33240.png)](https://asciinema.org/a/33240)
|
||||
|
||||
## Using for GitHub SSH authentication (via `trezor-git` utility)
|
||||
[![GitHub](https://asciinema.org/a/38337.png)](https://asciinema.org/a/38337)
|
||||
|
||||
## Loading multiple SSH identities from configuration file
|
||||
[![Config](https://asciinema.org/a/bdxxtgctk5syu56yfz8lcp7ny.png)](https://asciinema.org/a/bdxxtgctk5syu56yfz8lcp7ny)
|
||||
|
||||
# Public key generation
|
||||
|
||||
Run:
|
||||
|
||||
/tmp $ trezor-agent user@ssh.hostname.com -v > hostname.pub
|
||||
2015-09-02 15:03:18,929 INFO getting "ssh://user@ssh.hostname.com" public key from Trezor...
|
||||
2015-09-02 15:03:23,342 INFO disconnected from Trezor
|
||||
/tmp $ cat hostname.pub
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGSevcDwmT+QaZPUEWUUjTeZRBICChxMKuJ7dRpBSF8+qt+8S1GBK5Zj8Xicc8SHG/SE/EXKUL2UU3kcUzE7ADQ= ssh://user@ssh.hostname.com
|
||||
|
||||
Append `hostname.pub` contents to `/home/user/.ssh/authorized_keys`
|
||||
configuration file at `ssh.hostname.com`, so the remote server
|
||||
would allow you to login using the corresponding private key signature.
|
||||
|
||||
# Usage
|
||||
|
||||
Run:
|
||||
|
||||
/tmp $ trezor-agent user@ssh.hostname.com -v -c
|
||||
2015-09-02 15:09:39,782 INFO getting "ssh://user@ssh.hostname.com" public key from Trezor...
|
||||
2015-09-02 15:09:44,430 INFO please confirm user "roman" login to "ssh://user@ssh.hostname.com" using Trezor...
|
||||
2015-09-02 15:09:46,152 INFO signature status: OK
|
||||
Linux lmde 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u3 (2015-08-04) x86_64
|
||||
|
||||
The programs included with the Debian GNU/Linux system are free software;
|
||||
the exact distribution terms for each program are described in the
|
||||
individual files in /usr/share/doc/*/copyright.
|
||||
|
||||
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||
permitted by applicable law.
|
||||
Last login: Tue Sep 1 15:57:05 2015 from localhost
|
||||
~ $
|
||||
|
||||
Make sure to confirm SSH signature on the Trezor device when requested.
|
||||
|
||||
## Accessing remote Git/Mercurial repositories
|
||||
|
||||
Use your SSH public key to access your remote repository (e.g. [GitHub](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/)):
|
||||
|
||||
$ trezor-agent -v -e ed25519 git@github.com | xclip
|
||||
|
||||
Use the following Bash alias for convinient Git operations:
|
||||
|
||||
$ alias git_hub='trezor-agent -v -e ed25519 git@github.com -- git'
|
||||
|
||||
Replace `git` with `git_hub` for remote operations:
|
||||
|
||||
$ git_hub push origin master
|
||||
|
||||
The same works for Mercurial (e.g. on [BitBucket](https://confluence.atlassian.com/bitbucket/set-up-ssh-for-mercurial-728138122.html)):
|
||||
|
||||
$ trezor-agent -v -e ed25519 git@bitbucket.org -- hg push
|
||||
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
If SSH connection fails to work, please open an [issue](https://github.com/romanz/trezor-agent/issues)
|
||||
with a verbose log attached (by running `trezor-agent -vv`) .
|
||||
|
||||
## Incompatible SSH options
|
||||
|
||||
Note that your local SSH configuration may ignore `trezor-agent`, if it has `IdentitiesOnly` option set to `yes`.
|
||||
|
||||
IdentitiesOnly
|
||||
Specifies that ssh(1) should only use the authentication identity files configured in
|
||||
the ssh_config files, even if ssh-agent(1) or a PKCS11Provider offers more identities.
|
||||
The argument to this keyword must be “yes” or “no”.
|
||||
This option is intended for situations where ssh-agent offers many different identities.
|
||||
The default is “no”.
|
||||
|
||||
If you are failing to connect, try running:
|
||||
|
||||
$ trezor-agent -vv user@host -- ssh -vv -oIdentitiesOnly=no user@host
|
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
|
||||
agent = 'trezor-gpg-agent'
|
||||
binary = 'neopg'
|
||||
|
||||
if sys.argv[1:2] == ['agent']:
|
||||
os.execvp(agent, [agent, '-vv'] + sys.argv[2:])
|
||||
else:
|
||||
# HACK: pass this script's path as argv[0], so it will be invoked again
|
||||
# when NeoPG tries to run its own agent:
|
||||
# https://github.com/das-labor/neopg/blob/1fe50460abe01febb118641e37aa50bc429a1786/src/neopg.cpp#L114
|
||||
# https://github.com/das-labor/neopg/blob/1fe50460abe01febb118641e37aa50bc429a1786/legacy/gnupg/common/asshelp.cpp#L217
|
||||
os.execvp(binary, [__file__, 'gpg2'] + sys.argv[1:])
|
@ -0,0 +1,51 @@
|
||||
# Design
|
||||
|
||||
Most cryptographic tools (such as gpg, ssh and openssl) allow the offloading of some key cryptographic steps to *engines* or *agents*. This is to allow sensitive operations, such as asking for a password or doing the actual encryption step, to be kept separate from the larger body of code. This makes it easier to secure those steps, move them onto hardware or easier to audit.
|
||||
|
||||
SSH and GPG do this by means of a simple interprocess communication protocol (usually a unix domain socket) and an agent (`ssh-agent`) or GPG key daemon (`gpg-agent`). The `trezor-agent` mimics these two protocols.
|
||||
|
||||
These two agents make the connection between the front end (e.g. a `gpg --sign` command, or an `ssh user@fqdn`). And then they wait for a request from the 'front end', and then do the actual asking for a password and subsequent using the private key to sign or decrypt something.
|
||||
|
||||
The various hardware wallets (Trezor, KeepKey and Ledger) each have the ability (as of Firmware 1.3.4) to use the NIST P-256 elliptic curve to sign, encrypt or decrypt. This curve can be used with S/MIME, GPG and SSH.
|
||||
|
||||
So when you `ssh` to a machine - rather than consult the normal ssh-agent (which in turn will use your private SSH key in files such as `~/.ssh/id_rsa`) -- the trezor-agent will aks your hardware wallet to use its private key to sign the challenge.
|
||||
|
||||
## Key Naming
|
||||
|
||||
`trezor-agent` goes to great length to avoid using the valuable parent key.
|
||||
|
||||
The rationale behind this is that `trezor-agent` is to some extent condemned to *blindly* signing any NONCE given to it (e.g. as part of a challenge respone, or as the hash/hmac of someting to sign).
|
||||
|
||||
And doing so with the master private key is risky - as rogue (ssh) server could possibly provide a doctored NONCE that happens to be tied to a transaction or something else.
|
||||
|
||||
It therefore uses only derived child keys pairs instead (according to the [BIP-0032: Hierarchical Deterministic Wallets][1] system) - and ones on different leafs. So the parent key is only used within the device for creating the child keys - and not exposed in any way to `trezor-agent`.
|
||||
|
||||
### SSH
|
||||
|
||||
It is common for SSH users to use one (or a few) private keys with SSH on all servers they log into. The `trezor-agent` is slightly more cautious and derives a child key that is *unique* to the server and username you are logging into from your master private key on the device.
|
||||
|
||||
So taking a commmand such as:
|
||||
|
||||
$ trezor-agent -c user@fqdn.com
|
||||
|
||||
The `trezor-agent` will take the `user`@`fqdn.com`; canonicalise it (e.g. to add the ssh default port number if none was specified) and then apply some simple hashing (See [SLIP-0013 : Authentication using deterministic hierarchy][2]). The resulting 128bit hash is then used to construct a lead 'HD node' that contains an extened public private *child* key.
|
||||
|
||||
This way they keypair is specific to the server/hostname/port and protocol combination used. And it is this private key that is used to sign the nonce passed by the SSH server (as opposed to the master key).
|
||||
|
||||
The `trezor-agent` then instructs SSH to connect to the server. It will then engage in the normal challenge response process, ask the hardware wallet to blindly sign any nonce flashed by the server with the derived child private key and return this to the server. It then hands over to normal SSH for the rest of the logged in session.
|
||||
|
||||
### GPG
|
||||
|
||||
GPG uses much the same approach as SSH, except in this case it relies on [SLIP-0017 : ECDH using deterministic hierarchy][3] for the mapping to an ECDH key and it maps these to the normal GPG child key infrastructure.
|
||||
|
||||
Note: Keepkey does not support en-/de-cryption at this time.
|
||||
|
||||
### Index
|
||||
|
||||
The canonicalisation process ([SLIP-0013][2] and [SLIP-0017][3]) of an email address or ssh address allows for the mixing in of an extra 'index' - a unsigned 32 bit number. This allows one to have multiple, different keys, for the same address.
|
||||
|
||||
This feature is currently not used -- it is set to '0'. This may change in the future.
|
||||
|
||||
[1]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||
[2]: https://github.com/satoshilabs/slips/blob/master/slip-0013.md
|
||||
[3]: https://github.com/satoshilabs/slips/blob/master/slip-0017.md
|
@ -0,0 +1,141 @@
|
||||
# Installation
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
Install the following packages (depending on your distribution):
|
||||
|
||||
### OS dependencies
|
||||
|
||||
This software needs Python, libusb, and libudev along with development files.
|
||||
|
||||
You can install them on these distributions as follows:
|
||||
|
||||
##### Debian
|
||||
|
||||
$ apt-get install python3-pip python3-dev python3-tk libusb-1.0-0-dev libudev-dev
|
||||
|
||||
##### RedHat
|
||||
|
||||
$ yum install python3-pip python3-devel python3-tk libusb-devel libudev-devel \
|
||||
gcc redhat-rpm-config
|
||||
|
||||
##### Fedora
|
||||
|
||||
$ dnf install python3-pip python3-devel python3-tkinter libusb-devel libudev-devel \
|
||||
gcc redhat-rpm-config
|
||||
|
||||
##### OpenSUSE
|
||||
|
||||
$ zypper install python-pip python-devel python-tk libusb-1_0-devel libudev-devel
|
||||
|
||||
If you are using python3 or your system `pip` command points to `pip3.x`
|
||||
(`/etc/alternatives/pip -> /usr/bin/pip3.6`) you will need to install these
|
||||
dependencies instead:
|
||||
|
||||
$ zypper install python3-pip python3-devel python3-tk libusb-1_0-devel libudev-devel
|
||||
|
||||
##### macOS
|
||||
|
||||
There are many different options to install python environment on macOS ([official](https://www.python.org/downloads/mac-osx/), [anaconda](https://conda.io/docs/user-guide/install/macos.html), ..). Most importantly you need `libusb`. Probably the easiest way is via [homebrew](https://brew.sh/)
|
||||
|
||||
$ brew install libusb
|
||||
|
||||
### GPG
|
||||
|
||||
If you intend to use GPG make sure you have GPG installed and up to date. This software requires a GPG version >= 2.1.11.
|
||||
|
||||
You can verify your installed version by running:
|
||||
```
|
||||
$ gpg2 --version | head -n1
|
||||
gpg (GnuPG) 2.1.15
|
||||
```
|
||||
|
||||
* Follow this installation guide for [Debian](https://gist.github.com/vt0r/a2f8c0bcb1400131ff51)
|
||||
* Install GPG for [macOS](https://sourceforge.net/p/gpgosx/docu/Download/)
|
||||
* Install packages for Ubuntu 16.04 [here](https://launchpad.net/ubuntu/+source/gnupg2)
|
||||
* Install packages for Linux Mint 18 [here](https://community.linuxmint.com/software/view/gnupg2)
|
||||
|
||||
# 2. Install the TREZOR agent
|
||||
|
||||
1. Make sure you are running the latest firmware version on your Trezor:
|
||||
|
||||
* [TREZOR firmware releases](https://wallet.trezor.io/data/firmware/releases.json): `1.4.2+`
|
||||
|
||||
2. Make sure that your `udev` rules are configured [correctly](https://doc.satoshilabs.com/trezor-user/settingupchromeonlinux.html#manual-configuration-of-udev-rules).
|
||||
|
||||
3. Then, install the latest [trezor_agent](https://pypi.python.org/pypi/trezor_agent) package:
|
||||
|
||||
```
|
||||
$ pip3 install Cython hidapi
|
||||
$ pip3 install trezor_agent
|
||||
```
|
||||
|
||||
Or, directly from the latest source code:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/romanz/trezor-agent
|
||||
$ pip3 install --user -e trezor-agent/agents/trezor
|
||||
```
|
||||
|
||||
Or, through Homebrew on macOS:
|
||||
|
||||
```
|
||||
$ brew install trezor-agent
|
||||
```
|
||||
|
||||
# 3. Install the KeepKey agent
|
||||
|
||||
1. Make sure you are running the latest firmware version on your KeepKey:
|
||||
|
||||
* [KeepKey firmware releases](https://github.com/keepkey/keepkey-firmware/releases): `3.0.17+`
|
||||
|
||||
2. Make sure that your `udev` rules are configured [correctly](https://support.keepkey.com/support/solutions/articles/6000037796-keepkey-wallet-is-not-being-recognized-by-linux).
|
||||
Then, install the latest [keepkey_agent](https://pypi.python.org/pypi/keepkey_agent) package:
|
||||
|
||||
```
|
||||
$ pip3 install keepkey_agent
|
||||
```
|
||||
|
||||
Or, on Mac using Homebrew:
|
||||
|
||||
```
|
||||
$ homebrew install keepkey-agent
|
||||
```
|
||||
|
||||
Or, directly from the latest source code:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/romanz/trezor-agent
|
||||
$ pip3 install --user -e trezor-agent/agents/keepkey
|
||||
```
|
||||
|
||||
# 4. Install the Ledger Nano S agent
|
||||
|
||||
1. Make sure you are running the latest firmware version on your Ledger Nano S:
|
||||
|
||||
* [Ledger Nano S firmware releases](https://github.com/LedgerHQ/blue-app-ssh-agent): `0.0.3+` (install [SSH/PGP Agent](https://www.ledgerwallet.com/images/apps/chrome-mngr-apps.png) app)
|
||||
|
||||
2. Make sure that your `udev` rules are configured [correctly](https://ledger.zendesk.com/hc/en-us/articles/115005165269-What-if-Ledger-Wallet-is-not-recognized-on-Linux-).
|
||||
3. Then, install the latest [ledger_agent](https://pypi.python.org/pypi/ledger_agent) package:
|
||||
|
||||
```
|
||||
$ pip3 install ledger_agent
|
||||
```
|
||||
|
||||
Or, directly from the latest source code:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/romanz/trezor-agent
|
||||
$ pip3 install --user -e trezor-agent/agents/ledger
|
||||
```
|
||||
|
||||
# 5. Installation 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.
|
||||
|
||||
If you can't find the command-line utilities (after running `pip install --user`),
|
||||
please make sure that `~/.local/bin` is on your `PATH` variable
|
||||
(see a [relevant](https://github.com/pypa/pip/issues/3813) issue).
|
||||
|
||||
If you can't find command-line utilities and are on macOS/OSX check `~/Library/Python/2.7/bin` and add to `PATH` if necessary (see a [relevant](https://github.com/romanz/trezor-agent/issues/155) issue).
|
@ -0,0 +1,251 @@
|
||||
# GPG Agent
|
||||
|
||||
Note: the GPG-related code is still under development, so please try the current implementation
|
||||
and please let me [know](https://github.com/romanz/trezor-agent/issues/new) if something doesn't
|
||||
work well for you. If possible:
|
||||
|
||||
* record the session (e.g. using [asciinema](https://asciinema.org))
|
||||
* attach the GPG agent log from `~/.gnupg/{trezor,ledger}/gpg-agent.log` (can be [encrypted](https://keybase.io/romanz))
|
||||
|
||||
Thanks!
|
||||
|
||||
## 1. Configuration
|
||||
|
||||
1. Initialize the agent GPG directory.
|
||||
|
||||
[![asciicast](https://asciinema.org/a/3iNw2L9QWB8R3EVdYdAxMOLK8.png)](https://asciinema.org/a/3iNw2L9QWB8R3EVdYdAxMOLK8)
|
||||
|
||||
Run
|
||||
|
||||
```
|
||||
$ (trezor|keepkey|ledger)-gpg init "Roman Zeyde <roman.zeyde@gmail.com>"
|
||||
```
|
||||
|
||||
Follow the instructions provided to complete the setup. Keep note of the timestamp value which you'll need if you want to regenerate the key later.
|
||||
|
||||
If you'd like a Trezor-style PIN entry program, follow [these instructions](README-PINENTRY.md).
|
||||
|
||||
2. Add `export GNUPGHOME=~/.gnupg/(trezor|keepkey|ledger)` to your `.bashrc` or other environment file.
|
||||
|
||||
This `GNUPGHOME` contains your hardware keyring and agent settings. This agent software assumes all keys are backed by hardware devices so you can't use standard GPG keys in `GNUPGHOME` (if you do mix keys you'll receive an error when you attempt to use them).
|
||||
|
||||
If you wish to switch back to your software keys unset `GNUPGHOME`.
|
||||
|
||||
3. Log out and back into your session to ensure your environment is updated everywhere.
|
||||
|
||||
## 2. Usage
|
||||
|
||||
You can use any GPG commands or software that uses GPG as usual and will be prompted to interact with your hardware device as necessary. The agent is automatically started if it isn't running when you run any `gpg` command.
|
||||
|
||||
##### Restarting the agent
|
||||
|
||||
If you change settings or need to restart the agent for some other reason, simply kill it. It will restart the next time GPG is invoked.
|
||||
|
||||
## 3. Common Use Cases
|
||||
|
||||
### Sign and decrypt files
|
||||
|
||||
[![asciicast](https://asciinema.org/a/120441.png)](https://asciinema.org/a/120441)
|
||||
|
||||
### Inspect GPG keys
|
||||
You can use GNU Privacy Assistant (GPA) in order to inspect the created keys and perform signature and decryption operations as usual:
|
||||
|
||||
```
|
||||
$ sudo apt install gpa
|
||||
$ gpa
|
||||
```
|
||||
|
||||
[![GPA](https://cloud.githubusercontent.com/assets/9900/20224804/053d7474-a849-11e6-87f3-ab07dc536158.png)](https://www.gnupg.org/related_software/swlist.html#gpa)
|
||||
|
||||
### Sign Git commits and tags
|
||||
|
||||
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 commit.gpgsign 1
|
||||
$ git config --local gpg.program $(which gpg2)
|
||||
$ git commit --gpg-sign # create GPG-signed commit
|
||||
$ git log --show-signature -1 # verify commit signature
|
||||
$ git tag v1.2.3 --sign # create GPG-signed tag
|
||||
$ git tag v1.2.3 --verify # verify tag signature
|
||||
```
|
||||
|
||||
Note that your git email has to correlate to your gpg key email. If you use a different email for git, you'll need to either generate a new gpg key for that email or set your git email using the command:
|
||||
|
||||
````
|
||||
$ git config user.email foo@example.com
|
||||
````
|
||||
|
||||
If your git email is configured incorrectly, you will receive the error:
|
||||
|
||||
````
|
||||
error: gpg failed to sign the data
|
||||
fatal: failed to write commit object
|
||||
````
|
||||
|
||||
when committing to git.
|
||||
|
||||
### Manage passwords
|
||||
|
||||
Password managers such as [pass](https://www.passwordstore.org/) and [gopass](https://www.justwatch.com/gopass/) rely on GPG for encryption so you can use your device with them too.
|
||||
|
||||
##### With `pass`:
|
||||
|
||||
First install `pass` from [passwordstore.org] and initialize it to use your TREZOR-based GPG identity:
|
||||
```
|
||||
$ pass init "Roman Zeyde <roman.zeyde@gmail.com>"
|
||||
Password store initialized for Roman Zeyde <roman.zeyde@gmail.com>
|
||||
```
|
||||
Then, you can generate truly random passwords and save them encrypted using your public key (as separate `.gpg` files under `~/.password-store/`):
|
||||
```
|
||||
$ pass generate Dev/github 32
|
||||
$ pass generate Social/hackernews 32
|
||||
$ pass generate Social/twitter 32
|
||||
$ pass generate VPS/linode 32
|
||||
$ pass
|
||||
Password Store
|
||||
├── Dev
|
||||
│ └── github
|
||||
├── Social
|
||||
│ ├── hackernews
|
||||
│ └── twitter
|
||||
└── VPS
|
||||
└── linode
|
||||
```
|
||||
In order to paste them into the browser, you'd need to decrypt the password using your hardware device:
|
||||
```
|
||||
$ pass --clip VPS/linode
|
||||
Copied VPS/linode to clipboard. Will clear in 45 seconds.
|
||||
```
|
||||
|
||||
You can also use the following [Qt-based UI](https://qtpass.org/) for `pass`:
|
||||
```
|
||||
$ sudo apt install qtpass
|
||||
```
|
||||
|
||||
### Re-generate a GPG identity
|
||||
[![asciicast](https://asciinema.org/a/5tIQa5qt5bV134oeOqFyKEU29.png)](https://asciinema.org/a/5tIQa5qt5bV134oeOqFyKEU29)
|
||||
|
||||
If you've forgotten the timestamp value, but still have access to the public key, then you can
|
||||
retrieve the timestamp with the following command (substitute "john@doe.bit" for the key's address or id):
|
||||
|
||||
```
|
||||
$ gpg2 --export 'john@doe.bit' | gpg2 --list-packets | grep created | head -n1
|
||||
```
|
||||
|
||||
### Add new UIDs to your identity
|
||||
|
||||
After your main identity is created, you can add new user IDs using the regular GnuPG commands:
|
||||
```
|
||||
$ trezor-gpg init "Foobar" -vv
|
||||
$ export GNUPGHOME=${HOME}/.gnupg/trezor
|
||||
$ gpg2 -K
|
||||
------------------------------------------
|
||||
sec nistp256/6275E7DA 2017-12-05 [SC]
|
||||
uid [ultimate] Foobar
|
||||
ssb nistp256/35F58F26 2017-12-05 [E]
|
||||
|
||||
$ gpg2 --edit Foobar
|
||||
gpg> adduid
|
||||
Real name: Xyzzy
|
||||
Email address:
|
||||
Comment:
|
||||
You selected this USER-ID:
|
||||
"Xyzzy"
|
||||
|
||||
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
|
||||
|
||||
gpg> save
|
||||
|
||||
$ gpg2 -K
|
||||
------------------------------------------
|
||||
sec nistp256/6275E7DA 2017-12-05 [SC]
|
||||
uid [ultimate] Xyzzy
|
||||
uid [ultimate] Foobar
|
||||
ssb nistp256/35F58F26 2017-12-05 [E]
|
||||
```
|
||||
|
||||
### Generate GnuPG subkeys
|
||||
In order to add TREZOR-based subkey to an existing GnuPG identity, use the `--subkey` flag:
|
||||
```
|
||||
$ gpg2 -k foobar
|
||||
pub rsa2048/90C4064B 2017-10-10 [SC]
|
||||
uid [ultimate] foobar
|
||||
sub rsa2048/4DD05FF0 2017-10-10 [E]
|
||||
|
||||
$ trezor-gpg init "foobar" --subkey
|
||||
```
|
||||
|
||||
[![asciicast](https://asciinema.org/a/Ick5G724zrZRFsGY7ZUdFSnV1.png)](https://asciinema.org/a/Ick5G724zrZRFsGY7ZUdFSnV1)
|
||||
|
||||
In order to enter existing GPG passphrase, I recommend installing and using a graphical Pinentry:
|
||||
```
|
||||
$ sudo apt install pinentry-gnome3
|
||||
$ sudo update-alternatives --config pinentry
|
||||
There are 4 choices for the alternative pinentry (providing /usr/bin/pinentry).
|
||||
|
||||
Selection Path Priority Status
|
||||
------------------------------------------------------------
|
||||
* 0 /usr/bin/pinentry-gnome3 90 auto mode
|
||||
1 /usr/bin/pinentry-curses 50 manual mode
|
||||
2 /usr/bin/pinentry-gnome3 90 manual mode
|
||||
3 /usr/bin/pinentry-qt 80 manual mode
|
||||
4 /usr/bin/pinentry-tty 30 manual mode
|
||||
|
||||
Press <enter> to keep the current choice[*], or type selection number: 0
|
||||
```
|
||||
|
||||
### Sign and decrypt email
|
||||
|
||||
Follow [these instructions](enigmail.md) to set up Enigmail in Thunderbird.
|
||||
|
||||
### Start the agent as a systemd unit
|
||||
|
||||
##### 1. Create these files in `~/.config/systemd/user`
|
||||
|
||||
Replace `trezor` with `keepkey` or `ledger` as required.
|
||||
|
||||
###### `trezor-gpg-agent.service`
|
||||
|
||||
````
|
||||
[Unit]
|
||||
Description=trezor-gpg-agent
|
||||
Requires=trezor-gpg-agent.socket
|
||||
|
||||
[Service]
|
||||
Type=Simple
|
||||
Environment="GNUPGHOME=%h/.gnupg/trezor"
|
||||
Environment="PATH=/bin:/usr/bin:/usr/local/bin:%h/.local/bin"
|
||||
ExecStart=/usr/bin/trezor-gpg-agent -vv
|
||||
````
|
||||
|
||||
If you've installed `trezor-agent` locally you may have to change the path in `ExecStart=`.
|
||||
|
||||
###### `trezor-gpg-agent.socket`
|
||||
|
||||
````
|
||||
[Unit]
|
||||
Description=trezor-gpg-agent socket
|
||||
|
||||
[Socket]
|
||||
ListenStream=%t/gnupg/S.gpg-agent
|
||||
FileDescriptorName=std
|
||||
SocketMode=0600
|
||||
DirectoryMode=0700
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
````
|
||||
|
||||
##### 2. Stop trezor-gpg-agent if it's already running
|
||||
|
||||
```
|
||||
killall trezor-gpg-agent
|
||||
```
|
||||
|
||||
##### 3. Run
|
||||
|
||||
```
|
||||
systemctl --user start trezor-gpg-agent.service trezor-gpg-agent.socket
|
||||
systemctl --user enable trezor-gpg-agent.socket
|
||||
```
|
@ -0,0 +1,31 @@
|
||||
# NeoPG experimental support
|
||||
|
||||
1. Download build and install NeoPG from [source code](https://github.com/das-labor/neopg#installation).
|
||||
|
||||
2. Generate Ed25519-based identity (using a [special wrapper](https://github.com/romanz/trezor-agent/blob/c22109df24c6eb8263aa40183a016be3437b1a0c/contrib/neopg-trezor) to invoke TREZOR-based agent):
|
||||
|
||||
```bash
|
||||
$ export NEOPG_BINARY=$PWD/contrib/neopg-trezor
|
||||
$ $NEOPG_BINARY --help
|
||||
|
||||
$ export GNUPGHOME=/tmp/homedir
|
||||
$ trezor-gpg init "FooBar" -e ed25519
|
||||
sec ed25519 2018-07-01 [SC]
|
||||
802AF7E2DCF4491FFBB2F032341E95EF57CD7D5E
|
||||
uid [ultimate] FooBar
|
||||
ssb cv25519 2018-07-01 [E]
|
||||
```
|
||||
|
||||
3. Sign and verify signatures:
|
||||
```
|
||||
$ $NEOPG_BINARY -v --detach-sign FILE
|
||||
neopg: starting agent '/home/roman/Code/trezor/trezor-agent/contrib/neopg-trezor'
|
||||
neopg: using pgp trust model
|
||||
neopg: writing to 'FILE.sig'
|
||||
neopg: EDDSA/SHA256 signature from: "341E95EF57CD7D5E FooBar"
|
||||
|
||||
$ $NEOPG_BINARY --verify FILE.sig FILE
|
||||
neopg: Signature made Sun Jul 1 11:52:51 2018 IDT
|
||||
neopg: using EDDSA key 802AF7E2DCF4491FFBB2F032341E95EF57CD7D5E
|
||||
neopg: Good signature from "FooBar" [ultimate]
|
||||
```
|
@ -0,0 +1,69 @@
|
||||
# Custom PIN entry
|
||||
|
||||
In order to use the default GPG pinentry program, install one of the following Linux packages:
|
||||
|
||||
```
|
||||
$ apt install pinentry-{curses,gnome3,qt}
|
||||
```
|
||||
|
||||
or (on macOS):
|
||||
|
||||
```
|
||||
$ brew install pinentry
|
||||
```
|
||||
|
||||
By default a standard GPG PIN entry program is used when entering your Trezor PIN, but it's difficult to use if you don't have a numeric keypad or want to use your mouse.
|
||||
|
||||
You can specify a custom PIN entry program such as [trezor-gpg-pinentry-tk](https://github.com/rendaw/trezor-gpg-pinentry-tk) (and separately, a passphrase entry program) to match your workflow.
|
||||
|
||||
The below examples use `trezor-gpg-pinentry-tk` but any GPG compatible PIN entry can be used.
|
||||
|
||||
##### 1. Install the PIN entry
|
||||
|
||||
Run
|
||||
|
||||
```
|
||||
pip install trezor-gpg-pinentry-tk
|
||||
```
|
||||
|
||||
##### 2. SSH
|
||||
|
||||
Add the flag `--pin-entry-binary trezor-gpg-pinentry-tk` to all calls to `trezor-agent`.
|
||||
|
||||
To automatically use this flag, add the line `pinentry=trezor-gpg-pinentry-tk` to `~/.ssh/agent.config`. **Note** this is currently broken due to [this dependency issue](https://github.com/bw2/ConfigArgParse/issues/114).
|
||||
|
||||
If you run the SSH agent with Systemd you'll need to add `--pin-entry-binary` to the `ExecStart` command. You may also need to add this line:
|
||||
|
||||
```
|
||||
Environment="DISPLAY=:0"
|
||||
```
|
||||
|
||||
to the `[Service]` section to tell the PIN entry program how to connect to the X11 server.
|
||||
|
||||
##### 3. GPG
|
||||
|
||||
If you haven't completed initialization yet, run:
|
||||
|
||||
```
|
||||
$ (trezor|keepkey|ledger)-gpg init --pin-entry-binary trezor-gpg-pinentry-tk "Roman Zeyde <roman.zeyde@gmail.com>"
|
||||
```
|
||||
|
||||
to configure the PIN entry at the same time.
|
||||
|
||||
Otherwise, open `$GNUPGHOME/trezor/run-agent.sh` and change the `--pin-entry-binary` option to `trezor-gpg-pinentry-tk` and run:
|
||||
|
||||
```
|
||||
killall trezor-gpg-agent
|
||||
```
|
||||
|
||||
##### 4. Troubleshooting
|
||||
|
||||
Any problems running the PIN entry program with GPG should appear in `$HOME/.gnupg/trezor/gpg-agent.log`.
|
||||
|
||||
You can get similar logs for SSH by specifying `--log-file` in the SSH command line.
|
||||
|
||||
The passphrase is cached by the agent (after its first entry), which needs to be restarted in order to reset the passphrase:
|
||||
```
|
||||
$ killall trezor-agent # (for SSH)
|
||||
$ killall trezor-gpg-agent # (for GPG)
|
||||
```
|
@ -0,0 +1,209 @@
|
||||
# SSH Agent
|
||||
|
||||
## 1. Configuration
|
||||
|
||||
SSH requires no configuration, but you may put common command line options in `~/.ssh/agent.conf` to avoid repeating them in every invocation.
|
||||
|
||||
See `(trezor|keepkey|ledger)-agent -h` for details on supported options and the configuration file format.
|
||||
|
||||
If you'd like a Trezor-style PIN entry program, follow [these instructions](README-PINENTRY.md).
|
||||
|
||||
## 2. Usage
|
||||
|
||||
Use the `(trezor|keepkey|ledger)-agent` program to work with SSH. It has three main modes of operation:
|
||||
|
||||
##### 1. Export public keys
|
||||
|
||||
To get your public key so you can add it to `authorized_hosts` or allow
|
||||
ssh access to a service that supports it, run:
|
||||
|
||||
```
|
||||
(trezor|keepkey|ledger)-agent identity@myhost
|
||||
```
|
||||
|
||||
The identity (ex: `identity@myhost`) is used to derive the public key and is added as a comment to the exported key string.
|
||||
|
||||
##### 2. Run a command with the agent's environment
|
||||
|
||||
Run
|
||||
|
||||
```
|
||||
$ (trezor|keepkey|ledger)-agent identity@myhost -- COMMAND --WITH --ARGUMENTS
|
||||
```
|
||||
|
||||
to start the agent in the background and execute the command with environment variables set up to use the SSH agent. The specified identity is used for all SSH connections. The agent will exit after the command completes.
|
||||
Note the `--` separator, which is used to separate `trezor-agent`'s arguments from the SSH command arguments.
|
||||
|
||||
As a shortcut you can run
|
||||
|
||||
```
|
||||
$ (trezor|keepkey|ledger)-agent identity@myhost -s
|
||||
```
|
||||
|
||||
to start a shell with the proper environment.
|
||||
|
||||
##### 2. Connect to a server directly via `(trezor|keepkey|ledger)-agent`
|
||||
|
||||
If you just want to connect to a server this is the simplest way to do it:
|
||||
|
||||
```
|
||||
$ (trezor|keepkey|ledger)-agent user@remotehost -c
|
||||
```
|
||||
|
||||
The identity `user@remotehost` is used as both the destination user and host as well as for key derivation, so you must generate a separate key for each host you connect to.
|
||||
|
||||
## 3. Common Use Cases
|
||||
|
||||
### Start a single SSH session
|
||||
[![Demo](https://asciinema.org/a/22959.png)](https://asciinema.org/a/22959)
|
||||
|
||||
### Start multiple SSH sessions from a sub-shell
|
||||
|
||||
This feature allows using regular SSH-related commands within a subprocess running user's shell.
|
||||
`SSH_AUTH_SOCK` environment variable is defined for the subprocess (pointing to the SSH agent, running as a parent process).
|
||||
This way the user can use SSH-related commands (e.g. `ssh`, `ssh-add`, `sshfs`, `git`, `hg`), while authenticating via the hardware device.
|
||||
|
||||
[![Subshell](https://asciinema.org/a/33240.png)](https://asciinema.org/a/33240)
|
||||
|
||||
### Load different SSH identities from configuration file
|
||||
|
||||
[![Config](https://asciinema.org/a/bdxxtgctk5syu56yfz8lcp7ny.png)](https://asciinema.org/a/bdxxtgctk5syu56yfz8lcp7ny)
|
||||
|
||||
### Implement passwordless login
|
||||
|
||||
Run:
|
||||
|
||||
/tmp $ trezor-agent user@ssh.hostname.com -v > hostname.pub
|
||||
2015-09-02 15:03:18,929 INFO getting "ssh://user@ssh.hostname.com" public key from Trezor...
|
||||
2015-09-02 15:03:23,342 INFO disconnected from Trezor
|
||||
/tmp $ cat hostname.pub
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGSevcDwmT+QaZPUEWUUjTeZRBICChxMKuJ7dRpBSF8+qt+8S1GBK5Zj8Xicc8SHG/SE/EXKUL2UU3kcUzE7ADQ= ssh://user@ssh.hostname.com
|
||||
|
||||
Append `hostname.pub` contents to `/home/user/.ssh/authorized_keys`
|
||||
configuration file at `ssh.hostname.com`, so the remote server
|
||||
would allow you to login using the corresponding private key signature.
|
||||
|
||||
### Access remote Git/Mercurial repositories
|
||||
|
||||
Export your public key and register it in your repository web interface
|
||||
(e.g. [GitHub](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/)):
|
||||
|
||||
$ trezor-agent -v -e ed25519 git@github.com > ~/.ssh/github.pub
|
||||
|
||||
Add the following configuration to your `~/.ssh/config` file:
|
||||
|
||||
Host github.com
|
||||
IdentityFile ~/.ssh/github.pub
|
||||
|
||||
Use the following Bash alias for convenient Git operations:
|
||||
|
||||
$ alias ssh-shell='trezor-agent ~/.ssh/github.pub -v --shell'
|
||||
|
||||
Now, you can use regular Git commands under the "SSH-enabled" sub-shell:
|
||||
|
||||
$ ssh-shell
|
||||
$ git push origin master
|
||||
|
||||
The same works for Mercurial (e.g. on [BitBucket](https://confluence.atlassian.com/bitbucket/set-up-ssh-for-mercurial-728138122.html)):
|
||||
|
||||
$ ssh-shell
|
||||
$ hg push
|
||||
|
||||
### Start the agent as a systemd unit
|
||||
|
||||
##### 1. Create these files in `~/.config/systemd/user`
|
||||
|
||||
Replace `trezor` with `keepkey` or `ledger` as required.
|
||||
|
||||
###### `trezor-ssh-agent.service`
|
||||
|
||||
````
|
||||
[Unit]
|
||||
Description=trezor-agent SSH agent
|
||||
Requires=trezor-ssh-agent.socket
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment="DISPLAY=:0"
|
||||
Environment="PATH=/bin:/usr/bin:/usr/local/bin:%h/.local/bin"
|
||||
ExecStart=/usr/bin/trezor-agent --foreground --sock-path %t/trezor-agent/S.ssh IDENTITY
|
||||
````
|
||||
|
||||
If you've installed `trezor-agent` locally you may have to change the path in `ExecStart=`.
|
||||
|
||||
Replace `IDENTITY` with the identity you used when exporting the public key.
|
||||
|
||||
If you have multiple Trezors connected, you can select which one to use via a `TREZOR_PATH`
|
||||
environment variable. Use `trezorctl list` to find the correct path. Then add it
|
||||
to the agent with the following line:
|
||||
````
|
||||
Environment="TREZOR_PATH=<your path here>"
|
||||
````
|
||||
Note that USB paths depend on the _USB port_ which you use.
|
||||
|
||||
###### `trezor-ssh-agent.socket`
|
||||
|
||||
````
|
||||
[Unit]
|
||||
Description=trezor-agent SSH agent socket
|
||||
|
||||
[Socket]
|
||||
ListenStream=%t/trezor-agent/S.ssh
|
||||
FileDescriptorName=ssh
|
||||
Service=trezor-ssh-agent.service
|
||||
SocketMode=0600
|
||||
DirectoryMode=0700
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
````
|
||||
|
||||
##### 2. Run
|
||||
|
||||
```
|
||||
systemctl --user start trezor-ssh-agent.service trezor-ssh-agent.socket
|
||||
systemctl --user enable trezor-ssh-agent.socket
|
||||
```
|
||||
|
||||
##### 3. Add this line to your `.bashrc` or equivalent file:
|
||||
|
||||
```bash
|
||||
export SSH_AUTH_SOCK=$(systemctl show --user --property=Listen trezor-ssh-agent.socket | grep -o "/run.*")
|
||||
```
|
||||
|
||||
##### 4. SSH will now automatically use your device key in all terminals.
|
||||
|
||||
## 4. Troubleshooting
|
||||
|
||||
If SSH connection fails to work, please open an [issue](https://github.com/romanz/trezor-agent/issues)
|
||||
with a verbose log attached (by running `trezor-agent -vv`) .
|
||||
|
||||
##### `IdentitiesOnly` SSH option
|
||||
|
||||
Note that your local SSH configuration may ignore `trezor-agent`, if it has `IdentitiesOnly` option set to `yes`.
|
||||
|
||||
IdentitiesOnly
|
||||
Specifies that ssh(1) should only use the authentication identity files configured in
|
||||
the ssh_config files, even if ssh-agent(1) or a PKCS11Provider offers more identities.
|
||||
The argument to this keyword must be “yes” or “no”.
|
||||
This option is intended for situations where ssh-agent offers many different identities.
|
||||
The default is “no”.
|
||||
|
||||
If you are failing to connect, save your public key using:
|
||||
|
||||
$ trezor-agent -vv foobar@hostname.com > ~/.ssh/hostname.pub
|
||||
|
||||
And add the following lines to `~/.ssh/config` (providing the public key explicitly to SSH):
|
||||
|
||||
Host hostname.com
|
||||
User foobar
|
||||
IdentityFile ~/.ssh/hostname.pub
|
||||
|
||||
Then, the following commands should successfully command to the remote host:
|
||||
|
||||
$ trezor-agent -v foobar@hostname.com -s
|
||||
$ ssh foobar@hostname.com
|
||||
|
||||
or,
|
||||
|
||||
$ trezor-agent -v foobar@hostname.com -c
|
@ -0,0 +1,26 @@
|
||||
# Tutorial
|
||||
|
||||
First, install [Thunderbird](https://www.mozilla.org/en-US/thunderbird/) and
|
||||
the [Enigmail](https://www.enigmail.net/index.php/en/) add-on.
|
||||
|
||||
Make sure to use the correct GNUPGHOME path before starting Thunderbird:
|
||||
```bash
|
||||
$ export GNUPGHOME=${HOME}/.gnupg/trezor
|
||||
$ thunderbird
|
||||
```
|
||||
Run the Enigmail's setup wizard and choose your GPG identity:
|
||||
![01](https://user-images.githubusercontent.com/9900/31327339-47a5f69a-acd7-11e7-997c-7b5a286fe5bc.png)
|
||||
![02](https://user-images.githubusercontent.com/9900/31327344-51dcd246-acd7-11e7-8cdc-dd305a512dbb.png)
|
||||
![03](https://user-images.githubusercontent.com/9900/31327346-546862a0-acd7-11e7-8e00-b40994bd6f17.png)
|
||||
|
||||
Then, you can compose encrypted (and signed) messages using the regular UI:
|
||||
|
||||
NOTES:
|
||||
- The email's title is **public** - only the body is encrypted.
|
||||
- You will be asked to confirm the signature using the hardware device before sending the email.
|
||||
|
||||
![04](https://user-images.githubusercontent.com/9900/31327356-660d098e-acd7-11e7-9e43-762898f5b57e.png)
|
||||
![05](https://user-images.githubusercontent.com/9900/31327365-76679dda-acd7-11e7-9403-6965f0c6d8fe.png)
|
||||
|
||||
After receiving the email, you will be asked to confirm the decryption the hardware device:
|
||||
![06](https://user-images.githubusercontent.com/9900/31327371-7c1da4cc-acd7-11e7-9a5a-20accf621b49.png)
|
@ -1,3 +1,3 @@
|
||||
"""Cryptographic hardware device management."""
|
||||
|
||||
from . import interface
|
||||
from . import interface, ui
|
||||
|
@ -1,10 +1,28 @@
|
||||
"""TREZOR-related definitions."""
|
||||
|
||||
# pylint: disable=unused-import,import-error
|
||||
import os
|
||||
import logging
|
||||
|
||||
from trezorlib.client import CallException as Error
|
||||
from trezorlib.client import CallException, PinException
|
||||
from trezorlib.client import TrezorClient as Client
|
||||
from trezorlib.messages_pb2 import PassphraseAck, PinMatrixAck
|
||||
from trezorlib.transport_bridge import BridgeTransport
|
||||
from trezorlib.transport_hid import HidTransport
|
||||
from trezorlib.types_pb2 import IdentityType
|
||||
from trezorlib.messages import IdentityType, PassphraseAck, PinMatrixAck, PassphraseStateAck
|
||||
|
||||
try:
|
||||
from trezorlib.transport import get_transport
|
||||
except ImportError:
|
||||
from trezorlib.device import TrezorDevice
|
||||
get_transport = TrezorDevice.find_by_path
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def find_device():
|
||||
"""Selects a transport based on `TREZOR_PATH` environment variable.
|
||||
|
||||
If unset, picks first connected device.
|
||||
"""
|
||||
try:
|
||||
return get_transport(os.environ.get("TREZOR_PATH"))
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
log.debug("Failed to find a Trezor device: %s", e)
|
||||
|
@ -0,0 +1,129 @@
|
||||
"""UIs for PIN/passphrase entry."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from .. import util
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UI:
|
||||
"""UI for PIN/passphrase entry (for TREZOR devices)."""
|
||||
|
||||
def __init__(self, device_type, config=None):
|
||||
"""C-tor."""
|
||||
default_pinentry = 'pinentry' # by default, use GnuPG pinentry tool
|
||||
if config is None:
|
||||
config = {}
|
||||
self.pin_entry_binary = config.get('pin_entry_binary',
|
||||
default_pinentry)
|
||||
self.passphrase_entry_binary = config.get('passphrase_entry_binary',
|
||||
default_pinentry)
|
||||
self.options_getter = create_default_options_getter()
|
||||
self.device_name = device_type.__name__
|
||||
|
||||
def get_pin(self, name=None):
|
||||
"""Ask the user for (scrambled) PIN."""
|
||||
description = (
|
||||
'Use the numeric keypad to describe number positions.\n'
|
||||
'The layout is:\n'
|
||||
' 7 8 9\n'
|
||||
' 4 5 6\n'
|
||||
' 1 2 3')
|
||||
return interact(
|
||||
title='{} PIN'.format(name or self.device_name),
|
||||
prompt='PIN:',
|
||||
description=description,
|
||||
binary=self.pin_entry_binary,
|
||||
options=self.options_getter())
|
||||
|
||||
def get_passphrase(self, name=None):
|
||||
"""Ask the user for passphrase."""
|
||||
return interact(
|
||||
title='{} passphrase'.format(name or self.device_name),
|
||||
prompt='Passphrase:',
|
||||
description=None,
|
||||
binary=self.passphrase_entry_binary,
|
||||
options=self.options_getter())
|
||||
|
||||
|
||||
def create_default_options_getter():
|
||||
"""Return current TTY and DISPLAY settings for GnuPG pinentry."""
|
||||
options = []
|
||||
try:
|
||||
ttyname = subprocess.check_output(args=['tty']).strip()
|
||||
options.append(b'ttyname=' + ttyname)
|
||||
except subprocess.CalledProcessError as e:
|
||||
log.warning('no TTY found: %s', e)
|
||||
|
||||
display = os.environ.get('DISPLAY')
|
||||
if display is not None:
|
||||
options.append('display={}'.format(display).encode('ascii'))
|
||||
else:
|
||||
log.warning('DISPLAY not defined')
|
||||
|
||||
log.info('using %s for pinentry options', options)
|
||||
return lambda: options
|
||||
|
||||
|
||||
def write(p, line):
|
||||
"""Send and flush a single line to the subprocess' stdin."""
|
||||
log.debug('%s <- %r', p.args, line)
|
||||
p.stdin.write(line)
|
||||
p.stdin.flush()
|
||||
|
||||
|
||||
class UnexpectedError(Exception):
|
||||
"""Unexpected response."""
|
||||
|
||||
|
||||
def expect(p, prefixes, confidential=False):
|
||||
"""Read a line and return it without required prefix."""
|
||||
resp = p.stdout.readline()
|
||||
log.debug('%s -> %r', p.args, resp if not confidential else '********')
|
||||
for prefix in prefixes:
|
||||
if resp.startswith(prefix):
|
||||
return resp[len(prefix):]
|
||||
raise UnexpectedError(resp)
|
||||
|
||||
|
||||
def interact(title, description, prompt, binary, options):
|
||||
"""Use GPG pinentry program to interact with the user."""
|
||||
args = [binary]
|
||||
p = subprocess.Popen(args=args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
env=os.environ)
|
||||
p.args = args # TODO: remove after Python 2 deprecation.
|
||||
expect(p, [b'OK'])
|
||||
|
||||
title = util.assuan_serialize(title.encode('ascii'))
|
||||
write(p, b'SETTITLE ' + title + b'\n')
|
||||
expect(p, [b'OK'])
|
||||
|
||||
if description:
|
||||
description = util.assuan_serialize(description.encode('ascii'))
|
||||
write(p, b'SETDESC ' + description + b'\n')
|
||||
expect(p, [b'OK'])
|
||||
|
||||
if prompt:
|
||||
prompt = util.assuan_serialize(prompt.encode('ascii'))
|
||||
write(p, b'SETPROMPT ' + prompt + b'\n')
|
||||
expect(p, [b'OK'])
|
||||
|
||||
log.debug('setting %d options', len(options))
|
||||
for opt in options:
|
||||
write(p, b'OPTION ' + opt + b'\n')
|
||||
expect(p, [b'OK', b'ERR'])
|
||||
|
||||
write(p, b'GETPIN\n')
|
||||
pin = expect(p, [b'OK', b'D '], confidential=True)
|
||||
|
||||
p.communicate() # close stdin and wait for the process to exit
|
||||
exit_code = p.wait()
|
||||
if exit_code:
|
||||
raise subprocess.CalledProcessError(exit_code, binary)
|
||||
|
||||
return pin.decode('ascii').strip()
|
@ -0,0 +1,11 @@
|
||||
from .. import agent
|
||||
|
||||
|
||||
def test_sig_encode():
|
||||
SIG = (
|
||||
b'(7:sig-val(5:ecdsa(1:r32:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x0c)(1:s32:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00")))')
|
||||
assert agent.sig_encode(12, 34) == SIG
|
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -eux
|
||||
rm -rv dist/*
|
||||
python3 setup.py sdist
|
||||
gpg2 -v --detach-sign -a dist/*.tar.gz
|
||||
twine upload dist/*
|
@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
USER_ID="${1}"
|
||||
DEVICE=${DEVICE:="trezor"} # or "ledger"
|
||||
CURVE=${CURVE:="nist256p1"} # or "ed25519"
|
||||
TIMESTAMP=${TIMESTAMP:=`date +%s`} # key creation timestamp
|
||||
HOMEDIR=~/.gnupg/${DEVICE}
|
||||
|
||||
# NOTE: starting from GnuPG 2.2, gpg2 -> gpg
|
||||
GPG_BINARY=$(python -c "import libagent.gpg.keyring as k; print(k.get_gnupg_binary())")
|
||||
${GPG_BINARY} --version # verify that GnuPG 2.1+ is installed
|
||||
|
||||
# Prepare new GPG home directory for hardware-based identity
|
||||
rm -rf "${HOMEDIR}"
|
||||
mkdir -p "${HOMEDIR}"
|
||||
chmod 700 "${HOMEDIR}"
|
||||
|
||||
# Generate new GPG identity and import into GPG keyring
|
||||
$DEVICE-gpg create -v "${USER_ID}" -t "${TIMESTAMP}" -e "${CURVE}" > "${HOMEDIR}/pubkey.asc"
|
||||
${GPG_BINARY} --homedir "${HOMEDIR}" --import < "${HOMEDIR}/pubkey.asc" 2> /dev/null
|
||||
rm -f "${HOMEDIR}/S.gpg-agent" # (otherwise, our agent won't be started automatically)
|
||||
|
||||
# Make new GPG identity with "ultimate" trust (via its fingerprint)
|
||||
FINGERPRINT=$(${GPG_BINARY} --homedir "${HOMEDIR}" --list-public-keys --with-fingerprint --with-colons | sed -n -E 's/^fpr:::::::::([0-9A-F]+):$/\1/p' | head -n1)
|
||||
echo "${FINGERPRINT}:6" | ${GPG_BINARY} --homedir "${HOMEDIR}" --import-ownertrust 2> /dev/null
|
||||
|
||||
AGENT_PATH="$(which ${DEVICE}-gpg-agent)"
|
||||
|
||||
# Prepare GPG configuration file
|
||||
echo "# Hardware-based GPG configuration
|
||||
agent-program ${AGENT_PATH}
|
||||
personal-digest-preferences SHA512
|
||||
default-key \"${USER_ID}\"
|
||||
" > "${HOMEDIR}/gpg.conf"
|
||||
|
||||
# Prepare GPG agent configuration file
|
||||
echo "# Hardware-based GPG agent emulator
|
||||
log-file ${HOMEDIR}/gpg-agent.log
|
||||
verbosity 2
|
||||
" > "${HOMEDIR}/gpg-agent.conf"
|
||||
|
||||
# Prepare a helper script for setting up the new identity
|
||||
echo "#!/bin/bash
|
||||
set -eu
|
||||
export GNUPGHOME=${HOMEDIR}
|
||||
COMMAND=\$*
|
||||
if [ -z \"\${COMMAND}\" ]
|
||||
then
|
||||
\${SHELL}
|
||||
else
|
||||
\${COMMAND}
|
||||
fi
|
||||
" > "${HOMEDIR}/env"
|
||||
chmod u+x "${HOMEDIR}/env"
|
||||
|
||||
echo "Starting ${DEVICE}-gpg-agent at ${HOMEDIR}..."
|
||||
# Load agent and make sure it responds with the new identity
|
||||
GNUPGHOME="${HOMEDIR}" ${GPG_BINARY} -K 2> /dev/null
|
Loading…
Reference in New Issue