Implemented trezor-restore feature and fixed tmux-buttons bug

This commit is contained in:
Sun Knudsen 2021-04-22 09:33:45 -04:00
parent 1aa5bc79b1
commit 943c893a6f
No known key found for this signature in database
GPG key ID: 1FA767862BBD1305
7 changed files with 194 additions and 74 deletions

View file

@ -45,7 +45,7 @@ ssh pi@10.0.1.248 -i ~/.ssh/pi
```console
$ sudo apt update
$ sudo apt install -y git python3-pip
$ sudo apt install -y git python3-pip python3-rpi.gpio
$ sudo pip3 install adafruit-python-shell click==7.0
@ -230,7 +230,7 @@ $ pip3 install --user Electrum-$ELECTRUM_RELEASE_SEMVER.tar.gz
$ rm Electrum-$ELECTRUM_RELEASE_SEMVER.tar.gz*
```
### Step 8: install `tmux` and [trezorcrl](https://wiki.trezor.io/Using_trezorctl_commands_with_Trezor) (used to verify integrity of [Trezor](https://trezor.io/) devices)
### Step 8: install `tmux` and [trezorcrl](https://wiki.trezor.io/Using_trezorctl_commands_with_Trezor) (used to verify integrity of and restore [Trezor](https://trezor.io/) devices)
```console
$ sudo apt update
@ -242,17 +242,7 @@ $ pip3 install attrs trezor --user
$ sudo curl -o /etc/udev/rules.d/51-trezor.rules https://data.trezor.io/udev/51-trezor.rules
```
### Step 9: install `python3-rpi.gpio` and `keyboard` (used to control `tmux` panes)
```console
$ sudo apt update
$ sudo apt install -y python3-rpi.gpio
$ sudo pip3 install keyboard
```
### Step 10: import Suns PGP public key (used to verify downloads bellow)
### Step 9: import Suns PGP public key (used to verify downloads bellow)
```console
$ curl https://sunknudsen.com/sunknudsen.asc | gpg --import
@ -268,7 +258,7 @@ imported: 1
👍
### Step 11: download and verify [create-bip39-mnemonic.py](./create-bip39-mnemonic.py)
### Step 10: download and verify [create-bip39-mnemonic.py](./create-bip39-mnemonic.py)
```console
$ curl -o /home/pi/.local/bin/create-bip39-mnemonic.py https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/create-bip39-mnemonic.py
@ -302,7 +292,7 @@ Good signature
👍
### Step 12: download and verify [validate-bip39-mnemonic.py](./validate-bip39-mnemonic.py)
### Step 11: download and verify [validate-bip39-mnemonic.py](./validate-bip39-mnemonic.py)
```console
$ curl -o /home/pi/.local/bin/validate-bip39-mnemonic.py https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/validate-bip39-mnemonic.py
@ -336,7 +326,7 @@ Good signature
👍
### Step 13: download and verify [tmux-buttons.py](./tmux-buttons.py)
### Step 12: download and verify [tmux-buttons.py](./tmux-buttons.py)
```console
$ curl -o /home/pi/.local/bin/tmux-buttons.py https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/tmux-buttons.py
@ -351,7 +341,7 @@ $ curl -o /home/pi/.local/bin/tmux-buttons.py.sig https://sunknudsen.com/static/
$ gpg --verify /home/pi/.local/bin/tmux-buttons.py.sig
gpg: assuming signed data in '/home/pi/.local/bin/tmux-buttons.py'
gpg: Signature made Wed 21 Apr 2021 09:23:12 EDT
gpg: Signature made Thu Apr 22 09:13:47 2021 EDT
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
@ -370,7 +360,7 @@ Good signature
👍
### Step 14: download and verify [qr-backup.sh](./qr-backup.sh)
### Step 13: download and verify [qr-backup.sh](./qr-backup.sh)
```console
$ curl -o /home/pi/.local/bin/qr-backup.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-backup.sh
@ -404,7 +394,7 @@ Good signature
👍
### Step 15: download and verify [qr-restore.sh](./qr-restore.sh)
### Step 14: download and verify [qr-restore.sh](./qr-restore.sh)
```console
$ curl -o /home/pi/.local/bin/qr-restore.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-restore.sh
@ -438,7 +428,7 @@ Good signature
👍
### Step 16: download and verify [qr-clone.sh](./qr-clone.sh)
### Step 15: download and verify [qr-clone.sh](./qr-clone.sh)
```console
$ curl -o /home/pi/.local/bin/qr-clone.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/qr-clone.sh
@ -472,7 +462,7 @@ Good signature
👍
### Step 17: download and verify [secure-erase.sh](./secure-erase.sh)
### Step 16: download and verify [secure-erase.sh](./secure-erase.sh)
```console
$ curl -o /home/pi/.local/bin/secure-erase.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/secure-erase.sh
@ -506,7 +496,7 @@ Good signature
👍
### Step 18: download and verify [trezor-verify-integrity.sh](./trezor-verify-integrity.sh) (used to validate Trezor devices)
### Step 17: download and verify [trezor-verify-integrity.sh](./trezor-verify-integrity.sh) (used to validate Trezor devices)
```console
$ curl -o /home/pi/.local/bin/trezor-verify-integrity.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/trezor-verify-integrity.sh
@ -521,7 +511,7 @@ $ curl -o /home/pi/.local/bin/trezor-verify-integrity.sh.sig https://sunknudsen.
$ gpg --verify /home/pi/.local/bin/trezor-verify-integrity.sh.sig
gpg: assuming signed data in '/home/pi/.local/bin/trezor-verify-integrity.sh'
gpg: Signature made Wed Apr 21 13:15:30 2021 EDT
gpg: Signature made Thu Apr 22 09:13:56 2021 EDT
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
@ -540,6 +530,40 @@ Good signature
👍
### Step 18: download and verify [trezor-restore.sh](./trezor-restore.sh) (used to validate Trezor devices)
```console
$ curl -o /home/pi/.local/bin/trezor-restore.sh https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/trezor-restore.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1283 100 1283 0 0 1189 0 0:00:01 0:00:01 --:--:-- 1189
$ curl -o /home/pi/.local/bin/trezor-restore.sh.sig https://sunknudsen.com/static/media/privacy-guides/how-to-create-encrypted-paper-backup/trezor-restore.sh.sig
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 833 100 833 0 0 944 0 --:--:-- --:--:-- --:--:-- 944
$ gpg --verify /home/pi/.local/bin/trezor-restore.sh.sig
gpg: assuming signed data in '/home/pi/.local/bin/trezor-restore.sh'
gpg: Signature made Thu Apr 22 09:14:04 2021 EDT
gpg: using RSA key A98CCD122243655B26FAFB611FA767862BBD1305
gpg: Good signature from "Sun Knudsen <hello@sunknudsen.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: C4FB DDC1 6A26 2672 920D 0A0F C132 3A37 7DE1 4C8B
Subkey fingerprint: A98C CD12 2243 655B 26FA FB61 1FA7 6786 2BBD 1305
$ chmod 700 /home/pi/.local/bin/trezor-restore.sh
```
Primary key fingerprint matches [published](../how-to-encrypt-sign-and-decrypt-messages-using-gnupg-on-macos#verify-suns-pgp-public-key-using-its-fingerprint) fingerprints
👍
Good signature
👍
### Step 19: make filesystem read-only
> Heads-up: shout-out to Nico Kaiser for his amazing [guide](https://gist.github.com/nicokaiser/08aa5b7b3958f171cf61549b70e8a34b) on how to configure a read-only Raspberry Pi.

View file

@ -1,5 +1,5 @@
import RPi.GPIO as GPIO
import keyboard
import subprocess
import time
GPIO.setmode(GPIO.BCM)
@ -10,13 +10,14 @@ GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_UP)
def click(channel):
if channel == 17:
keyboard.send("ctrl+b, up")
subprocess.run(["tmux", "select-pane", "-t", "0"])
elif channel == 22:
keyboard.send("ctrl+b, down")
subprocess.run(["tmux", "select-pane", "-t", "1"])
elif channel == 23:
keyboard.send("ctrl+b, shift+7")
subprocess.run(["tmux", "kill-session"])
# elif channel == 27:
# keyboard.send("")
# subprocess.run(["tmux"])
GPIO.add_event_detect(17, GPIO.RISING, callback=click, bouncetime=300)
GPIO.add_event_detect(22, GPIO.RISING, callback=click, bouncetime=300)
GPIO.add_event_detect(23, GPIO.RISING, callback=click, bouncetime=300)

View file

@ -1,16 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmCAJ0AACgkQH6dnhiu9
EwWl6hAAuswrzfBiZ0kboM1qa4vtCtv/Mst1ZGmSs+pzTwH0K7uPnITMiW5JN1Cu
jODENEZPRNmpgoSSOV6tvJmGhYKWEVHRHP6fdU3xHG9AJZcrrq0LR+i+7qO+kdoJ
iBc/w1KZsjv8Iu0vpXSeqROAxwvG6enUGexx4Ov4EovZHnUjttC2O62VQ1yIVlUy
UxVs3Ky95w9WIo3KTUTjJrrQ3drpi3G0ezq4JHQRvPDscHZnTAcj7oxsPMKVZ8z1
kBI1UUyPgUKvMRssnLjp8hUC+Bc2mrZXt8f66Y+R0C0/xp5r8UijabogbIsM83sz
oreDHsaDgidzvxKO3OPy3YBG+HLaccKddcyb7mYsH6oBzpx0WgcAwszICCV33bke
PEyPMQ3jVyl6EtlGSxGvofglA4MqP0K7enCAmhMsbWF6p2iyz203dDfvV/fFwONi
PBRjgbk6z9x67uAc9XnZrTwaIYsiCYel6EBW39w/ZfUGocnEGuIjrDCypN7b0b3U
pQy2ML6gC0/bsXo4wGThN3wMI32cxxFrEjwZDYwzS14h4eufar96JFlVohPsBdr1
589goQwkfQToClwnA7Jlsmqc/ZctGSkqQl/wY7beT+/KJYSIA36aolgVNlefgTc0
i+esMZRMxc1WQrt8XZEjg0Nu8DjUPdkapQJStdsrZiqO61EPfHc=
=gTZ3
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmCBdosACgkQH6dnhiu9
EwVO0w/+OuHCOnL3nAF0ShoQx2851IFsuiJHP3FHKpQNBIqde4DhudYDjusrOyGR
NnmCo6gotUMVqzCUaqPhC23tUzUYB4KhpjDA/mz0HTEr1JIFQvxa0N1AMW0HnsnZ
EJLi53eCzjx+9lA8Wy+Okh+mZtM5hflatv/yONIrXyMXV+jDk0sgWJ1amxQvPEaT
D/L/9LGvJ9S7QQ/BJfxNVLu+CkBJAqxr8IPKG+mLJMX9nChF+AXu58xGmH35YZtP
nQwjEINFhUziTIyJJwRSLKZa96LhPkXLFtdfDcgs8br+T+Hjaa9AOGd9WJiU1SkX
p3F1rsbeC1w7KEsbFG1KkyS4KQe4oOFMXBGhBtvTiSXn/f7BWjJ6G3vMImzBWJ7I
tszifz/xcVxYsTHMfjtCMIvS+Es/wqAn6MOzsLJwc6T6qT+hz2bA+aP4MM2BQ2QB
mzeEavFumvlpFrCnEbeKNF+WyNK3ULDOEBrK1B1sT+CBzVmQm0RVovgs9Diqsxfi
zEYDnjY569tr9lh6rYHm9IjC4lMsQ7d8u/seaFROqK0BFd9vezItDFOYz2YqI06M
pTYTghBymSlxBgWspieBggH62Ji7wD+0t3MW0f34O4i226h9Ol7CWj9luA5MGADB
I2by6x5m9m5L6aK0ipD/hP/n3uUHvFitnPjNYY3FJvCYXLMME1I=
=RWAj
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,88 @@
#! /bin/bash
set -e
set -o pipefail
function cleanup()
{
kill 0
exit 0
}
trap cleanup EXIT
positional=()
while [[ $# -gt 0 ]]; do
argument="$1"
case $argument in
-h|--help)
printf "%s\n" \
"Usage: trezor-restore.sh [options]" \
"" \
"Options:" \
" --label <label> set Trezor label" \
" --qr-restore-options see \`qr-restore.sh --help\`" \
" -h, --help display help for command"
exit 0
;;
--qr-restore-options)
qr_restore_options=$2
shift
shift
;;
--label)
label=$2
shift
shift
;;
*)
positional+=("$1")
shift
;;
esac
done
set -- "${positional[@]}"
bold=$(tput bold)
red=$(tput setaf 1)
normal=$(tput sgr0)
basedir=$(dirname "$0")
label_arg=""
if [ -n "$label" ]; then
label_arg="--label \"$label\" "
fi
tput reset
printf "$bold$red%s$normal\n" "Restore Trezor device using encrypted paper backup (y or n)?"
read -r answer
if [ "$answer" != "y" ]; then
printf "%s\n" "Cancelled"
exit 0
fi
printf "$bold$red%s$normal\n" "TREZOR WILL BE PERMANENTLY WIPED."
printf "$bold$red%s$normal\n" "Do you wish to proceed (y or n)?"
read -r answer
if [ "$answer" != "y" ]; then
printf "%s\n" "Cancelled"
exit 0
fi
printf "%s\n" "Spawning tmux panes…"
sleep 1
python3 $basedir/tmux-buttons.py &
tmux new -d -s trezor-restore
tmux rename-window -t trezor-restore trezorctl
tmux send-keys -t trezor-restore "trezorctl wipe-device && trezorctl recovery-device --pin-protection --passphrase-protection $label_arg--words 24 --type scrambled" Enter
tmux split-window -t trezor-restore
tmux rename-window -t trezor-restore qr-restore
tmux send-keys -t trezor-restore "qr-restore.sh $(echo $qr_restore_options | sed 's/--word-list *//') --word-list" Enter
tmux attach -t trezor-restore

View file

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmCBdpwACgkQH6dnhiu9
EwXizA/+Ja8i0nH2r6u7jXk+YhljdRjZFGNDOq3xLxMhDadUELbHJA5NhIdFHjY4
OGXUmQh2dH0pbX825kYnVCVcfBhRH9+umX7Ddlqb9YThp466/XMoSVJzvXA7IDHb
cBQ6WsZ2VcJnc36/R6drwp333Sg7CJ7FGLFhgmk2l/y6wvc1WaZ2f2MLjc4fRl3b
GYwoqZcDx1z8QPsto6ba9SQuGPs4gjDxd7f3kaYba1PMcLCZxx3dOrtk7VSyA19r
yGGaP2zTT9OOlP/Mm3dm/NXya0sOj01np9bZ4hrcK3CsZNJeyf2XaaAaYY9mEHNU
8nPuT1kq4svbeaXI4U2J5CYOy3LLBOpjyZr87ClI8ppSmOHwYSZI++4A3/NkaBQK
+r5RDwlQIRC6FEO9gIMoWoInhM4GOCNnQITJENVhKDBKR7rG0K/FZLyZUKmnMM/y
wYPLqk8s4Cbu/aakXd94vbEna8OeAM/v7sZCiUwg70Q2BeB/otMyrqnzP1a6VCxB
L0AWzc9fJYd4NlzKHuzNRcNM+fWMOH0sXhffkA7wS52+G7rakiZ/VgZ2FrIx3abA
DCgzac11KfA+RXUHcmE+NoxtWad4Y8Y8OzNcbiKU1a2umyJg0g4bH2esiP/itVZm
aCnI3KXuhwRYaIfIub9T9xZZoktHb8CLPDQRhrUeIDW1j5rqQag=
=hbtz
-----END PGP SIGNATURE-----

View file

@ -5,11 +5,11 @@ set -o pipefail
function cleanup()
{
sudo kill 0
kill 0
exit 0
}
trap cleanup INT EXIT
trap cleanup EXIT
positional=()
while [[ $# -gt 0 ]]; do
@ -17,7 +17,7 @@ while [[ $# -gt 0 ]]; do
case $argument in
-h|--help)
printf "%s\n" \
"Usage: trezor-validate.sh [options]" \
"Usage: trezor-verify-integrity.sh [options]" \
"" \
"Options:" \
" --qr-restore-options see \`qr-restore.sh --help\`" \
@ -49,21 +49,12 @@ printf "%s\n" "Spawning tmux panes…"
sleep 1
sudo bash -c "python3 $basedir/tmux-buttons.py &"
python3 $basedir/tmux-buttons.py &
tmux new -d -s trezor-validate
tmux rename-window -t trezor-validate trezorctl
tmux send-keys -t trezor-validate "trezorctl recovery-device --words 24 --type scrambled --dry-run" Enter
tmux split-window -t trezor-validate
tmux rename-window -t trezor-validate qr-restore
tmux send-keys -t trezor-validate "qr-restore.sh $(echo $qr_restore_options | sed 's/--word-list *//') --word-list" Enter
tmux attach -t trezor-validate
tput reset
printf "$bold%s$normal\n" "Press ctrl+c to exit"
while :
do
sleep 60
done
tmux new -d -s trezor-verify-integrity
tmux rename-window -t trezor-verify-integrity trezorctl
tmux send-keys -t trezor-verify-integrity "trezorctl recovery-device --words 24 --type scrambled --dry-run" Enter
tmux split-window -t trezor-verify-integrity
tmux rename-window -t trezor-verify-integrity qr-restore
tmux send-keys -t trezor-verify-integrity "qr-restore.sh $(echo $qr_restore_options | sed 's/--word-list *//') --word-list" Enter
tmux attach -t trezor-verify-integrity

View file

@ -1,16 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmCAXbIACgkQH6dnhiu9
EwVBFg/9EctBpaNqFR54nzCPKsZoa6g5DqCAkGeWI7JXOjbV551Do6SAFK7RrG5S
g454q77w7XmMFrJFIl8Yd+h88KyKni0zoi5AFtEL4qVAiVaJJZvMxHYAfxvS4zgE
ksM0M2svVf/FkIBEmzJsDliNTCAALsaT7XZ6s4cLjaBs1P6RK9LZb/cobkckDOqL
/3hcaOplDPGaLIOFzdjuYZv6k/WE9wf+uuAlKgnmevnCDWq+eO0W0CasGkIDcw61
QIqllFK3c8RJKSv7Ab+9GPQGFM//+Is4rRXXH10StaTvnpTTP+Q9QBG7faFGjwZv
dzwKI88fZAxY8cCKYeNdHsA2RNqf74bJ/3S5INdudfKbelj1oU1o1CTk8eMCsqSP
XdGjv7KVkoTI1bHhkBy2s2lBs9ZDU4GjPmD7gaABDPQk2u4Yatw+zN/8cFZ8LrgT
0CaCVCXBVwwihrtdpO0OM4c9YCTEWPyphAkUs3S0+geElyaYWHFBFODpM/yxqS3f
GA1E6hvQD+jZmVM++bHVyWq4Li0nXtknsihNTnURcD+S0GsKlpdFgYTmggMyNyCQ
nbEuUHMs6J0dQFYHo1se6rKTEpRdcSvVLsj8UbIVdA5Ip7OX810poxU3Z+as4cKO
1MU4K7mzVtda0LLz156iyAEKiJHhGvoneFgcqqZx92FzBsV+Mlk=
=MGmG
iQIzBAABCgAdFiEEqYzNEiJDZVsm+vthH6dnhiu9EwUFAmCBdpQACgkQH6dnhiu9
EwXQTg/+Nhi3XmFBXGQmGBfB606ZVaFbE6Gwl9ltzvMlS/bPRn7ypMeeGPfmSpvR
1pt54zBMhW77mfYFnq70gx44Jt2GslcnFFyL1SB3C8+W1v/Hhx5ukIgOFXjwmxQ6
BbP1tSH0M6RHm1NxJ+ct5ju/7EgDE7xIDRU6KRQTb3rMGq5X2lvmvHFpS62BsA/i
G9PldYjL947q5jntoeCj3pJmbk7u8aFZwvKgxiPOTUzd78Im70oDwlhMeUGNMKfm
ux9gy1lTvsYMmAM7XNjdKGmqduCWqmAr8/xp59VArYkOUnD8U4GK/a+NqV63I4o9
ey1uvyFwM2Y4vvLp2GqJgWE/ul1agrFaW4+yir8H3zNs9TbjOdytMhZSY9XbuSST
KEhRNNfKF7VSo+qHjMrBZVuJ6sGEDmylBFBsBVfyl1fCS7siyDQ6x0MSqVjqANQd
Nb8dsTkErhnxZHbYH/O09+hqgPiGoEvA0VES+xcIk7jjPtYK/0Hnodjy7HNznwhM
+HO8RV+IWllVFM8bX/KwlFBhf99d/SqpU6peBh5B+1Y81v/UpkuQzlxKqIEa9png
wzPG21/5YTkKEzrS16qxIprT3TOcabfNmYO5BGCszmJTiV8ceTsjX7kDqMFXbtsO
nNJYtaatmNw+HU/qqrQ5a0I5Y28641nMCcrfwJbammNQ0JgmuQg=
=OvCj
-----END PGP SIGNATURE-----