Skip to content

Instantly share code, notes, and snippets.

@lrvick
Created July 27, 2021 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lrvick/a66e770b25444710ea484c8bd5040d82 to your computer and use it in GitHub Desktop.
Save lrvick/a66e770b25444710ea484c8bd5040d82 to your computer and use it in GitHub Desktop.
Rotate PGP pins on yulbikeys automatically and randomly ant encrypt to multiple recipients.
#!/bin/bash
set -e
export LC_ALL=
export LANGUAGE=en
function gpg_env(){
GNUPGHOME=$(mktemp -d -p /dev/shm/); export GNUPGHOME
echo "pinentry-mode loopback" >> "$GNUPGHOME/gpg.conf"
{ echo "allow-loopback-pinentry";
echo "allow-preset-passphrase";
} >> "$GNUPGHOME/gpg-agent.conf"
#{ echo "log-file /tmp/scd.log";
# echo "debug-level guru";
# echo "debug-all";
# echo "debug-ccid-driver";
#} >> "$GNUPGHOME/scdaemon.conf"
killall gpg-agent
gpg-agent --daemon --extra-socket "$GNUPGHOME/S.gpg-agent" 2> /dev/null
echo "export PATH=$GNUPGHOME:$PATH \
export GNUPGHOME=$GNUPGHOME; \
export GPG_AGENT_INFO=$GNUPGHOME/S.gpg-agent"
}
function gpg_cleanup(){
gpgconf --kill gpg-agent
rm -rf "$GNUPGHOME"
}
function gpg_change_pin(){
local role=$1
local old=$2
local new=$3
case $role in
user) role_code=81;;
admin) role_code=83;;
esac
local pins; pins="$(printf "%s%s" "$old" "$new" | od -A n -t x1 -w)"
local length; length="$( printf "%02X" "$((${#old} + ${#new}))")"
local response; response="$(\
echo "APDU 00 24 00 ${role_code} ${length}${pins}" \
| /usr/lib/gnupg/scdaemon --server 2> /dev/null \
| sed 's/\x0//g' | head -n2 | tail -n1 )"
case $response in
D) return 0; ;;
D\ i*) >&2 echo "Invalid pin for card"; exit 1; ;;
ERR*) echo "$response"; exit 1; ;;
esac
}
key1="$1"
key2="$2"
(( $# != 3 )) || \
{ echo "Usage: pinrot user1.asc user2.asc >> pin.asc"; exit; }
[ -f "$key1" ] || { echo "Key $1 does not exist"; exit 1; }
[ -f "$key2" ] || { echo "Key $2 does not exist"; exit 1; }
eval "$(gpg_env)"
gpg --import "$key1" "$key2" 2>/dev/null
gpg --list-keys --fingerprint --with-colons \
| sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' \
| gpg --import-ownertrust > /dev/null 2>&1
read -rp "Please insert a GPG smartcard for given shard then hit enter"
new_user_pin=$(pwgen 10)
read -rp "Current user pin (default: 123456) -> " user_pin
gpg_change_pin "user" "$user_pin" "$new_user_pin"
new_admin_pin=$(pwgen 10)
read -rp "Current admin pin (default: 12345678) -> " admin_pin
gpg_change_pin "admin" "$admin_pin" "$new_admin_pin"
# Encrypt keys to stdout
# shellcheck disable=2046
printf "%s\\n%s" "$new_user_pin" "$new_admin_pin" | gpg --throw-keyids -ea $(
gpg \
--trust-model always \
--yes \
--batch \
--list-keys \
--with-colons \
--fast-list-mode \
| awk -F: '/^pub/{printf "-r %s ", $5}' \
) 2> /dev/null
gpg_cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment