aboutsummaryrefslogtreecommitdiff
path: root/scripts/generate.sh
blob: ef4c6f174eb38bb804154fbb40e979f5da692a0a (plain) (blame)
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env bash
# https://github.com/drduh/YubiKey-Guide/blob/master/scripts/generate.sh
# Generates GnuPG keys and corresponding passphrases to secure them.

#set -x  # uncomment to debug
set -o errtrace
set -o nounset
set -o pipefail

umask 077

export LC_ALL="C"

get_temp_dir () {
    # Returns temporary working directory path.
    mktemp -d -t $(date +%Y.%m.%d)-XXXX
}

get_id_label () {
    # Returns Identity name/label.
    printf "YubiKey User <yubikey@example.domain>"
}

get_key_type () {
    # Returns key type and size.
    printf "rsa2048"
}

get_key_expiration () {
    # Returns key expiration date.
    printf "2027-05-01"
}

get_pass () {
    # Returns random passphrase.
    tr -dc "A-Z2-9" < /dev/urandom | \
        tr -d "IOUS5" | \
        fold  -w  ${PASS_GROUPSIZE:-4} | \
        paste -sd ${PASS_DELIMITER:--} - | \
        head  -c  ${PASS_LENGTH:-29}
}

set_pass () {
    # Exports Certify and LUKS passphrases.
    export CERTIFY_PASS="$(get_pass)"
    export LUKS_PASS="$(get_pass)"
    printf "set passphrases (certify='%s', luks='%s')\n" \
        "$CERTIFY_PASS" "$LUKS_PASS"
}

gen_key_certify () {
    # Generates Certify key with no expiration.
    echo "$CERTIFY_PASS" | \
        gpg --batch --passphrase-fd 0 \
            --quick-generate-key "$IDENTITY" \
            "$KEY_TYPE" "cert" "never"
}

set_id_fp () {
    # Sets Key ID and Fingerprint environment vars.
    export KEY_ID=$(gpg -k --with-colons "$IDENTITY" | \
        awk -F: '/^pub:/ { print $5; exit }')
    export KEY_FP=$(gpg -k --with-colons "$IDENTITY" | \
        awk -F: '/^fpr:/ { print $10; exit }')
    printf "got identity (fp='%s', id='%s')\n" \
        "$KEY_FP" "$KEY_ID"
}

gen_key_subs () {
    # Generates Subkeys with specified expiration.
    for SUBKEY in sign encrypt auth ; do \
        echo "$CERTIFY_PASS" | \
            gpg --batch --passphrase-fd 0 \
                --pinentry-mode=loopback \
                --quick-add-key "$KEY_FP" \
                "$KEY_TYPE" "$SUBKEY" "$KEY_EXPIRATION"
    done
}

list_keys () {
    # Prints available secret keys.
    gpg --list-secret-keys
}

save_secrets () {
    # Exports secret keys to local files.
    echo "$CERTIFY_PASS" | \
        gpg --output $GNUPGHOME/$KEY_ID-Certify.key \
            --batch --pinentry-mode=loopback --passphrase-fd 0 \
            --armor --export-secret-keys $KEY_ID

    echo "$CERTIFY_PASS" | \
        gpg --output $GNUPGHOME/$KEY_ID-Subkeys.key \
            --batch --pinentry-mode=loopback --passphrase-fd 0 \
            --armor --export-secret-subkeys $KEY_ID
}

save_pubkey () {
    # Exports public key to local file.
    gpg --output $GNUPGHOME/$KEY_ID-$(date +%F).asc \
        --armor --export $KEY_ID
}

export GNUPGHOME="$(get_temp_dir)"
cd "$GNUPGHOME"
printf "set temp dir (path='%s')\n" "$(pwd)"

export IDENTITY="$(get_id_label)"
export KEY_TYPE="$(get_key_type)"
export KEY_EXPIRATION="$(get_key_expiration)"
printf "set attributes (label='%s', type='%s', expire='%s')\n" \
    "$IDENTITY" "$KEY_TYPE" "$KEY_EXPIRATION"

set_pass

gen_key_certify

set_id_fp

gen_key_subs

list_keys

save_secrets

save_pubkey