Skip to content

Instantly share code, notes, and snippets.

@rynkowsg
Last active June 27, 2021 15:24
Show Gist options
  • Save rynkowsg/f9a6dd2dfbfd56f28a203ceb7a88b639 to your computer and use it in GitHub Desktop.
Save rynkowsg/f9a6dd2dfbfd56f28a203ceb7a88b639 to your computer and use it in GitHub Desktop.
Example of non-interactive GPG
#!/usr/bin/env bash
# shellcheck disable=SC2155
RED=$(printf '\033[31m')
GREEN=$(printf '\033[32m')
YELLOW=$(printf '\033[33m')
BLUE=$(printf '\033[34m')
BOLD=$(printf '\033[1m')
RESET=$(printf '\033[m')
function gen_master_key() {
local home_dir="$(echo "${1}" | jq -r ".home_dir // \"${GNUPGHOME}\"")"
local passphrase="$(gpg --gen-random --armor 0 24)}"
local uid="$(echo "${1}" | jq -r '.uid')"
local algo="$(echo "${1}" | jq -r '.algo // ""')"
local usage="$(echo "${1}" | jq -r '.usage // ""')"
local expire="$(echo "${1}" | jq -r '.expire // ""')"
local output_file="$(mktemp)"
set -x
gpg --homedir "${home_dir}" --batch --no-tty \
--status-fd 1 --passphrase "${passphrase}" \
--quick-generate-key "${uid}" "${algo}" "${usage}" "${expire}" >"${output_file}" 2>&1
set +x
local fingerprint="$(awk '/KEY_CREATED P/ { print $4}' "${output_file}")"
local revocation_cert_path="$(awk '/revocation/ { print substr($6, 2, length($6)-2) }' "${output_file}")"
rm -f "${output_file}"
cat <<-EOF
{"fingerprint": "${fingerprint}",
"uid": "${uid}",
"algo": "${algo}",
"revocationCertPath": "${revocation_cert_path}",
"passphrase": "${passphrase}",
"home_dir": "${home_dir}"}
EOF
}
function add_subkey() {
local home_dir="$(echo "${1}" | jq -r '.home_dir')"
local passphrase="$(echo "${1}" | jq -r '.passphrase')"
local master_fpr="$(echo "${1}" | jq -r '.fingerprint')"
local algo="$(echo "${2}" | jq -r '.algo')"
local usage="$(echo "${2}" | jq -r '.usage')"
local expire="$(echo "${2}" | jq -r '.expire')"
local output_file="$(mktemp)"
set -x
gpg --homedir "${home_dir}" --batch \
--status-fd 1 --pinentry-mode loopback --passphrase "${passphrase}" \
--quick-add-key "${master_fpr}" "${algo}" "${usage}" "${expire}" >"${output_file}" 2>&1
set +x
local fingerprint="$(awk '/KEY_CREATED S/ { print $4}' "${output_file}")"
rm -f "${output_file}"
cat <<-EOF
{"usage": "${usage}",
"algo": "${algo}",
"fingerprint": "${fingerprint}"}
EOF
}
function add_uid() {
local home_dir="$(echo "${1}" | jq -r ".home_dir // \"${GNUPGHOME}\"")"
local passphrase="$(echo "${1}" | jq -r '.passphrase')"
local master_fpr="$(echo "${1}" | jq -r '.fingerprint')"
local uid="$(echo "${2}" | jq -r '.uid')"
local output_file="$(mktemp)"
set -x
gpg --homedir "${home_dir}" --batch \
--status-fd 1 --pinentry-mode loopback --passphrase "${passphrase}" \
--quick-add-uid "${master_fpr}" "${uid}" >"${output_file}" 2>&1
set +x
rm -f "${output_file}"
}
function set_primary_uid() {
local home_dir="$(echo "${1}" | jq -r ".home_dir // \"${GNUPGHOME}\"")"
local master_fpr="$(echo "${1}" | jq -r '.fingerprint')"
local passphrase="$(echo "${1}" | jq -r '.passphrase')"
local uid="$(echo "${2}" | jq -r '.uid')"
local output_file="$(mktemp)"
set -x
gpg --homedir "${home_dir}" --batch \
--status-fd 1 --pinentry-mode loopback --passphrase "${passphrase}" \
--quick-set-primary-uid "${master_fpr}" "${uid}" >"${output_file}" 2>&1
set +x
rm -f "${output_file}"
}
function demo() {
unset GNUPGHOME
local gnupg_home="$(mktemp -d)"
# create master key (cert only)
local master_key_params="$(echo '{"uid": "Grzegorz Rynkowski", "algo": "rsa2048", "usage": "cert", "expire": "2090-01-01"}' \
| jq --arg home "${gnupg_home}" '. += {"home_dir": $home}')"
local master_key_info="$(gen_master_key "${master_key_params}")"
# create subkeys
local subkey_1_info="$(add_subkey "${master_key_info}" '{"algo": "rsa2048", "usage": "encrypt", "expire": "1y"}')"
local subkey_2_info="$(add_subkey "${master_key_info}" '{"algo": "rsa2048", "usage": "sign", "expire": "1y"}')"
local subkey_3_info="$(add_subkey "${master_key_info}" '{"algo": "rsa2048", "usage": "auth", "expire": "1y"}')"
# add uids
add_uid "${master_key_info}" '{"uid": "Grzegorz Rynkowski <[email protected]>"}'
add_uid "${master_key_info}" '{"uid": "Grzegorz Rynkowski <[email protected]>"}'
set_primary_uid "${master_key_info}" '{"uid": "[email protected]"}'
printf "\n${YELLOW}${BOLD}%s${RESET}\n%s\n" "MASTER" "${master_key_info}"
printf "\n${YELLOW}${BOLD}%s${RESET}\n%s\n" "SUBKEY_1" "${subkey_1_info}"
printf "\n${YELLOW}${BOLD}%s${RESET}\n%s\n" "SUBKEY_2" "${subkey_2_info}"
printf "\n${YELLOW}${BOLD}%s${RESET}\n%s\n" "SUBKEY_3" "${subkey_3_info}"
printf "\n${YELLOW}${BOLD}%s${RESET}\n" "LIST OF KEYS"
gpg --homedir "${gnupg_home}" --list-secret-keys
printf "%s\n" "-- FILES SAVED in GNUPGHOME=${gnupg_home}:"
tree "${gnupg_home}"
rm -rf "${gnupg_home}"
set +x
}
demo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment