Repository navigation
Expand file tree
/
Copy pathgenerate-gpg
More file actions
executable file
·65 lines (59 loc) · 3.08 KB
/
Copy pathgenerate-gpg
File metadata and controls
executable file
·65 lines (59 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
source "${PWD}/helpers/trap_and_trace.sh"
PATH="${PWD}:${PATH}"
log_attention "Enter your name and email address to generate a new GPG key."
until [[ "${confirm:-}" == "y" ]]; do
read -p "Your Name: " USER_ID
read -p "Your email address: " USER_EMAIL
USER_ID="${USER_ID} <${USER_EMAIL}>"
log_attention "Your GPG key will be generated with the following USER ID: ${USER_ID}"
read -p "Is this correct? [y/n] " confirm
done
# Fingerprint of the newest secret key whose user ID exactly matches USER_ID,
# or empty if there is none. Sorts on the creation timestamp (field 6 of the
# `sec` record) and takes the `fpr` record that follows it. gpg exits 2 when no
# key matches, which isn't an error here.
newest_secret_key() {
{ gpg --list-secret-keys --with-colons "=${USER_ID}" 2>/dev/null || true; } |
awk -F: '$1 == "sec" {created = $6; want = 1; next}
$1 == "fpr" && want {print created, $10; want = 0}' |
sort -n | tail -n1 | cut -d ' ' -f2
}
# Reuse an existing key for this user ID if there is one, so the script can be
# re-run to finish configuring git after a partial run.
sec_key="$(newest_secret_key)"
if [[ -n "${sec_key}" ]]; then
log_attention "A GPG key already exists for \"${USER_ID}\": ${sec_key}"
read -p "Use this key instead of generating a new one? [y/n] " reuse
[[ "${reuse}" == "y" ]] || sec_key=""
fi
if [[ -z "${sec_key}" ]]; then
# Generating a new GPG key
# https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key
# --yes allows a second key for an existing user ID; KEY_CREATED on the
# status fd reports the new key's fingerprint.
log_info "Generating a new GPG key for USER ID \"${USER_ID}\""
sec_key="$(gpg --quiet --yes --status-fd 1 --quick-generate-key "${USER_ID}" default default none |
awk '$2 == "KEY_CREATED" {print $4}')"
if [[ -z "${sec_key}" ]]; then
log_error "Could not determine the fingerprint of the new GPG key"
exit 1
fi
fi
log_info "Registering GPG key ${sec_key}"
# Codespaces has issues when GPG commit signing is enabled on the containers as
# well as in gitconfig. Since our global gitconfig gets synced to dotfiles and
# thus to codespaces, we can set some system level config here instead.
# https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key
log_info "Configuring git for GPG"
# Exit code 5 means gpg.format wasn't set, which is fine
git config unset --global --all gpg.format || [[ $? -eq 5 ]]
git config set --global --all user.signingkey "${sec_key}"
git config set --global --all commit.gpgsign true # sign all commits
git config set --global --all tag.gpgsign true # sign all tags
git config set --global --all gpg.program "$(command -v gpg 2>/dev/null)"
# Adding your GPG key to your GitHub account
# https://docs.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account
log_success "To add your public key to GitHub, etc., run 'gpg --armor --export \"${sec_key}\" | pbcopy' to copy the key to your clipboard."