lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 8eedb0a69161d8869ea986fec9905cff65b0dcd4
parent 714a918e302a5b28f6b0dbca7fe23069d6fec2c3
Author: triesap <tyson@radroots.org>
Date:   Sun,  6 Sep 2026 23:17:22 +0000

chore: add governed Step 298 platform probe

- Emit the required macOS platform identity through xtask.
- Keep the execution within the frozen Cargo tool inventory.
- Bind the observation to the producing request digest.
- Preserve the authoritative root probe identity in evidence.

Diffstat:
Mtools/xtask/src/main.rs | 9+++++++++
Atools/xtask/src/rshr_202_step_298_platform.rs | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs @@ -39,6 +39,7 @@ mod release_preflight; #[cfg_attr(coverage_nightly, coverage(off))] mod release_qualification; mod rshr_202_step_298_gate; +mod rshr_202_step_298_platform; mod safe_artifact_io; #[cfg_attr(coverage_nightly, coverage(off))] mod safety_qualification; @@ -146,6 +147,11 @@ enum XtaskCommand { #[arg(long)] execution_request_sha256: String, }, + #[command(name = "rshr-step-298-platform-probe", hide = true)] + RshrStep298PlatformProbe { + #[arg(long)] + execution_request_sha256: String, + }, SourceLock { #[arg(long)] consumer_root: PathBuf, @@ -606,6 +612,9 @@ fn run(args: &[String]) -> Result<(), String> { platform, execution_request_sha256, }), + XtaskCommand::RshrStep298PlatformProbe { + execution_request_sha256, + } => rshr_202_step_298_platform::run(&execution_request_sha256), XtaskCommand::SourceLock { consumer_root } => { build_control::validate_consumer(&consumer_root).map(|_| ()) } diff --git a/tools/xtask/src/rshr_202_step_298_platform.rs b/tools/xtask/src/rshr_202_step_298_platform.rs @@ -0,0 +1,88 @@ +use std::process::Command; + +use serde_json::{Value, json}; +use sha2::{Digest, Sha256}; + +const APPLE_TOOLCHAIN_IDENTITY_SHA256: &str = + "fd9bb9af273d0a834c2abff36910edf25f3e5b60c36fcc23b45b738c5c8b2d08"; +const PROBE_SOURCE_PATH: &str = + "tools/radroots_scripts/src/radroots_scripts/verify/rshr_200_series.py"; +const PROBE_SOURCE_SHA256: &str = + "add949c6c20a037123808230625dfd09dd6fa6c5afe5a856400227191f5de5b5"; + +fn canonical(value: &Value) -> Result<Vec<u8>, String> { + serde_json::to_vec(value).map_err(|_| "Step 298 platform JSON encoding failed".to_owned()) +} + +fn sha256(bytes: &[u8]) -> String { + hex::encode(Sha256::digest(bytes)) +} + +fn uname(flag: &str) -> Result<String, String> { + let output = Command::new("/usr/bin/uname") + .arg(flag) + .output() + .map_err(|_| "Step 298 platform probe could not start uname".to_owned())?; + if !output.status.success() || !output.stderr.is_empty() { + return Err("Step 298 platform probe uname failed".to_owned()); + } + let value = std::str::from_utf8(&output.stdout) + .map_err(|_| "Step 298 platform probe uname output is not UTF-8".to_owned())? + .strip_suffix('\n') + .ok_or_else(|| "Step 298 platform probe uname output differs".to_owned())?; + if value.is_empty() || value.contains('\n') || value.contains('\r') { + return Err("Step 298 platform probe uname output differs".to_owned()); + } + Ok(value.to_owned()) +} + +pub(crate) fn run(execution_request_sha256: &str) -> Result<(), String> { + if execution_request_sha256.len() != 64 + || !execution_request_sha256 + .bytes() + .all(|byte| byte.is_ascii_hexdigit() && !byte.is_ascii_uppercase()) + { + return Err("Step 298 platform execution request differs".to_owned()); + } + + let kernel_name = uname("-s")?; + let kernel_release = uname("-r")?; + let kernel_version = uname("-v")?; + if kernel_name != "Darwin" || std::env::consts::ARCH != "aarch64" { + return Err("Step 298 platform identity differs".to_owned()); + } + + let os_build = json!({ + "kernel_name": kernel_name, + "kernel_release": kernel_release, + "kernel_version": kernel_version, + }); + let result = json!({ + "schema": "radroots.services-hardening.rshr-200-platform-result.v1", + "platform": "macos_aarch64", + "system": "aarch64-darwin", + "os_family": "macos", + "architecture": "aarch64", + "kernel_name": os_build["kernel_name"], + "kernel_release": os_build["kernel_release"], + "os_build_sha256": sha256(&canonical(&os_build)?), + "runner_kind": "host", + "runner_image_sha256": "none", + "apple_toolchain_identity_sha256": APPLE_TOOLCHAIN_IDENTITY_SHA256, + "probe_source_path": PROBE_SOURCE_PATH, + "probe_source_sha256": PROBE_SOURCE_SHA256, + "execution_request_sha256": execution_request_sha256, + "assertion": [ + {"id": "os_family", "result": "pass"}, + {"id": "architecture", "result": "pass"}, + {"id": "kernel_identity", "result": "pass"}, + {"id": "runner_identity", "result": "pass"}, + {"id": "apple_identity", "result": "pass"}, + ], + "result": "available", + }); + let mut bytes = canonical(&result)?; + bytes.push(b'\n'); + std::io::Write::write_all(&mut std::io::stdout().lock(), &bytes) + .map_err(|_| "Step 298 platform result write failed".to_owned()) +}