diff --git a/public.key b/public.key index 19c9f0e..d9d4429 100644 --- a/public.key +++ b/public.key @@ -1,64 +1,64 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -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 -rdtB4A== -=lrzs +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 +a5QDMQ== +=UbaI -----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/setup-gpg-keys.sh b/scripts/setup-gpg-keys.sh index dbcd8d5..dcc334e 100755 --- a/scripts/setup-gpg-keys.sh +++ b/scripts/setup-gpg-keys.sh @@ -4,74 +4,71 @@ set -euo pipefail KEY_NAME="Zurvan Linux Archive" KEY_EMAIL="archive@zurvanlinux.org" KEY_LENGTH=4096 +BATCH_FILE="/tmp/gpg-batch-$$" +PASSPHRASE_FILE="/tmp/zurvan-gpg-passphrase.txt" + +cleanup() { + rm -f "${BATCH_FILE}" +} +trap cleanup EXIT if gpg --list-keys "${KEY_EMAIL}" >/dev/null 2>&1; then FPR=$(gpg --list-keys --with-colons "${KEY_EMAIL}" | awk -F: '/^pub:/ {print $10; exit}') echo "ERROR: A key for ${KEY_EMAIL} already exists in this keyring." - echo " Aborting to avoid overwriting. Remove it first if intended:" + echo " Aborting to avoid overwriting. Remove it first:" echo " gpg --batch --yes --delete-secret-keys ${FPR}" echo " gpg --batch --yes --delete-keys ${FPR}" exit 1 fi -cat > /tmp/gpg-batch-primary-$$ < "${BATCH_FILE}" < /tmp/gpg-addkey-$$.exp < " -send "addkey\r" -expect "keyt" -send "4\r" -expect "keys" -send "${KEY_LENGTH}\r" -expect "expire" -send "0\r" -expect "y/N" -send "y\r" -expect "y/N" -send "y\r" -expect "gpg> " -send "save\r" -expect eof -EOF -chmod +x /tmp/gpg-addkey-$$.exp - -echo "[*] Adding signing-only subkey ..." -/tmp/gpg-addkey-$$.exp "${PRIMARY_KEYID}" - -SUBKEY_FPR=$(gpg --list-keys --with-colons "${KEY_EMAIL}" | awk -F: '/^sub:/ {print $5; exit}') -echo "=== Signing subkey fingerprint: ${SUBKEY_FPR} ===" +echo "=== Signing subkey: ${SUBKEY_KEYID} ===" OUT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +PUB_FILE="${OUT_DIR}/public.key" +SEC_FILE="${OUT_DIR}/secret-subkey.asc" -echo "[*] Exporting public key -> ${OUT_DIR}/public.key" -gpg --armor --export "${KEY_EMAIL}" > "${OUT_DIR}/public.key" +echo "[*] Exporting public key -> ${PUB_FILE}" +gpg --armor --export "${KEY_EMAIL}" > "${PUB_FILE}" -echo "[*] Exporting secret subkey -> ${OUT_DIR}/secret-subkey.asc" -gpg --armor --export-secret-subkeys "${PRIMARY_KEYID}" > "${OUT_DIR}/secret-subkey.asc" || true -if [[ ! -s "${OUT_DIR}/secret-subkey.asc" ]]; then +echo "[*] Exporting secret subkey -> ${SEC_FILE}" +gpg --pinentry-mode loopback --passphrase "${SUBKEY_PASSPHRASE}" \ + --armor --export-secret-subkeys "${PRIMARY_KEYID}" > "${SEC_FILE}" || true +if [[ ! -s "${SEC_FILE}" ]]; then echo "ERROR: Failed to export secret subkey." >&2 exit 1 fi -chmod 600 "${OUT_DIR}/public.key" "${OUT_DIR}/secret-subkey.asc" +chmod 600 "${PUB_FILE}" "${SEC_FILE}" + +echo "[*] Saving passphrase -> ${PASSPHRASE_FILE}" +echo "${SUBKEY_PASSPHRASE}" > "${PASSPHRASE_FILE}" +chmod 600 "${PASSPHRASE_FILE}" cat < Secrets and variables -> Actions -> New repository secret -3. In GitHub, add these secrets to the apt-repository repo: - Settings -> Secrets and variables -> Actions -> New repository secret - - Name: APT_SIGNING_SUBKEY - Value: contents of secret-subkey.asc (the whole armored block) - - Name: APT_SIGNING_PASSPHRASE - Value: leave blank / unset unless the exported subkey is passphrase-protected - (the publish-repo.yml worklow invokes gpg with --pinentry-mode loopback - and APT_SIGNING_PASSPHRASE at signing time). +3. After storing secrets, delete the temporary files: + rm -f ${PASSPHRASE_FILE} + rm -f ${SEC_FILE} 4. Keep the primary key offline / air-gapped permanently. - If the subkey leaks, revoke it from the offline primary key and - generate a new signing subkey. - -5. Re-run .github/workflows/publish-repo.yml to verify signing works. ============================================================= EOF