test-native-provenance.sh

2.7 KB · raw

1#!/bin/sh2# Hermetic negative-path tests for the native-library provenance allow-list.3# No Android SDK, Gradle, or built APK is required.4set -eu56SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)7ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)8CHECK="$SCRIPT_DIR/check-native-provenance.py"9TEMP_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/peach-native-provenance-tests.XXXXXX")10trap 'trash "$TEMP_ROOT"' EXIT HUP INT TERM1112cp -R "$ROOT/docs/." "$TEMP_ROOT/docs"13mkdir -p "$TEMP_ROOT/scripts"14mkdir -p "$TEMP_ROOT/app/src/main/jniLibs/arm64-v8a" "$TEMP_ROOT/app/src/main/jniLibs/x86_64"15cp "$ROOT/app/src/main/jniLibs/arm64-v8a/libpeach_noise_core.so" "$TEMP_ROOT/app/src/main/jniLibs/arm64-v8a/"16cp "$ROOT/app/src/main/jniLibs/x86_64/libpeach_noise_core.so" "$TEMP_ROOT/app/src/main/jniLibs/x86_64/"17# The checker resolves the repository root as its own parent's parent, so it has18# to sit in a `scripts/` directory of the temporary tree, not at its root.19cp "$CHECK" "$TEMP_ROOT/scripts/check-native-provenance.py"2021# Positive control: the genuine tree passes.22python3 "$TEMP_ROOT/scripts/check-native-provenance.py" || exit 12324# An unrecorded library in the source set is refused even though every recorded25# digest still matches (PB-26-123): the inventory is an allow-list.26: > "$TEMP_ROOT/app/src/main/jniLibs/arm64-v8a/libextra.so"27if python3 "$TEMP_ROOT/scripts/check-native-provenance.py" >/dev/null 2>&1; then28    echo "FAIL: an unrecorded native library was accepted" >&229    exit 130fi31trash "$TEMP_ROOT/app/src/main/jniLibs/arm64-v8a/libextra.so"32python3 "$TEMP_ROOT/scripts/check-native-provenance.py" || exit 13334# A library that reached the artifact only through a dependency never appears35# under jniLibs, so the packaged APK is checked directly. Here the recorded set36# is present and correct; only the extra entry must refuse.37python3 - "$TEMP_ROOT/fake.apk" \38    "$TEMP_ROOT/app/src/main/jniLibs/arm64-v8a/libpeach_noise_core.so" <<'PY'39import sys, zipfile40apk, noise_core = sys.argv[1], sys.argv[2]41with open(noise_core, "rb") as stream:42    payload = stream.read()43with zipfile.ZipFile(apk, "w") as archive:44    archive.writestr("lib/arm64-v8a/libpeach_noise_core.so", payload)45    archive.writestr("lib/arm64-v8a/libdependency.so", b"unreviewed")46PY47if python3 "$TEMP_ROOT/scripts/check-native-provenance.py" "$TEMP_ROOT/fake.apk" >/dev/null 2>&1; then48    echo "FAIL: an unrecorded packaged native library was accepted" >&249    exit 150fi5152# A recorded library whose bytes changed is refused.53printf '\n' >> "$TEMP_ROOT/app/src/main/jniLibs/arm64-v8a/libpeach_noise_core.so"54if python3 "$TEMP_ROOT/scripts/check-native-provenance.py" >/dev/null 2>&1; then55    echo "FAIL: mutated native library was accepted" >&256    exit 157fi5859printf 'PASS: native provenance allow-list and drift gate\n'