Fix: Harden installer provenance boundary

This commit is contained in:
Gabriel Brown
2026-08-27 05:56:46 -04:00
parent 27acbe7a95
commit 94a4314730
8 changed files with 245 additions and 19 deletions
+24 -8
View File
@@ -6,15 +6,27 @@
declare -gA INSTALLER_PROVENANCE=()
_primary_key_fingerprints() {
gpg --batch --with-colons --import-options show-only --import "$1" 2>/dev/null \
| awk -F: '$1 == "pub" { primary = 1; next } primary && $1 == "fpr" { print $10; primary = 0 }'
}
key_fingerprint_matches() {
local file="$1" expected="$2" actual
actual="$(gpg --batch --with-colons --import-options show-only --import "$file" 2>/dev/null \
| awk -F: '$1 == "fpr" { print $10; exit }')"
[[ "$actual" == "$expected" ]]
local file="$1" expected="$2"
local -a primary_fingerprints=()
mapfile -t primary_fingerprints < <(_primary_key_fingerprints "$file")
[[ ${#primary_fingerprints[@]} -eq 1 && "${primary_fingerprints[0]}" == "$expected" ]]
}
_key_has_one_primary() {
local -a primary_fingerprints=()
mapfile -t primary_fingerprints < <(_primary_key_fingerprints "$1")
[[ ${#primary_fingerprints[@]} -eq 1 ]]
}
verify_detached_signature() {
local key="$1" signature="$2" content="$3" home
_key_has_one_primary "$key" || return 1
home="$(mktemp -d)" || return 1
chmod 700 "$home"
GNUPGHOME="$home" gpg --batch --quiet --import "$key" >/dev/null 2>&1 \
@@ -25,18 +37,22 @@ verify_detached_signature() {
}
download_sha256() {
local url="$1" expected="$2" max_bytes="$3" destination="$4" actual
local url="$1" expected="$2" max_bytes="$3" destination="$4" actual directory filename
[[ "$expected" =~ ^[0-9a-f]{64}$ ]] || return 1
actual="$expected"
local part="${destination}.part"
directory="$(dirname -- "$destination")"
filename="$(basename -- "$destination")"
(
trap 'rm -f -- "$part"' EXIT
local part=""
trap '[[ -z "$part" ]] || rm -f -- "$part"' EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
[[ "$max_bytes" =~ ^[1-9][0-9]*$ ]] || exit 1
[[ -n "$destination" && -d "$(dirname "$destination")" ]] || exit 1
[[ -n "$destination" && -d "$directory" ]] || exit 1
umask 077
part="$(mktemp "$directory/.${filename}.part.XXXXXX")" || exit 1
curl --fail --location --connect-timeout 10 --max-time 600 \
--max-filesize "$max_bytes" --output "$part" "$url" \
|| exit 1