129 lines
5.9 KiB
Python
129 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
"""Offline synthetic-transcript tests for Phase-1.0T sanitization."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
|
|
def load(path: Path):
|
|
spec = importlib.util.spec_from_file_location("phase10t_transcript", path)
|
|
assert spec and spec.loader
|
|
module = importlib.util.module_from_spec(spec)
|
|
sys.modules[spec.name] = module
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def require(value: bool, message: str) -> None:
|
|
if not value:
|
|
raise RuntimeError(message)
|
|
|
|
|
|
def greeting(extra: str = "") -> str:
|
|
return (
|
|
"Welcome to shsrv.elf running on pid 123, compiled Jul 22 2026 at 12:34:56\n"
|
|
"Model: synthetic-model\n"
|
|
"S/N: SYNTHETIC-SERIAL-DO-NOT-RETAIN\n"
|
|
"S/W: 9.60\n"
|
|
"SoC temp: 40 C\n"
|
|
"CPU temp: 41 C\n"
|
|
"CPU freq: 3500 MHz\n" + extra)
|
|
|
|
|
|
def help_text(commands: list[str]) -> str:
|
|
return "Builtin commands:\n" + "".join(
|
|
f" {command} - synthetic\n" for command in commands) + "\n"
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--root", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
module = load(args.root.resolve() / "tools/phase10t_shsrv_transcript.py")
|
|
current_commands = "authid browse cat cd chgrp chmod chown chroot cmp cp df echo env exec exit export file find grep hbdbg hbldr hexdump http2_get id kill launch ln ls mkdir mknod mount mv notify pkg_install procstat ps pwd reptyr rm rmdir sfocreate sfoinfo sleep stat sum suspend sync sysctl touch umount".split()
|
|
v07_commands = "browse cat cd chgrp chmod chown chroot cmp cp echo env exec exit export file find grep hbldr help hexdump http2_get id kill launch ln ls mkdir mknod mount mv notify ps pwd rm rmdir sfocreate sfoinfo sleep stat sum sync sysctl touch umount".split()
|
|
cases = []
|
|
|
|
def case(name):
|
|
def register(function):
|
|
cases.append((name, function))
|
|
return function
|
|
return register
|
|
|
|
@case("01 empty transcript is invalid and non-exact")
|
|
def _():
|
|
result = module.parse_transcript("")
|
|
require(result["classification"] == "INVALID_OR_INCOMPLETE" and result["exact_identity"] is False, "empty input accepted")
|
|
|
|
@case("02 greeting is compile metadata only")
|
|
def _(): require(module.parse_transcript(greeting())["classification"] == "COMPILE_METADATA_ONLY", "greeting promoted")
|
|
|
|
@case("03 serial value is discarded")
|
|
def _():
|
|
result = module.parse_transcript(greeting())
|
|
require(result["sensitive_input"]["serial_line_seen"] is True and "SYNTHETIC-SERIAL" not in json.dumps(result), "serial retained")
|
|
|
|
@case("04 telemetry values are discarded")
|
|
def _():
|
|
result = module.parse_transcript(greeting())
|
|
require(result["sensitive_input"]["telemetry_line_seen"] is True and "3500" not in json.dumps(result), "telemetry retained")
|
|
|
|
@case("05 firmware metadata is retained")
|
|
def _(): require(module.parse_transcript(greeting())["compile_metadata"]["firmware"] == "9.60", "firmware lost")
|
|
|
|
@case("06 v0.19 help matches only a source family")
|
|
def _():
|
|
result = module.parse_transcript(greeting(help_text(current_commands)))
|
|
require(result["command_fingerprint"]["sha256"] == module.CURRENT_COMMAND_HASH and result["command_fingerprint"]["source_family_match"] == "OFFICIAL_V019_SOURCE_FAMILY_CANDIDATE" and result["command_fingerprint"]["proves_exact_binary"] is False, "v0.19 fingerprint mismatch")
|
|
|
|
@case("07 v0.7 help matches only a source family")
|
|
def _():
|
|
result = module.parse_transcript(greeting(help_text(v07_commands)))
|
|
require(result["command_fingerprint"]["sha256"] == module.V07_COMMAND_HASH and result["command_fingerprint"]["source_family_match"] == "OFFICIAL_V07_SOURCE_FAMILY_CANDIDATE", "v0.7 fingerprint mismatch")
|
|
|
|
@case("08 altered help stays unresolved")
|
|
def _(): require(module.parse_transcript(greeting(help_text(["help", "unknown"])))["command_fingerprint"]["source_family_match"] == "UNRESOLVED", "unknown family promoted")
|
|
|
|
@case("09 unknown stat path is discarded")
|
|
def _(): require(module.parse_transcript(greeting("filename: /unknown\nsize: 123\n"), {"/approved"})["file_observations"] == [], "unknown path retained")
|
|
|
|
@case("10 approved stat path is retained")
|
|
def _():
|
|
result = module.parse_transcript(greeting("filename: /approved\nsize: 123\nmtime: 456\n"), {"/approved"})
|
|
require(result["file_observations"] == [{"path": "/approved", "metadata_seen": True, "size": 123, "mtime": 456, "proves_exact_binary": False}], "approved metadata mismatch")
|
|
|
|
@case("11 sum is labeled weak and non-cryptographic")
|
|
def _():
|
|
result = module.parse_transcript(greeting("12345 /approved\n"), {"/approved"})
|
|
observation = result["file_observations"][0]
|
|
require(observation["weak_checksum_algorithm"] == "BSD_ROTATE_16" and observation["cryptographic_checksum"] is False, "weak sum promoted")
|
|
|
|
@case("12 all combined metadata remains non-exact")
|
|
def _():
|
|
text = greeting(help_text(current_commands) + "filename: /approved\nsize: 123\n12345 /approved\n")
|
|
result = module.parse_transcript(text, {"/approved"})
|
|
require(result["exact_identity"] is False and all(not item["proves_exact_binary"] for item in result["file_observations"]), "combined metadata promoted")
|
|
|
|
failures = []
|
|
for name, function in cases:
|
|
try:
|
|
function()
|
|
print(f"PASS {name}")
|
|
except Exception as error: # noqa: BLE001 - test harness
|
|
failures.append(f"{name}: {error}")
|
|
print(f"FAIL {name}: {error}")
|
|
if failures:
|
|
return 1
|
|
print(f"Phase-1.0T transcript tests passed: {len(cases)}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|