from __future__ import annotations
import argparse
from datetime import datetime, timezone
import hashlib
import json
from pathlib import Path
import sys
from typing import Any
class ProofValidationError(RuntimeError):
pass
def is_sha256(value: Any) -> bool:
return (
isinstance(value, str)
and len(value) == 64
and all(character in "0123456789abcdef" for character in value)
)
def is_git_oid(value: Any) -> bool:
return (
isinstance(value, str)
and len(value) == 40
and all(character in "0123456789abcdef" for character in value)
)
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def load_json(path: Path) -> dict[str, Any]:
try:
value = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as error:
raise ProofValidationError(f"cannot read JSON {path}: {error}") from error
if not isinstance(value, dict):
raise ProofValidationError(f"JSON root is not an object: {path}")
return value
def locate_artifact(
proof: Path,
proof_directory: Path,
gate: str,
artifact: dict[str, Any],
) -> Path:
original = artifact.get("path")
name = artifact.get("name")
if not name and original:
name = Path(str(original)).name
if not isinstance(name, str) or not name or Path(name).name != name:
raise ProofValidationError("proof artifact name is invalid")
candidates = [
proof.parent / name,
proof_directory / "artifacts" / gate / name,
]
if isinstance(original, str) and original:
candidates.append(Path(original))
for candidate in candidates:
if candidate.is_file():
return candidate.resolve()
raise ProofValidationError(f"proof artifact is missing: {name}")
def verify_artifacts(
proof: Path,
proof_directory: Path,
gate: str,
payload: dict[str, Any],
) -> dict[str, Path]:
artifacts = payload.get("artifacts")
if not isinstance(artifacts, list) or not artifacts:
raise ProofValidationError("proof contains no artifacts")
located: dict[str, Path] = {}
for raw in artifacts:
if not isinstance(raw, dict):
raise ProofValidationError("proof artifact entry is not an object")
path = locate_artifact(proof, proof_directory, gate, raw)
expected_size = raw.get("size")
expected_hash = raw.get("sha256")
if not isinstance(expected_size, int) or expected_size < 0:
raise ProofValidationError(f"artifact size is invalid: {path}")
if not is_sha256(expected_hash):
raise ProofValidationError(f"artifact hash is invalid: {path}")
if path.stat().st_size != expected_size:
raise ProofValidationError(f"artifact size mismatch: {path}")
actual_hash = sha256(path)
if actual_hash != expected_hash:
raise ProofValidationError(f"artifact hash mismatch: {path}")
if path.name in located:
raise ProofValidationError(f"duplicate proof artifact name: {path.name}")
located[path.name] = path
return located
def metadata(payload: dict[str, Any]) -> dict[str, str]:
value = payload.get("metadata")
if not isinstance(value, dict):
raise ProofValidationError("proof metadata is missing")
if not all(isinstance(key, str) and isinstance(item, str) for key, item in value.items()):
raise ProofValidationError("proof metadata must contain strings")
return value
def require_artifact(located: dict[str, Path], name: str) -> Path:
try:
return located[name]
except KeyError as error:
raise ProofValidationError(f"required proof artifact is absent: {name}") from error
def require_expected_hash(label: str, actual: Any, expected: str | None) -> None:
if expected is None:
return
if not is_sha256(expected):
raise ProofValidationError(f"expected {label} hash is invalid")
if actual != expected:
raise ProofValidationError(f"{label} hash differs from the certified artifact")
def validate_embedded_artifact(
evidence: dict[str, Any], located: dict[str, Path], name: str
) -> None:
raw_artifacts = evidence.get("artifacts")
if not isinstance(raw_artifacts, list):
raise ProofValidationError("evidence artifact list is missing")
matching = [
item
for item in raw_artifacts
if isinstance(item, dict) and item.get("name") == name
]
if len(matching) != 1:
raise ProofValidationError(f"evidence must name exactly one {name} artifact")
item = matching[0]
path = require_artifact(located, name)
if item.get("size") != path.stat().st_size or item.get("sha256") != sha256(path):
raise ProofValidationError(f"evidence artifact binding differs: {name}")
def validate_upstream(
payload: dict[str, Any],
located: dict[str, Path],
upstream_commit: str,
source_tree: str,
suite: str,
log_name: str,
marker_prefix: str,
expected_daemon_sha256: str | None,
expected_client_sha256: str | None,
expected_nss_sha256: str | None,
) -> None:
values = metadata(payload)
if values.get("suite") != suite:
raise ProofValidationError("upstream proof names the wrong suite")
if values.get("unmodified-recorded-files") != "true":
raise ProofValidationError("upstream proof does not attest unmodified recorded files")
evidence = load_json(require_artifact(located, "evidence.json"))
if evidence.get("schema") != 1:
raise ProofValidationError("unsupported upstream evidence schema")
if evidence.get("suite") != suite:
raise ProofValidationError("upstream evidence names the wrong suite")
if evidence.get("unmodified_recorded_upstream_files") is not True:
raise ProofValidationError("upstream test hashes were not preserved")
if evidence.get("upstream_commit") != upstream_commit:
raise ProofValidationError("upstream evidence uses another baseline")
if evidence.get("source_tree") != source_tree:
raise ProofValidationError("upstream evidence source tree is stale")
for name in ("daemon_sha256", "client_sha256"):
if not is_sha256(evidence.get(name)):
raise ProofValidationError(f"upstream evidence {name} is invalid")
require_expected_hash(
"upstream daemon", evidence["daemon_sha256"], expected_daemon_sha256
)
require_expected_hash(
"upstream client", evidence["client_sha256"], expected_client_sha256
)
marker = evidence.get("runtime_marker")
expected_marker = marker_prefix + source_tree + "_" + evidence["daemon_sha256"]
if suite == "TEST-75-RESOLVED":
if not is_sha256(evidence.get("nss_module_sha256")):
raise ProofValidationError("upstream evidence nss_module_sha256 is invalid")
require_expected_hash(
"upstream NSS module",
evidence["nss_module_sha256"],
expected_nss_sha256,
)
expected_marker += "_" + evidence["nss_module_sha256"]
if marker != expected_marker:
raise ProofValidationError("candidate runtime marker is missing")
log = require_artifact(located, log_name)
raw_log = evidence.get("log")
if not isinstance(raw_log, dict) or raw_log.get("name") != log_name:
raise ProofValidationError("upstream evidence log metadata is missing")
if raw_log.get("size") != log.stat().st_size or raw_log.get("sha256") != sha256(log):
raise ProofValidationError("upstream evidence log binding differs")
if marker.encode() not in log.read_bytes():
raise ProofValidationError("candidate runtime marker is absent from the suite log")
def validate_security(
payload: dict[str, Any], located: dict[str, Path], source_commit: str
) -> None:
values = metadata(payload)
required = {"fuzz", "asan", "ubsan", "miri", "tsan", "valgrind"}
profiles = {
item.strip()
for item in values.get("profiles", "").split(",")
if item.strip()
}
if profiles != required:
raise ProofValidationError(
"security proof profiles differ: " + repr(sorted(profiles))
)
evidence = load_json(require_artifact(located, "security-evidence.json"))
if evidence.get("schema") != 2:
raise ProofValidationError("unsupported security evidence schema")
if evidence.get("source_commit") != source_commit:
raise ProofValidationError("security evidence source commit is stale")
repository = evidence.get("repository")
if (
not isinstance(repository, str)
or not repository
or repository.count("/") != 1
or any(character.isspace() for character in repository)
):
raise ProofValidationError("security evidence repository is invalid")
host = payload.get("host")
if not isinstance(host, dict) or host.get("github_repository") != repository:
raise ProofValidationError("security proof repository binding differs")
workflow = evidence.get("workflow")
if (
not isinstance(workflow, dict)
or set(workflow) != {"id", "name", "path"}
or not isinstance(workflow.get("id"), int)
or workflow["id"] <= 0
or workflow.get("name") != "Replacement security gates"
or workflow.get("path")
!= ".github/workflows/replacement-security-gates.yml"
):
raise ProofValidationError("security workflow identity differs")
run = evidence.get("run")
if (
not isinstance(run, dict)
or set(run)
!= {
"id",
"attempt",
"event",
"conclusion",
"repository",
"head_repository",
"workflow_head_sha",
"head_branch",
"workflow_path",
"workflow_name",
"display_title",
}
or not isinstance(run.get("id"), int)
or run["id"] <= 0
or not isinstance(run.get("attempt"), int)
or run["attempt"] <= 0
or run.get("event") != "workflow_dispatch"
or run.get("conclusion") != "success"
or run.get("repository") != repository
or run.get("head_repository") != repository
or run.get("workflow_head_sha") != source_commit
or run.get("head_branch") != "main"
or run.get("workflow_path") != workflow["path"]
or run.get("workflow_name")
!= f"Replacement security gates {source_commit}"
or run.get("display_title")
!= f"Replacement security gates {source_commit}"
):
raise ProofValidationError("security workflow run identity differs")
if evidence.get("missing") != []:
raise ProofValidationError("security evidence still has missing categories")
required_categories = evidence.get("required_categories")
if (
not isinstance(required_categories, list)
or len(required_categories) != len(required)
or set(required_categories) != required
):
raise ProofValidationError("security evidence category set differs")
matched = evidence.get("matched")
if not isinstance(matched, dict) or set(matched) != required:
raise ProofValidationError("security evidence matched-job set differs")
expected_jobs = {
"fuzz": "libFuzzer corpus and smoke",
"asan": "Address Sanitizer ASan",
"ubsan": "Undefined Behavior Sanitizer UBSan",
"miri": "Miri strict provenance",
"tsan": "Thread Sanitizer TSan",
"valgrind": "Valgrind NSS Varlink and DNS fallback",
}
seen_job_ids: set[int] = set()
matched_items: list[dict[str, Any]] = []
for category in required:
values = matched.get(category)
if not isinstance(values, list) or len(values) != 1:
raise ProofValidationError(f"security category has no successful job: {category}")
item = values[0]
steps = item.get("steps") if isinstance(item, dict) else None
if (
not isinstance(item, dict)
or "head_sha" in item
or item.get("repository") != repository
or item.get("requested_source_commit") != source_commit
or item.get("workflow_id") != workflow["id"]
or item.get("workflow_name") != workflow["name"]
or item.get("workflow_path") != workflow["path"]
or item.get("run_id") != run["id"]
or item.get("run_attempt") != run["attempt"]
or item.get("event") != run["event"]
or item.get("workflow_head_sha") != run["workflow_head_sha"]
or item.get("workflow_head_branch") != run["head_branch"]
or item.get("workflow_head_repository") != run["head_repository"]
or item.get("workflow_display_title") != run["display_title"]
or item.get("job_name") != expected_jobs[category]
or item.get("job_conclusion") != "success"
or item.get("job_run_id") != run["id"]
or item.get("job_run_attempt") != run["attempt"]
or item.get("job_head_sha") != source_commit
or item.get("job_head_branch") != run["head_branch"]
or item.get("job_workflow_name") != run["workflow_name"]
or not isinstance(item.get("job_id"), int)
or item["job_id"] <= 0
or not isinstance(item.get("html_url"), str)
or not item["html_url"].endswith(f"/actions/runs/{run['id']}")
or not isinstance(item.get("created_at"), str)
or not isinstance(item.get("updated_at"), str)
or not isinstance(steps, list)
or not all(isinstance(step, str) and step for step in steps)
or "Verify exact source identity" not in steps
):
raise ProofValidationError(f"security category evidence is malformed: {category}")
if item["job_id"] in seen_job_ids:
raise ProofValidationError("security evidence contains duplicate job ids")
seen_job_ids.add(item["job_id"])
matched_items.append(item)
all_evidence = evidence.get("all_successful_job_evidence")
if (
not isinstance(all_evidence, list)
or len(all_evidence) != len(matched_items)
or {item.get("job_id") for item in all_evidence if isinstance(item, dict)}
!= seen_job_ids
or {
json.dumps(item, sort_keys=True, separators=(",", ":"))
for item in all_evidence
if isinstance(item, dict)
}
!= {
json.dumps(item, sort_keys=True, separators=(",", ":"))
for item in matched_items
}
):
raise ProofValidationError("security successful-job evidence set differs")
def validate_boot(
payload: dict[str, Any],
located: dict[str, Path],
source_commit: str,
source_tree: str,
upstream_commit: str,
expected_daemon_sha256: str | None,
expected_client_sha256: str | None,
expected_nss_sha256: str | None,
) -> None:
values = metadata(payload)
if values.get("environment") != "qemu":
raise ProofValidationError("boot proof did not use QEMU")
if values.get("boot-count") != "2":
raise ProofValidationError("boot proof did not complete exactly two candidate boots")
if values.get("rollback-verified") != "true":
raise ProofValidationError("boot proof did not verify rollback")
evidence = load_json(require_artifact(located, "evidence.json"))
if evidence.get("schema") != 1:
raise ProofValidationError("unsupported boot evidence schema")
if evidence.get("environment") != "qemu":
raise ProofValidationError("boot evidence did not use QEMU")
if evidence.get("distribution") != "ubuntu" or evidence.get("release") != "noble":
raise ProofValidationError("boot evidence used an unexpected image")
if evidence.get("boot_count") != 2:
raise ProofValidationError("boot evidence count differs")
if evidence.get("candidate_healthy_each_boot") is not True:
raise ProofValidationError("candidate was not healthy on every boot")
if evidence.get("rollback_verified") is not True:
raise ProofValidationError("rollback did not pass")
if evidence.get("source_commit") != source_commit:
raise ProofValidationError("boot evidence source commit is stale")
if evidence.get("source_tree") != source_tree:
raise ProofValidationError("boot evidence source tree is stale")
if evidence.get("upstream_commit") != upstream_commit:
raise ProofValidationError("boot evidence uses another baseline")
for name in ("daemon_sha256", "client_sha256", "nss_module_sha256"):
if not is_sha256(evidence.get(name)):
raise ProofValidationError(f"boot evidence {name} is invalid")
require_expected_hash(
"boot daemon", evidence["daemon_sha256"], expected_daemon_sha256
)
require_expected_hash(
"boot client", evidence["client_sha256"], expected_client_sha256
)
require_expected_hash(
"boot NSS module", evidence["nss_module_sha256"], expected_nss_sha256
)
validate_embedded_artifact(evidence, located, "mkosi-build.log")
validate_embedded_artifact(evidence, located, "qemu-console.log")
console = require_artifact(located, "qemu-console.log").read_bytes()
required_markers = (
f"RUSTD_RESOLVED_CANDIDATE_BOOT_1_{evidence['daemon_sha256']}",
f"RUSTD_RESOLVED_CANDIDATE_BOOT_2_{evidence['daemon_sha256']}",
f"RUSTD_RESOLVED_CANDIDATE_NSS_BOOT_1_{evidence['nss_module_sha256']}",
f"RUSTD_RESOLVED_CANDIDATE_NSS_BOOT_2_{evidence['nss_module_sha256']}",
f"RUSTD_RESOLVED_BOOT_ROLLBACK_PASS_{upstream_commit}",
f"RUSTD_RESOLVED_BOOT_PROOF_PASS_{source_tree}_{evidence['daemon_sha256']}",
)
if any(marker.encode() not in console for marker in required_markers):
raise ProofValidationError("boot evidence log is missing a required runtime marker")
def validate_reproducible(
payload: dict[str, Any],
located: dict[str, Path],
source_commit: str,
source_tree: str,
upstream_commit: str,
expected_daemon_sha256: str | None,
expected_client_sha256: str | None,
expected_nss_sha256: str | None,
local_reproducible_directory: Path | None,
) -> None:
values = metadata(payload)
required_metadata = {
"build-count": "2",
"byte-identical": "true",
"cargo-release": "1.74.0",
"rustc-release": "1.74.0",
}
if values != required_metadata:
raise ProofValidationError("reproducible proof metadata differs")
required_names = {
"manifest.json",
"systemd-resolved",
"resolvectl",
"libnss_resolve.so.2",
"rustd-resolved.tar.gz",
"files.sha256",
"rust-toolchain.txt",
}
if set(located) != required_names:
raise ProofValidationError(
"reproducible proof artifact set differs: " + repr(sorted(located))
)
manifest_path = require_artifact(located, "manifest.json")
manifest = load_json(manifest_path)
if manifest.get("schema") != 2 or manifest.get("reproducible") is not True:
raise ProofValidationError("reproducible manifest schema or result is invalid")
if manifest.get("build_count") != 2:
raise ProofValidationError("reproducible manifest build count differs")
if manifest.get("source_commit") != source_commit:
raise ProofValidationError("reproducible manifest source commit is stale")
if manifest.get("source_tree") != source_tree:
raise ProofValidationError("reproducible manifest source tree is stale")
if manifest.get("upstream_commit") != upstream_commit:
raise ProofValidationError("reproducible manifest upstream baseline is stale")
if manifest.get("rustc_release") != "1.74.0":
raise ProofValidationError("reproducible manifest rustc release differs")
if manifest.get("cargo_release") != "1.74.0":
raise ProofValidationError("reproducible manifest cargo release differs")
for label, value in (
("rustc", manifest.get("rustc_sha256")),
("cargo", manifest.get("cargo_sha256")),
):
if not is_sha256(value):
raise ProofValidationError(
f"reproducible manifest {label} executable hash is invalid"
)
source_date_epoch = manifest.get("source_date_epoch")
if (
not isinstance(source_date_epoch, int)
or source_date_epoch < 0
or source_date_epoch > 253402300799
):
raise ProofValidationError("reproducible manifest source date epoch is invalid")
expected_generated_at = datetime.fromtimestamp(
source_date_epoch, tz=timezone.utc
).isoformat()
if manifest.get("generated_at") != expected_generated_at:
raise ProofValidationError(
"reproducible manifest generated timestamp differs"
)
expected_identical = {
"systemd-resolved",
"resolvectl",
"libnss_resolve.so.2",
"files.sha256",
"rustd-resolved.tar.gz",
}
raw_identical = manifest.get("byte_identical")
if (
not isinstance(raw_identical, list)
or len(raw_identical) != len(expected_identical)
or set(raw_identical) != expected_identical
):
raise ProofValidationError("reproducible manifest byte-identical set differs")
raw_artifacts = manifest.get("artifacts")
manifest_names = required_names - {"manifest.json"}
if not isinstance(raw_artifacts, list):
raise ProofValidationError("reproducible manifest artifact list is missing")
entries: dict[str, dict[str, Any]] = {}
for item in raw_artifacts:
if not isinstance(item, dict):
raise ProofValidationError("reproducible manifest artifact entry is malformed")
name = item.get("name")
if (
not isinstance(name, str)
or not name
or Path(name).name != name
or name in entries
):
raise ProofValidationError("reproducible manifest artifact name is invalid")
entries[name] = item
if set(entries) != manifest_names:
raise ProofValidationError("reproducible manifest artifact set differs")
for name, item in entries.items():
path = require_artifact(located, name)
if item.get("size") != path.stat().st_size or item.get("sha256") != sha256(path):
raise ProofValidationError(
f"reproducible manifest artifact binding differs: {name}"
)
toolchain = require_artifact(located, "rust-toolchain.txt").read_text(
encoding="utf-8"
)
if "rustc 1.74.0" not in toolchain or "cargo 1.74.0" not in toolchain:
raise ProofValidationError("reproducible toolchain evidence differs")
if (
f"rustc_binary_sha256 {manifest['rustc_sha256']}" not in toolchain
or f"cargo_binary_sha256 {manifest['cargo_sha256']}" not in toolchain
):
raise ProofValidationError(
"reproducible toolchain executable hash evidence differs"
)
require_expected_hash(
"reproducible daemon",
entries["systemd-resolved"].get("sha256"),
expected_daemon_sha256,
)
require_expected_hash(
"reproducible client",
entries["resolvectl"].get("sha256"),
expected_client_sha256,
)
require_expected_hash(
"reproducible NSS module",
entries["libnss_resolve.so.2"].get("sha256"),
expected_nss_sha256,
)
if local_reproducible_directory is not None:
local_directory = local_reproducible_directory.resolve()
local_manifest = load_json(local_directory / "manifest.json")
comparable_fields = (
"schema",
"reproducible",
"build_count",
"byte_identical",
"source_commit",
"source_tree",
"upstream_commit",
"source_date_epoch",
"generated_at",
"rustc_release",
"cargo_release",
"rustc_sha256",
"cargo_sha256",
)
if any(local_manifest.get(name) != manifest.get(name) for name in comparable_fields):
raise ProofValidationError(
"external reproducible manifest metadata differs from the local canonical release"
)
raw_local_artifacts = local_manifest.get("artifacts")
if not isinstance(raw_local_artifacts, list):
raise ProofValidationError(
"local canonical reproducible manifest artifact list is missing"
)
local_entries: dict[str, dict[str, Any]] = {}
for item in raw_local_artifacts:
if not isinstance(item, dict):
raise ProofValidationError(
"local canonical reproducible manifest artifact entry is malformed"
)
name = item.get("name")
if (
not isinstance(name, str)
or not name
or Path(name).name != name
or name in local_entries
):
raise ProofValidationError(
"local canonical reproducible manifest artifact name is invalid"
)
local_entries[name] = item
if set(local_entries) != manifest_names:
raise ProofValidationError(
"local canonical reproducible manifest artifact set differs"
)
for name, item in local_entries.items():
path = local_directory / name
if not path.is_file():
raise ProofValidationError(
f"local canonical reproducible artifact is missing: {name}"
)
if (
not isinstance(item.get("size"), int)
or item["size"] < 0
or not is_sha256(item.get("sha256"))
or item["size"] != path.stat().st_size
or item["sha256"] != sha256(path)
):
raise ProofValidationError(
f"local canonical reproducible artifact binding differs: {name}"
)
external_map = {
name: (item.get("size"), item.get("sha256"))
for name, item in entries.items()
}
local_map = {
name: (item.get("size"), item.get("sha256"))
for name, item in local_entries.items()
}
if external_map != local_map:
differing = sorted(
name
for name in manifest_names
if external_map.get(name) != local_map.get(name)
)
raise ProofValidationError(
"external reproducible artifacts differ from the local canonical release: "
+ ", ".join(differing)
)
if sha256(local_directory / "manifest.json") != sha256(manifest_path):
raise ProofValidationError(
"external reproducible manifest differs from the local canonical release"
)
def arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--proof", required=True, type=Path)
parser.add_argument("--gate", required=True)
parser.add_argument("--source-commit", required=True)
parser.add_argument("--source-tree", required=True)
parser.add_argument("--upstream-commit", required=True)
parser.add_argument("--proof-directory", required=True, type=Path)
parser.add_argument("--expected-daemon-sha256")
parser.add_argument("--expected-client-sha256")
parser.add_argument("--expected-nss-sha256")
parser.add_argument("--local-reproducible-directory", type=Path)
return parser.parse_args()
def main() -> int:
options = arguments()
proof = options.proof.resolve()
proof_directory = options.proof_directory.resolve()
payload = load_json(proof)
if payload.get("schema") != 1:
raise ProofValidationError("unsupported proof schema")
if payload.get("gate") != options.gate:
raise ProofValidationError("proof gate mismatch")
if payload.get("result") != "pass":
raise ProofValidationError("proof did not pass")
source_commit = payload.get("source_commit")
if not is_git_oid(source_commit):
raise ProofValidationError("proof source commit is invalid")
if not is_git_oid(options.source_commit):
raise ProofValidationError("expected source commit is invalid")
if source_commit != options.source_commit:
raise ProofValidationError("proof source commit is stale")
if not is_git_oid(options.source_tree):
raise ProofValidationError("expected source tree is invalid")
if not is_git_oid(options.upstream_commit):
raise ProofValidationError("expected upstream commit is invalid")
if payload.get("source_tree") != options.source_tree:
raise ProofValidationError("proof source tree is stale")
if payload.get("upstream_commit") != options.upstream_commit:
raise ProofValidationError("proof upstream baseline is stale")
located = verify_artifacts(proof, proof_directory, options.gate, payload)
if options.gate == "upstream-test-75":
validate_upstream(
payload,
located,
options.upstream_commit,
options.source_tree,
"TEST-75-RESOLVED",
"TEST-75-RESOLVED.log",
"RUSTD_RESOLVED_TEST_75_",
options.expected_daemon_sha256,
options.expected_client_sha256,
options.expected_nss_sha256,
)
elif options.gate == "upstream-test-89-mdns":
validate_upstream(
payload,
located,
options.upstream_commit,
options.source_tree,
"TEST-89-RESOLVED-MDNS",
"TEST-89-RESOLVED-MDNS.log",
"RUSTD_RESOLVED_TEST_89_RESOLVED_MDNS_",
options.expected_daemon_sha256,
options.expected_client_sha256,
None,
)
elif options.gate == "security-suite":
validate_security(payload, located, source_commit)
elif options.gate == "boot-replacement":
validate_boot(
payload,
located,
source_commit,
options.source_tree,
options.upstream_commit,
options.expected_daemon_sha256,
options.expected_client_sha256,
options.expected_nss_sha256,
)
elif options.gate == "reproducible-release":
validate_reproducible(
payload,
located,
source_commit,
options.source_tree,
options.upstream_commit,
options.expected_daemon_sha256,
options.expected_client_sha256,
options.expected_nss_sha256,
options.local_reproducible_directory,
)
else:
raise ProofValidationError(f"unknown proof gate: {options.gate}")
for name, path in sorted(located.items()):
print(f"verified {name}: {path}")
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except (OSError, ProofValidationError) as error:
print(f"validate-replacement-proof: {error}", file=sys.stderr)
raise SystemExit(1) from error