Test: Add installer provenance boundary

This commit is contained in:
Gabriel Brown
2026-08-27 05:43:26 -04:00
parent fc8f226747
commit 27acbe7a95
20 changed files with 915 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
#!/usr/bin/env bash
# The production change that breaks these cases is accepting an unverified
# download, a wrong signer, or executable/malformed provenance data.
set -euo pipefail
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
fixtures="$repo_dir/tests/setup/fixtures/provenance"
config="$repo_dir/setup/provenance/installers.conf"
test_tmp="$(mktemp -d)"
host_gnupg="${GNUPGHOME:-$HOME/.gnupg}"
host_rpmdb="/usr/lib/sysimage/rpm/rpmdb.sqlite"
cleanup() {
rm -rf -- "$test_tmp"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
fail() {
printf 'package provenance contract: %s\n' "$*" >&2
exit 1
}
expect_success() {
"$@" || fail "expected success: $*"
}
expect_failure() {
if "$@"; then
fail "expected failure: $*"
fi
}
assert_file_bytes() {
local path="$1" expected="$2"
[[ "$(<"$path")" == "$expected" ]] || fail "unexpected bytes in $path"
}
snapshot() {
local path="$1"
if [[ -e "$path" ]]; then
stat -c '%i:%s:%Y:%Z' "$path"
else
printf 'absent'
fi
}
# This must be the only production file sourced by the contract.
# shellcheck source=../../setup/lib/artifact-provenance
source "$repo_dir/setup/lib/artifact-provenance"
fixture_fingerprint='6016FF18CAE298CE3648EE2325E01F765E1EF9FA'
tiny_sha256='291bd319ae85488101e908e37fc0fa1b0da1429ba27e10d2b391cb3f60dd44ea'
base64 --decode "$fixtures/signed-fixture.rpm.base64" > "$test_tmp/signed-fixture.rpm"
base64 --decode "$fixtures/unsigned-fixture.rpm.base64" > "$test_tmp/unsigned-fixture.rpm"
expect_success key_fingerprint_matches "$fixtures/fixture-key.asc" "$fixture_fingerprint"
expect_failure key_fingerprint_matches "$fixtures/fixture-key.asc" '0000000000000000000000000000000000000000'
expect_success verify_detached_signature \
"$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/SHASUMS256.txt"
expect_failure verify_detached_signature \
"$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/tiny-artifact"
cp "$fixtures/SHASUMS256.txt.asc" "$test_tmp/bad-signature.asc"
sed -i 's/^=nTYb$/=nTYa/' "$test_tmp/bad-signature.asc"
expect_failure verify_detached_signature \
"$fixtures/fixture-key.asc" "$test_tmp/bad-signature.asc" "$fixtures/SHASUMS256.txt"
mkdir "$test_tmp/bin"
cat > "$test_tmp/bin/curl" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
output=''
while (($#)); do
case "$1" in
--output) output="$2"; shift 2 ;;
*) shift ;;
esac
done
case "${CURL_FIXTURE:?}" in
good) cp "$CURL_FIXTURE_ROOT/tiny-artifact" "$output" ;;
oversized) head -c 1025 /dev/zero > "$output" ;;
interrupted) printf 'partial' > "$output"; exit 42 ;;
*) exit 64 ;;
esac
STUB
chmod +x "$test_tmp/bin/curl"
PATH="$test_tmp/bin:$PATH"
export PATH CURL_FIXTURE_ROOT="$fixtures"
destination="$test_tmp/destination"
export CURL_FIXTURE=good
expect_success download_sha256 'https://fixture.invalid/good' "$tiny_sha256" 1024 "$destination"
cmp -s "$fixtures/tiny-artifact" "$destination" || fail 'verified download changed artifact bytes'
[[ ! -e "$destination.part" ]] || fail 'successful download left a part file'
export CURL_FIXTURE=good
expect_failure download_sha256 'https://fixture.invalid/uppercase-digest' \
'291BD319AE85488101E908E37FC0FA1B0DA1429BA27E10D2B391CB3F60DD44EA' 1024 \
"$test_tmp/uppercase-destination"
printf 'known-good\n' > "$destination"
export CURL_FIXTURE=good
expect_failure download_sha256 'https://fixture.invalid/bad-digest' \
'0000000000000000000000000000000000000000000000000000000000000000' 1024 "$destination"
assert_file_bytes "$destination" 'known-good'
[[ ! -e "$destination.part" ]] || fail 'bad digest left a part file'
export CURL_FIXTURE=oversized
expect_failure download_sha256 'https://fixture.invalid/oversized' "$tiny_sha256" 1024 "$destination"
assert_file_bytes "$destination" 'known-good'
[[ ! -e "$destination.part" ]] || fail 'oversized download left a part file'
export CURL_FIXTURE=interrupted
expect_failure download_sha256 'https://fixture.invalid/interrupted' "$tiny_sha256" 1024 "$destination"
assert_file_bytes "$destination" 'known-good'
[[ ! -e "$destination.part" ]] || fail 'interrupted download left a part file'
before_gnupg="$(snapshot "$host_gnupg")"
before_rpmdb="$(snapshot "$host_rpmdb")"
expect_success rpm_signature_matches \
"$test_tmp/signed-fixture.rpm" "$fixtures/fixture-key.asc" "$fixture_fingerprint"
expect_failure rpm_signature_matches \
"$test_tmp/unsigned-fixture.rpm" "$fixtures/fixture-key.asc" "$fixture_fingerprint"
expect_failure rpm_signature_matches \
"$test_tmp/signed-fixture.rpm" "$fixtures/fixture-key.asc" '0000000000000000000000000000000000000000'
[[ "$before_gnupg" == "$(snapshot "$host_gnupg")" ]] || fail 'host GPG state changed'
[[ "$before_rpmdb" == "$(snapshot "$host_rpmdb")" ]] || fail 'host RPM database changed'
expect_success load_installer_provenance "$config"
[[ "${INSTALLER_PROVENANCE[BUN_VERSION]:-}" == '1.4.0' ]] || fail 'valid provenance was not loaded'
parser_fixture="$test_tmp/installers.conf"
cp "$config" "$parser_fixture"
printf 'UNKNOWN_KEY=value\n' >> "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"
cp "$config" "$parser_fixture"
printf 'BUN_VERSION=1.4.0\n' >> "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"
grep -v '^NODE_VERSION=' "$config" > "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"
cp "$config" "$parser_fixture"
sed -i 's/^BUN_VERSION=/ BUN_VERSION=/' "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"
cp "$config" "$parser_fixture"
sed -i 's/^BUN_VERSION=.*/BUN_VERSION=$(id -u)/' "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"
cp "$config" "$parser_fixture"
printf 'BUN_ARMV7_URL=https://fixture.invalid/bun\n' >> "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"
printf 'package provenance contract: PASS\n'