From 8c0a752934ff58a773aab7fb54baddfe9941994d Mon Sep 17 00:00:00 2001 From: drduh Date: Sun, 15 Jun 2025 13:01:56 -0700 Subject: [PATCH 1/6] implement fail function --- scripts/generate.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/scripts/generate.sh b/scripts/generate.sh index faf857f..0ec7cbd 100755 --- a/scripts/generate.sh +++ b/scripts/generate.sh @@ -11,14 +11,20 @@ umask 077 export LC_ALL="C" +fail() { + # Print an error string in red and exit. + tput setaf 1 ; printf "%s\n" "${1}" ; tput sgr0 + exit 1 +} + print_cred () { - # Print a credential string in red. - tput setaf 1 ; printf "%s\n" "${1}" ; tput sgr0 + # Print a credential string in red. + tput setaf 1 ; printf "%s\n" "${1}" ; tput sgr0 } print_id () { - # Print an identity string in yellow. - tput setaf 3 ; printf "%s\n" "${1}" ; tput sgr0 + # Print an identity string in yellow. + tput setaf 3 ; printf "%s\n" "${1}" ; tput sgr0 } get_id_label () { @@ -28,12 +34,13 @@ get_id_label () { get_key_type () { # Returns key type and size. + #printf "default" printf "rsa4096" } get_key_expiration () { # Returns key expiration date. - printf "2027-05-01" + printf "2027-07-01" } get_temp_dir () { @@ -87,6 +94,9 @@ set_fingerprint () { key_list=$(gpg --list-secret-keys --with-colons) export KEY_ID=$(printf "$key_list" | awk -F: '/^sec/ { print $5; exit }') export KEY_FP=$(printf "$key_list" | awk -F: '/^fpr/ { print $10; exit }') + if [[ -z "$KEY_FP" || -z "$KEY_ID" ]]; then + fail "could not set key fingerprint" + fi printf "got identity (fp='%s', id='%s')\n" "$KEY_FP" "$KEY_ID" } From d8ad5c469b11275a1c6dfba6740803a994c2f4da Mon Sep 17 00:00:00 2001 From: drduh Date: Sun, 15 Jun 2025 13:22:45 -0700 Subject: [PATCH 2/6] split subkey gen command, note ed25519 auth --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 51f9009..638b4f9 100644 --- a/README.md +++ b/README.md @@ -490,13 +490,22 @@ EOF Generate Signature, Encryption and Authentication Subkeys using the previously configured key type, passphrase and expiration: ```console -for SUBKEY in sign encrypt auth ; do \ - echo "$CERTIFY_PASS" | \ +echo "$CERTIFY_PASS" | \ gpg --batch --pinentry-mode=loopback --passphrase-fd 0 \ - --quick-add-key "$KEYFP" "$KEY_TYPE" "$SUBKEY" "$EXPIRATION" -done + --quick-add-key "$KEYFP" "$KEY_TYPE" sign "$EXPIRATION" + +echo "$CERTIFY_PASS" | \ + gpg --batch --pinentry-mode=loopback --passphrase-fd 0 \ + --quick-add-key "$KEYFP" "$KEY_TYPE" encrypt "$EXPIRATION" + +echo "$CERTIFY_PASS" | \ + gpg --batch --pinentry-mode=loopback --passphrase-fd 0 \ + --quick-add-key "$KEYFP" "$KEY_TYPE" auth "$EXPIRATION" ``` +> [!NOTE] +> Some systems no longer accept RSA keys for SSH authentication; set the `KEY_TYPE` variable to `ed25519` before generating the last `auth` subkey. + # Verify keys List available secret keys: From d446832705be6b8ea6665396be19858398a6dce6 Mon Sep 17 00:00:00 2001 From: drduh Date: Sun, 15 Jun 2025 13:29:08 -0700 Subject: [PATCH 3/6] explicit note on ed25519 auth subkeys to fix #507 --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 638b4f9..83ab8d9 100644 --- a/README.md +++ b/README.md @@ -438,7 +438,7 @@ export KEYID=$(gpg -k --with-colons "$IDENTITY" | \ export KEYFP=$(gpg -k --with-colons "$IDENTITY" | \ awk -F: '/^fpr:/ { print $10; exit }') -printf "\nKey ID: %40s\nKey FP: %40s\n\n" "$KEYID" "$KEYFP" +printf "\nKey ID/Fingerprint: %20s\n%s\n\n" "$KEYID" "$KEYFP" ```
@@ -487,7 +487,7 @@ EOF # Create Subkeys -Generate Signature, Encryption and Authentication Subkeys using the previously configured key type, passphrase and expiration: +Generate Signature and Encryption Subkeys using the previously configured key type, passphrase and expiration: ```console echo "$CERTIFY_PASS" | \ @@ -497,15 +497,19 @@ echo "$CERTIFY_PASS" | \ echo "$CERTIFY_PASS" | \ gpg --batch --pinentry-mode=loopback --passphrase-fd 0 \ --quick-add-key "$KEYFP" "$KEY_TYPE" encrypt "$EXPIRATION" +``` +Followed by the Authentication Subkey: + +> [!NOTE] +> Some systems no longer accept RSA for SSH authentication; set the `KEY_TYPE` variable to `ed25519` before generating Authentication Subkey. + +``` echo "$CERTIFY_PASS" | \ gpg --batch --pinentry-mode=loopback --passphrase-fd 0 \ --quick-add-key "$KEYFP" "$KEY_TYPE" auth "$EXPIRATION" ``` -> [!NOTE] -> Some systems no longer accept RSA keys for SSH authentication; set the `KEY_TYPE` variable to `ed25519` before generating the last `auth` subkey. - # Verify keys List available secret keys: From e974dbb95cb6727cce3f0e61971f36085e0e0567 Mon Sep 17 00:00:00 2001 From: drduh Date: Sun, 15 Jun 2025 13:36:09 -0700 Subject: [PATCH 4/6] create scripts dir before creating keygrips --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83ab8d9..f46e943 100644 --- a/README.md +++ b/README.md @@ -1806,7 +1806,7 @@ gpg-connect-agent "scd serialno" "learn --force" /bye Alternatively, use a script to delete the GnuPG shadowed key, where the serial number is stored (see [GnuPG #T2291](https://dev.gnupg.org/T2291)): ```console -cat >> ~/scripts/remove-keygrips.sh <> ~/scripts/remove-keygrips.sh <&2; exit 1; } KEYGRIPS=$(gpg --with-keygrip --list-secret-keys "$@" | awk '/Keygrip/ { print $3 }') From 76d557b0f6e6a5c5b5d80569b749d4db3aabaeef Mon Sep 17 00:00:00 2001 From: drduh Date: Sun, 15 Jun 2025 14:08:13 -0700 Subject: [PATCH 5/6] set individual key types default to ed25519 for auth --- README.md | 2 +- scripts/generate.sh | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f46e943..1e8af57 100644 --- a/README.md +++ b/README.md @@ -367,7 +367,7 @@ Subkeys must be renewed or rotated using the Certify key - see [Updating keys](# Set Subkeys to expire on a planned date: ```console -export EXPIRATION=2027-05-01 +export EXPIRATION=2027-07-01 ``` The expiration date may also be relative, for example set to two years from today: diff --git a/scripts/generate.sh b/scripts/generate.sh index 0ec7cbd..a054585 100755 --- a/scripts/generate.sh +++ b/scripts/generate.sh @@ -32,12 +32,25 @@ get_id_label () { printf "YubiKey User " } -get_key_type () { - # Returns key type and size. +get_key_type_sign () { + # Returns key type for signature subkey. #printf "default" printf "rsa4096" } +get_key_type_enc () { + # Returns key type for encryption subkey. + #printf "default" + printf "rsa4096" +} + +get_key_type_auth () { + # Returns key type for authentication subkey. + #printf "default" + #printf "rsa4096" + printf "ed25519" +} + get_key_expiration () { # Returns key expiration date. printf "2027-07-01" @@ -58,10 +71,12 @@ set_temp_dir () { set_attrs () { # Sets identity and key attributes. export IDENTITY="$(get_id_label)" - export KEY_TYPE="$(get_key_type)" + export KEY_TYPE_SIGN="$(get_key_type_sign)" + export KEY_TYPE_ENC="$(get_key_type_enc)" + export KEY_TYPE_AUTH="$(get_key_type_auth)" export KEY_EXPIRATION="$(get_key_expiration)" - printf "set attributes (label='%s', type='%s', expire='%s')\n" \ - "$IDENTITY" "$KEY_TYPE" "$KEY_EXPIRATION" + printf "set attributes (label='%s', sign='%s', enc='%s', auth='%s', expire='%s')\n" \ + "$IDENTITY" "$KEY_TYPE_SIGN" "$KEY_TYPE_ENC" "$KEY_TYPE_AUTH" "$KEY_EXPIRATION" } get_pass () { @@ -85,8 +100,7 @@ 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" + --quick-generate-key "$IDENTITY" "$KEY_TYPE_SIGN" "cert" "never" } set_fingerprint () { @@ -102,13 +116,15 @@ set_fingerprint () { 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 + echo "$CERTIFY_PASS" | \ + gpg --batch --passphrase-fd 0 --pinentry-mode=loopback \ + --quick-add-key "$KEY_FP" "$KEY_TYPE_SIGN" sign "$KEY_EXPIRATION" + echo "$CERTIFY_PASS" | \ + gpg --batch --passphrase-fd 0 --pinentry-mode=loopback \ + --quick-add-key "$KEY_FP" "$KEY_TYPE_ENC" encrypt "$KEY_EXPIRATION" + echo "$CERTIFY_PASS" | \ + gpg --batch --passphrase-fd 0 --pinentry-mode=loopback \ + --quick-add-key "$KEY_FP" "$KEY_TYPE_AUTH" auth "$KEY_EXPIRATION" } save_secrets () { From 48fe57a24f69be16ddb8f1db3ddaf2b457a993c9 Mon Sep 17 00:00:00 2001 From: drduh Date: Tue, 17 Jun 2025 18:57:42 -0700 Subject: [PATCH 6/6] increment stdout dates, cite ed25519 --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 1e8af57..34300da 100644 --- a/README.md +++ b/README.md @@ -502,7 +502,7 @@ echo "$CERTIFY_PASS" | \ Followed by the Authentication Subkey: > [!NOTE] -> Some systems no longer accept RSA for SSH authentication; set the `KEY_TYPE` variable to `ed25519` before generating Authentication Subkey. +> Some systems no longer accept RSA for SSH authentication; to use [Ed25519](https://ed25519.cr.yp.to/), set the `KEY_TYPE` variable to `ed25519` before generating Authentication Subkey. ``` echo "$CERTIFY_PASS" | \ @@ -521,12 +521,12 @@ gpg -K The output will display **[C]ertify, [S]ignature, [E]ncryption and [A]uthentication** keys: ```console -sec rsa4096/0xF0F2CFEB04341FB5 2025-01-01 [C] +sec rsa4096/0xF0F2CFEB04341FB5 2025-07-01 [C] Key fingerprint = 4E2C 1FA3 372C BA96 A06A C34A F0F2 CFEB 0434 1FB5 uid [ultimate] YubiKey User -ssb rsa4096/0xB3CD10E502E19637 2025-01-01 [S] [expires: 2027-05-01] -ssb rsa4096/0x30CBE8C4B085B9F7 2025-01-01 [E] [expires: 2027-05-01] -ssb rsa4096/0xAD9E24E1B8CB9600 2025-01-01 [A] [expires: 2027-05-01] +ssb rsa4096/0xB3CD10E502E19637 2025-07-01 [S] [expires: 2027-07-01] +ssb rsa4096/0x30CBE8C4B085B9F7 2025-07-01 [E] [expires: 2027-07-01] +ssb rsa4096/0xAD9E24E1B8CB9600 2025-07-01 [A] [expires: 2027-07-01] ``` # Backup keys @@ -960,12 +960,12 @@ EOF Verify Subkeys are on YubiKey with `gpg -K` - indicated by `ssb>`: ```console -sec rsa4096/0xF0F2CFEB04341FB5 2025-01-01 [C] +sec rsa4096/0xF0F2CFEB04341FB5 2025-07-01 [C] Key fingerprint = 4E2C 1FA3 372C BA96 A06A C34A F0F2 CFEB 0434 1FB5 uid [ultimate] YubiKey User -ssb> rsa4096/0xB3CD10E502E19637 2025-01-01 [S] [expires: 2027-05-01] -ssb> rsa4096/0x30CBE8C4B085B9F7 2025-01-01 [E] [expires: 2027-05-01] -ssb> rsa4096/0xAD9E24E1B8CB9600 2025-01-01 [A] [expires: 2027-05-01] +ssb> rsa4096/0xB3CD10E502E19637 2025-07-01 [S] [expires: 2027-07-01] +ssb> rsa4096/0x30CBE8C4B085B9F7 2025-07-01 [E] [expires: 2027-07-01] +ssb> rsa4096/0xAD9E24E1B8CB9600 2025-07-01 [A] [expires: 2027-07-01] ``` The `>` after a tag indicates the key is stored on a smart card. @@ -1129,18 +1129,18 @@ PIN retry counter : 3 3 3 Signature counter : 0 KDF setting ......: on Signature key ....: CF5A 305B 808B 7A0F 230D A064 B3CD 10E5 02E1 9637 - created ....: 2025-01-01 12:00:00 + created ....: 2025-07-01 12:00:00 Encryption key....: A5FA A005 5BED 4DC9 889D 38BC 30CB E8C4 B085 B9F7 - created ....: 2025-01-01 12:00:00 + created ....: 2025-07-01 12:00:00 Authentication key: 570E 1355 6D01 4C04 8B6D E2A3 AD9E 24E1 B8CB 9600 - created ....: 2025-01-01 12:00:00 -General key info..: sub rsa4096/0xB3CD10E502E19637 2025-01-01 YubiKey User -sec# rsa4096/0xF0F2CFEB04341FB5 created: 2025-01-01 expires: never -ssb> rsa4096/0xB3CD10E502E19637 created: 2025-01-01 expires: 2027-05-01 + created ....: 2025-07-01 12:00:00 +General key info..: sub rsa4096/0xB3CD10E502E19637 2025-07-01 YubiKey User +sec# rsa4096/0xF0F2CFEB04341FB5 created: 2025-07-01 expires: never +ssb> rsa4096/0xB3CD10E502E19637 created: 2025-07-01 expires: 2027-07-01 card-no: 0006 05553211 -ssb> rsa4096/0x30CBE8C4B085B9F7 created: 2025-01-01 expires: 2027-05-01 +ssb> rsa4096/0x30CBE8C4B085B9F7 created: 2025-07-01 expires: 2027-07-01 card-no: 0006 05553211 -ssb> rsa4096/0xAD9E24E1B8CB9600 created: 2025-01-01 expires: 2027-05-01 +ssb> rsa4096/0xAD9E24E1B8CB9600 created: 2025-07-01 expires: 2027-07-01 card-no: 0006 05553211 ```