dotfiles-modern/bin/backup-pgp-keys

140 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# a script to generate backups for my GPG keys
# literally all of active keys I use for different purposes, including some
# I maintain (such as Recap Time Squad's keys for support and security issues
DEFAULT_PRIVATE_KEYS="0527234A430387EA5695D824A30EBE40AD856D88 4D5E631758CB9CC45941B1CE67BFC91B3DA12BE8 EA957E7086E934F8DB9CAD21940047813E9D641C 5D69E717C5BC95731C2AD8BD120C218ED2291996 2CFF8721393487AEEF2C38987067DB4C7768552F 18C97CF46F06176E7EC43BDC7E4E0EF8B968A952 51D2F9710A20AAE56DC9A9AB77D63E4A0C267204 11F7802B423286A5FCF40AF48AEB225605921F92"
DEFAULT_PUBLIC_KEYS="0527234A430387EA5695D824A30EBE40AD856D88 4D5E631758CB9CC45941B1CE67BFC91B3DA12BE8 EA957E7086E934F8DB9CAD21940047813E9D641C 5D69E717C5BC95731C2AD8BD120C218ED2291996"
# allow anybody to automate this via envvars
PRIVATE_KEYS="${PRIVATE_KEYS:-"$DEFAULT_PRIVATE_KEYS"}"
PUBLIC_KEYS="${PUBLIC_KEYS:-"$DEFAULT_PUBLIC_KEYS"}"
# Command snippet taken from OpenKeychain FAQs
# https://www.openkeychain.org/faq/#what-is-the-best-way-to-transfer-my-own-key-to-openkeychain
BACKUP_FILE_PASSWORD=$(gpg --armor --gen-random 1 20)
TIMESTAMP=$(date +%s)
generate_pubkey_bak() {
echo "[Stage 1]: Export all public keys per PUBLIC_KEYS to '$EXPORT_DIR/personal-$TIMESTAMP.asc'"
echo
sleep 3
if [[ $_arg_secretkeys_only == "true" ]]; then
echo "warning: Skipping because --only-secret flag is used"
return
fi
for key in $PUBLIC_KEYS; do
echo "Exporting keyid $key's public key"
if [[ $_arg_dryrun == "true" ]]; then
echo "+ gpg --armor --export \"$key\" >> \"$EXPORT_DIR/personal-$TIMESTAMP.asc\""
else
gpg --armor --export "$key" >> "$EXPORT_DIR/personal-$TIMESTAMP.asc"
fi
sleep 3
done
}
generate_privkey_bak() {
echo "[Stage 2]: Export all private keys per PRIVATE_KEYS to '$EXPORT_DIR/backup-personal-$TIMESTAMP.asc'"
echo
sleep 3
if [[ $_arg_pubkeys_only == "true" ]]; then
echo "warning: Skipping because --only-public flag is used"
return
fi
if [[ $_arg_dryrun == "true" ]]; then
for key in $PRIVATE_KEYS; do
echo "Exporting keyid $key with private key"
echo "+ gpg --armor --export-secret-keys $key >> $EXPORT_DIR/backup-personal-$TIMESTAMP.asc"
sleep 5
done
echo "+ gpg --batch --asymmetric --passphrase \"$BACKUP_FILE_PASSWORD\" --output \"$EXPORT_DIR/private-keys-backup-$TIMESTAMP.sec.asc\""
return
fi
for key in $PRIVATE_KEYS; do
echo "Exporting keyid $key with private key"
gpg --armor --export-secret-keys "$key" >> "$EXPORT_DIR/backup-personal-$TIMESTAMP.asc"
sleep 5
done
echo "warning: Use the following passphrase for encrypting the private key backup in case"
echo "warning: both --batch and --passphrase flags didn't work in 10 seconds below."
echo "warning:"
echo "warning: $BACKUP_FILE_PASSWORD"
echo "warning:"
sleep 10
gpg --batch --asymmetric --passphrase "$BACKUP_FILE_PASSWORD" --output "$EXPORT_DIR/private-keys-backup-$TIMESTAMP.sec.asc"
}
check_export_dir() {
echo "[Stage 0]: Check if the \$EXPORT_DIR exists and create if necessary"
echo
sleep 3
# dry-run
if [[ $_arg_dryrun == "true" ]]; then
echo "+ mkdir $EXPORT_DIR"
return
fi
if [[ ! -d "$EXPORT_DIR" ]]; then
echo "warning: Directory $EXPORT_DIR doesn't exist, attempting to create dir..."
if mkdir "$EXPORT_DIR"; then
true
else
error_code=$?
echo "error: Something gone horribly wrong while creating export directory."
echo "error: Check the logs, fix perms with chmod/chown/sudo and try again."
exit $error_code
fi
else
echo "info: export directory exists, contiuning..."
fi
}
usage() {
echo "USAGE: [EXPORT_DIR=\$(pwd)] $0 [--only-public | --only-secret | --dry-run]"
}
main() {
if [[ $DEBUG != "" ]]; then
set -x
fi
_arg_pubkeys_only=false
_arg_secretkeys_only=false
_arg_dryrun=false
EXPORT_DIR=${EXPORT_DIR:-"$HOME/.export-toolkit"}
# arg parser goes here
for _arg in "${@}"; do {
if test "$_arg" != "--" && [[ "$_arg" == -* ]]; then {
case "$_arg" in
--help | -h)
usage; exit 0
;;
--public-keys-only | --pubkeys | --only-public | -p)
_arg_pubkeys_only=true
;;
--private-keys-only | --secretkeys | --only-secret | -s)
_arg_secretkeys_only=true
;;
--dryrun | --dry-run | -d)
_arg_dryrun=true
;;
esac
shift;
} fi
} done
check_export_dir
generate_pubkey_bak
generate_privkey_bak
}
main "$@"