Created
July 2, 2022 03:43
-
-
Save davidlj95/62efea859cfd932c7d0dbe2e8ad433b1 to your computer and use it in GitHub Desktop.
Helps fixing a GPG paperkey using checksums & vim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# So you have backed up your GPG key using paperkey, and have scanned it | |
# using OCR techniques. However, it's not perfect and some checksums do not match | |
# Some 8s are Bs, 0s are Os... This script will try to spot errors so you | |
# can compare those lines and fix them | |
# | |
# Given a secret key exported using paperkey, tries to decode it. | |
# | |
# In case a CRC checksum wrong is found, a vim editor will be opened | |
# in the line that requires a fix. When a change is done in the file, | |
# it will be checked again, and if line being fixed is correct, will | |
# move automatically to next line until all lines are cleared | |
# | |
# The public key is needed too. You can fetch it using: | |
# | |
# gpg --recv-keys <id> | |
# gpg --export > public-key.gpg | |
# | |
# After having a proper secret key file, import your secret key using: | |
# paperkey --pubring public-key.gpg --secrets secret-key.asc | gpg --import | |
# | |
# More info: | |
# https://wiki.archlinux.org/title/Paperkey#Restore_secret_key | |
# Paperkey tool needed | |
if ! command -v paperkey > /dev/null 2>&1; then | |
>&2 echo "❌ paperkey is not installed" | |
exit 1 | |
fi | |
# Usage | |
function print_usage_and_exit() { | |
>&2 echo "Usage:" | |
>&2 echo "./fix-paperkey.sh <secret_key_file> <public_key_file>" | |
>&2 echo "[--no-auto] [--pause]" | |
>&2 echo "" | |
>&2 echo "--no-auto: does not save & check the file again after each edit" | |
>&2 echo "--pause: pause to indicate which line is failing before entering editor" | |
exit 1 | |
} | |
# Args | |
if [ $# -lt 2 ]; then | |
>&2 echo "❌ Not enough arguments" | |
print_usage_and_exit | |
fi | |
secret_key_file="$1" | |
if ! [ -r "$secret_key_file" ]; then | |
>&2 echo "❌ Secret key file '$secret_key_file' not readable" | |
exit 1 | |
fi | |
shift | |
public_key_file="$1" | |
if ! [ -r "$public_key_file" ]; then | |
>&2 echo "❌ Public key file '$public_key_file' not readable" | |
exit 1 | |
fi | |
shift | |
auto="true" | |
pause="" | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
--no-auto) | |
auto="" | |
shift | |
;; | |
--pause) | |
pause="true" | |
shift | |
;; | |
*) | |
>&2 echo "❌ Unknown argument '$1'" | |
print_usage_and_exit | |
;; | |
esac | |
done | |
# Remove # / empty lines to jump to line | |
sed -i.bak '/^#/d' "$secret_key_file" | |
sed -i.bak '/^[[:space:]]*$/d' "$secret_key_file" | |
rm "$secret_key_file.bak" | |
last_error_line=0 | |
while ! error=$((\ | |
paperkey --pubring "$public_key_file" --secrets "$secret_key_file" \ | |
) 2>&1); do | |
# Parse error message and retrieve failing line (or quit if not CRC error) | |
error_regexp='CRC on line ([0-9]+) does not match \(([A-F0-9]{6}\!\=[A-F0-9]{6})\)' | |
if [[ $error =~ $error_regexp ]]; then | |
error_line="${BASH_REMATCH[1]}" | |
error_crc_mismatch="${BASH_REMATCH[2]}" | |
>&2 echo "ℹ️ CRC Error detected on line $error_line ($error_crc_mismatch)" | |
else | |
>&2 echo "❌ Unknown error:" | |
>&2 echo "$error" | |
exit 1 | |
fi | |
# Open Vim where something needs to be fixed + highlight line being edited + autosave & quit every change | |
if [ "$pause" = "true" ]; then | |
>&2 echo "⌨️ Press a key to enter the editor and fix it" | |
read | |
fi | |
vim \ | |
-c 'set cursorline' \ | |
+$error_line \ | |
${auto:+-c 'autocmd TextChanged,TextChangedI *.* wq'} \ | |
"$secret_key_file" | |
# Transform file to uppercase | |
# Doing it this way as can't do it with sed in BSD | |
# https://stackoverflow.com/a/18298422 | |
tmpfile="$(mktemp)" | |
cat "$secret_key_file" | tr '[:lower:]' '[:upper:]' > "$tmpfile" | |
mv -f "$tmpfile" "$secret_key_file" | |
done | |
echo "✅ All good" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
RESERVED