Fix: Isolate installer GPG inspection
This commit is contained in:
@@ -6,10 +6,16 @@
|
|||||||
|
|
||||||
declare -gA INSTALLER_PROVENANCE=()
|
declare -gA INSTALLER_PROVENANCE=()
|
||||||
|
|
||||||
_primary_key_fingerprints() {
|
_primary_key_fingerprints() (
|
||||||
gpg --batch --with-colons --import-options show-only --import "$1" 2>/dev/null \
|
local home
|
||||||
|
home="$(mktemp -d)" || exit 1
|
||||||
|
chmod 700 "$home"
|
||||||
|
trap 'rm -rf -- "$home"' EXIT
|
||||||
|
trap 'exit 130' INT
|
||||||
|
trap 'exit 143' TERM
|
||||||
|
GNUPGHOME="$home" 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 }'
|
| awk -F: '$1 == "pub" { primary = 1; next } primary && $1 == "fpr" { print $10; primary = 0 }'
|
||||||
}
|
)
|
||||||
|
|
||||||
key_fingerprint_matches() {
|
key_fingerprint_matches() {
|
||||||
local file="$1" expected="$2"
|
local file="$1" expected="$2"
|
||||||
@@ -27,13 +33,15 @@ _key_has_one_primary() {
|
|||||||
verify_detached_signature() {
|
verify_detached_signature() {
|
||||||
local key="$1" signature="$2" content="$3" home
|
local key="$1" signature="$2" content="$3" home
|
||||||
_key_has_one_primary "$key" || return 1
|
_key_has_one_primary "$key" || return 1
|
||||||
home="$(mktemp -d)" || return 1
|
(
|
||||||
|
home="$(mktemp -d)" || exit 1
|
||||||
chmod 700 "$home"
|
chmod 700 "$home"
|
||||||
|
trap 'rm -rf -- "$home"' EXIT
|
||||||
|
trap 'exit 130' INT
|
||||||
|
trap 'exit 143' TERM
|
||||||
GNUPGHOME="$home" gpg --batch --quiet --import "$key" >/dev/null 2>&1 \
|
GNUPGHOME="$home" gpg --batch --quiet --import "$key" >/dev/null 2>&1 \
|
||||||
&& GNUPGHOME="$home" gpg --batch --verify "$signature" "$content" >/dev/null 2>&1
|
&& GNUPGHOME="$home" gpg --batch --verify "$signature" "$content" >/dev/null 2>&1
|
||||||
local status=$?
|
)
|
||||||
rm -rf -- "$home"
|
|
||||||
return "$status"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
download_sha256() {
|
download_sha256() {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ config="$repo_dir/setup/provenance/installers.conf"
|
|||||||
test_tmp="$(mktemp -d)"
|
test_tmp="$(mktemp -d)"
|
||||||
host_gnupg="${GNUPGHOME:-$HOME/.gnupg}"
|
host_gnupg="${GNUPGHOME:-$HOME/.gnupg}"
|
||||||
host_rpmdb="/usr/lib/sysimage/rpm/rpmdb.sqlite"
|
host_rpmdb="/usr/lib/sysimage/rpm/rpmdb.sqlite"
|
||||||
|
ambient_gnupg="$test_tmp/fresh-ambient-gnupg"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm -rf -- "$test_tmp"
|
rm -rf -- "$test_tmp"
|
||||||
@@ -55,6 +56,14 @@ snapshot_gpg_state() {
|
|||||||
done < <(find "$path" -maxdepth 1 -type f \( -name pubring.kbx -o -name trustdb.gpg \) | sort)
|
done < <(find "$path" -maxdepth 1 -type f \( -name pubring.kbx -o -name trustdb.gpg \) | sort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export GNUPGHOME="$ambient_gnupg"
|
||||||
|
mkdir -m 700 "$ambient_gnupg"
|
||||||
|
ambient_before="$(snapshot "$ambient_gnupg")"
|
||||||
|
ambient_gpg_files_before="$(snapshot_gpg_state "$ambient_gnupg")"
|
||||||
|
before_gnupg="$(snapshot "$host_gnupg")"
|
||||||
|
before_gpg_files="$(snapshot_gpg_state "$host_gnupg")"
|
||||||
|
before_rpmdb="$(snapshot "$host_rpmdb")"
|
||||||
|
|
||||||
# This must be the only production file sourced by the contract.
|
# This must be the only production file sourced by the contract.
|
||||||
# shellcheck source=../../setup/lib/artifact-provenance
|
# shellcheck source=../../setup/lib/artifact-provenance
|
||||||
source "$repo_dir/setup/lib/artifact-provenance"
|
source "$repo_dir/setup/lib/artifact-provenance"
|
||||||
@@ -70,6 +79,10 @@ base64 --decode "$fixtures/wrong-signer-fixture.rpm.base64" > "$test_tmp/wrong-s
|
|||||||
|| fail 'tampered artifact does not differ by exactly one byte'
|
|| fail 'tampered artifact does not differ by exactly one byte'
|
||||||
|
|
||||||
expect_success key_fingerprint_matches "$fixtures/fixture-key.asc" "$fixture_fingerprint"
|
expect_success key_fingerprint_matches "$fixtures/fixture-key.asc" "$fixture_fingerprint"
|
||||||
|
[[ "$ambient_before" == "$(snapshot "$ambient_gnupg")" ]] \
|
||||||
|
|| fail 'fingerprint inspection created ambient GPG state'
|
||||||
|
[[ "$ambient_gpg_files_before" == "$(snapshot_gpg_state "$ambient_gnupg")" ]] \
|
||||||
|
|| fail 'fingerprint inspection created an ambient GPG keybox or trust database'
|
||||||
expect_failure key_fingerprint_matches "$fixtures/fixture-key.asc" '0000000000000000000000000000000000000000'
|
expect_failure key_fingerprint_matches "$fixtures/fixture-key.asc" '0000000000000000000000000000000000000000'
|
||||||
cat "$fixtures/fixture-key.asc" "$fixtures/wrong-signer-key.asc" > "$test_tmp/combined-key.asc"
|
cat "$fixtures/fixture-key.asc" "$fixtures/wrong-signer-key.asc" > "$test_tmp/combined-key.asc"
|
||||||
expect_failure key_fingerprint_matches "$test_tmp/combined-key.asc" "$fixture_fingerprint"
|
expect_failure key_fingerprint_matches "$test_tmp/combined-key.asc" "$fixture_fingerprint"
|
||||||
@@ -78,6 +91,8 @@ expect_success verify_detached_signature \
|
|||||||
"$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/SHASUMS256.txt"
|
"$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/SHASUMS256.txt"
|
||||||
expect_failure verify_detached_signature \
|
expect_failure verify_detached_signature \
|
||||||
"$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/tiny-artifact"
|
"$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/tiny-artifact"
|
||||||
|
expect_failure verify_detached_signature \
|
||||||
|
"$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/tiny-artifact-tampered"
|
||||||
cp "$fixtures/SHASUMS256.txt.asc" "$test_tmp/bad-signature.asc"
|
cp "$fixtures/SHASUMS256.txt.asc" "$test_tmp/bad-signature.asc"
|
||||||
sed -i 's/^=MJqv$/=MJqa/' "$test_tmp/bad-signature.asc"
|
sed -i 's/^=MJqv$/=MJqa/' "$test_tmp/bad-signature.asc"
|
||||||
expect_failure verify_detached_signature \
|
expect_failure verify_detached_signature \
|
||||||
@@ -159,9 +174,6 @@ expect_failure download_sha256 'https://fixture.invalid/interrupted' "$tiny_sha2
|
|||||||
assert_file_bytes "$destination" 'known-good'
|
assert_file_bytes "$destination" 'known-good'
|
||||||
[[ ! -e "$destination.part" ]] || fail 'interrupted download left a part file'
|
[[ ! -e "$destination.part" ]] || fail 'interrupted download left a part file'
|
||||||
|
|
||||||
before_gnupg="$(snapshot "$host_gnupg")"
|
|
||||||
before_gpg_files="$(snapshot_gpg_state "$host_gnupg")"
|
|
||||||
before_rpmdb="$(snapshot "$host_rpmdb")"
|
|
||||||
expect_success rpm_signature_matches \
|
expect_success rpm_signature_matches \
|
||||||
"$test_tmp/signed-fixture.rpm" "$fixtures/fixture-key.asc" "$fixture_fingerprint"
|
"$test_tmp/signed-fixture.rpm" "$fixtures/fixture-key.asc" "$fixture_fingerprint"
|
||||||
expect_failure rpm_signature_matches \
|
expect_failure rpm_signature_matches \
|
||||||
@@ -175,6 +187,9 @@ expect_failure rpm_signature_matches \
|
|||||||
[[ "$before_gnupg" == "$(snapshot "$host_gnupg")" ]] || fail 'host GPG state changed'
|
[[ "$before_gnupg" == "$(snapshot "$host_gnupg")" ]] || fail 'host GPG state changed'
|
||||||
[[ "$before_gpg_files" == "$(snapshot_gpg_state "$host_gnupg")" ]] || fail 'host GPG keybox or trust database changed'
|
[[ "$before_gpg_files" == "$(snapshot_gpg_state "$host_gnupg")" ]] || fail 'host GPG keybox or trust database changed'
|
||||||
[[ "$before_rpmdb" == "$(snapshot "$host_rpmdb")" ]] || fail 'host RPM database changed'
|
[[ "$before_rpmdb" == "$(snapshot "$host_rpmdb")" ]] || fail 'host RPM database changed'
|
||||||
|
[[ "$ambient_before" == "$(snapshot "$ambient_gnupg")" ]] || fail 'production helper created ambient GPG state'
|
||||||
|
[[ "$ambient_gpg_files_before" == "$(snapshot_gpg_state "$ambient_gnupg")" ]] \
|
||||||
|
|| fail 'production helper created an ambient GPG keybox or trust database'
|
||||||
|
|
||||||
expect_success load_installer_provenance "$config"
|
expect_success load_installer_provenance "$config"
|
||||||
[[ "${INSTALLER_PROVENANCE[BUN_VERSION]:-}" == '1.4.0' ]] || fail 'valid provenance was not loaded'
|
[[ "${INSTALLER_PROVENANCE[BUN_VERSION]:-}" == '1.4.0' ]] || fail 'valid provenance was not loaded'
|
||||||
|
|||||||
Reference in New Issue
Block a user