#!/bin/sh -e # Copyright (c) 2021, la-ninpre # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # ---------------------------------------------------------------------- # # # small script to backup secret gpg keys using paperkey and qrencode. # # basic usage: # # $ paperbackup -u user@email.com # # by default exports minimized public key and paperkeyed secret key # to qr-encoded images, which then are combined into one image for # easy printing. # # dependencies: # - gpg (obviously) # - paperkey # - qrencode # - imagemagick (optional, use -n to disable montage) usage() { echo "usage: ${0##*/} [OPTIONS]" echo echo "options:" echo " -u, --uid {UID}" echo " gpg keyid or uid (this is mandatory)" echo " -l, --level {L,M,Q,H}" echo " qrencode correction level" echo " -t, --term" echo " output to terminal instead of png image" echo " -n, --nomontage" echo " disable composing qrcodes to one image" echo " -h, --help" echo " print usage information" echo } check_uid() { [ -z "$1" ] && echo "uid could not be empty" && exit 1 if ! gpg -K "$1" >/dev/null then exit 1 fi PB_UID="$1" } check_corr_lvl() { case "$1" in l|L|m|M|q|Q|h|H) PB_CORR_LVL="$1" ;; *) echo "correction level should be one of L,M,Q,H" usage exit 1 ;; esac } qr_encode() { PB_QRENCODE_FLAGS="-8 -l $PB_CORR_LVL -t $PB_TYPE" case "$PB_TYPE" in png) PB_QRENCODE_FLAGS="$PB_QRENCODE_FLAGS -o $1" ;; UTF8) ;; *) exit 1 ;; esac # i don't know if it is safe to do so, but it's very convenient # shellcheck disable=SC2086 qrencode $PB_QRENCODE_FLAGS } get_pubkey() { [ -n "$1" ] && gpg --export --export-options export-minimal "$1" \ | qr_encode "$1-pubkey.png" } get_seckey() { [ -n "$1" ] && gpg --export-secret-key "$1" \ | paperkey --output-type raw | qr_encode "$1-seckey.png" } montage_keys() { montage \ -pointsize 18 \ -title "\nsecret key backup for $PB_UID\n$PB_DATE" \ -label pubkey "$PB_UID-pubkey.png" \ -label seckey "$PB_UID-seckey.png" \ -mode concatenate \ "$PB_UID-keys.png" rm -f "$PB_UID-pubkey.png" "$PB_UID-seckey.png" } main() { PB_TYPE="png" PB_CORR_LVL="H" PB_DATE=$(date "+%F %T") PB_MONTAGE=1 while [ -n "$1" ] do case "$1" in --uid|-u) shift check_uid "$1" ;; --level|-l) shift check_corr_lvl "$1" ;; --term|-t) PB_TYPE="UTF8" ;; --nomontage|-n) PB_MONTAGE=0 ;; --help|-h) echo "backup secret gpg key using paperkey and qrencode" echo usage exit ;; *) usage exit 1 ;; esac shift done [ -z "$PB_UID" ] && echo "please specify uid or keyid" && exit 1; get_pubkey "$PB_UID" && get_seckey "$PB_UID" [ "$PB_TYPE" = "png" ] \ && [ "$PB_MONTAGE" -eq 1 ] \ && montage_keys exit 0 } main "$@"