#!/usr/bin/env python3 """Check a LogIQ report package. python3 verify_report_package.py logiq-report-42-2026-08-08.tar.gz Exit code 0 means both questions were answered yes: the manifest carries a valid signature from LogistiXpert, and every file in the archive still has the hash the manifest records for it. Any other exit code means do not rely on the report. The script is deliberately standalone — one file, one dependency (`cryptography`), no part of the Analyzer needed — because whoever checks a report is usually not the person who produced it and should not have to install the tool that made it. pip install cryptography The public key is built in and is the one published at https://logistixpert.com/verify. Compare them if you have any reason to. Another key can be given with --key for an installation that signs with its own. """ from __future__ import annotations import argparse import base64 import hashlib import json import sys import tarfile from pathlib import Path try: from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey except ImportError: # pragma: no cover sys.exit("This needs the `cryptography` package: pip install cryptography") LOGISTIXPERT_PUBLIC_KEY = "uv/SV8Y1MOin3jKMIe3BKMTVsfP8I4S+P1OcqSPeiLs=" GREEN, RED, YELLOW, OFF = "\033[32m", "\033[31m", "\033[33m", "\033[0m" def is_reader_noise(path: str) -> bool: """macOS `tar` writes an AppleDouble `._name` beside every entry when it re-packs a directory. Those are the reader's own tools talking, and listing them buries the line that matters.""" name = path.rsplit("/", 1)[-1] return name.startswith("._") or name == ".DS_Store" def sha256(data: bytes) -> str: return hashlib.sha256(data).hexdigest() def load(archive: Path) -> dict[str, bytes]: with tarfile.open(archive, "r:gz") as tar: out = {} for member in tar.getmembers(): if not member.isfile(): continue parts = Path(member.name).parts handle = tar.extractfile(member) if handle is not None: out["/".join(parts[1:]) if len(parts) > 1 else member.name] = handle.read() return out def check(archive: Path, key_b64: str) -> int: try: blobs = load(archive) except (OSError, tarfile.TarError) as exc: print(f"{RED}✗{OFF} {archive.name} is not a readable archive: {exc}") return 2 raw = blobs.get("MANIFEST.json") if raw is None: print(f"{RED}✗{OFF} no MANIFEST.json — this is not a LogIQ report package") return 2 manifest = json.loads(raw) print(f"Package {archive.name}") print(f"Report {manifest.get('report_id')} · {manifest.get('source_name')}") print(f"Made {manifest.get('created_at')} by {manifest.get('product')} " f"{manifest.get('tool_version')}") run = manifest.get("run") or {} if run.get("verdict"): print(f"Verdict {run['verdict']} score {run.get('score')}") print() failed = False signature = blobs.get("MANIFEST.json.sig") if signature is None and manifest.get("signed_by"): # Never-signed says so in the manifest; this one had it taken off. print(f"{RED}✗{OFF} SIGNATURE MISSING — the manifest says {manifest['signed_by']} signed " f"this, but there is no MANIFEST.json.sig in the archive") failed = True elif signature is None: print(f"{YELLOW}!{OFF} unsigned — the archive carries no signature, so it says what it " f"contains but not who produced it") else: try: Ed25519PublicKey.from_public_bytes(base64.b64decode(key_b64)).verify(signature, raw) print(f"{GREEN}✓{OFF} signature valid — issued by {manifest.get('signed_by')}") except Exception: # noqa: BLE001 print(f"{RED}✗{OFF} SIGNATURE DOES NOT MATCH — the manifest was altered, or it was " f"not signed with the key you checked against") failed = True listed = {f["path"]: f for f in manifest.get("files", [])} bad = [] for path, entry in sorted(listed.items()): data = blobs.get(path) if data is None: bad.append(f"missing: {path}") elif sha256(data) != entry.get("sha256"): bad.append(f"altered: {path}") known = {"MANIFEST.json", "MANIFEST.json.sig", "SHA256SUMS", "README.txt"} for extra in sorted({p for p in blobs if not is_reader_noise(p)} - set(listed) - known): bad.append(f"unlisted: {extra}") sums = blobs.get("SHA256SUMS") if sums is not None and manifest.get("sha256sums_sha256") not in (None, sha256(sums)): bad.append("altered: SHA256SUMS") if bad: print(f"{RED}✗{OFF} {len(bad)} problem(s) with the contents:") for line in bad: print(f" {line}") failed = True else: print(f"{GREEN}✓{OFF} {len(listed)} files, every hash matches the manifest") print() if failed: print(f"{RED}Do not rely on this report.{OFF}") return 1 if signature is None: print(f"{YELLOW}The contents are intact. The origin is not established.{OFF}") return 3 print(f"{GREEN}The package is authentic and complete.{OFF}") return 0 def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("archive", type=Path, help="the .tar.gz to check") parser.add_argument("--key", default=LOGISTIXPERT_PUBLIC_KEY, metavar="BASE64", help="public key to check against (default: the LogistiXpert key)") args = parser.parse_args(argv) if not args.archive.exists(): return print(f"No such file: {args.archive}") or 2 return check(args.archive, args.key) if __name__ == "__main__": sys.exit(main())