Something went wrong. Try again.
Flatpak-style launcher for sandboxed WebAssembly tools. Install, verify, and run .wasm binaries with explicit capability grants. Single binary, local-first, zero telemetry. wasmbox.orbiter.website
wasm rust wasmbox
Something went wrong. Try again.
2.5 kB · 85 lines
Rust
at dev
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586//! Hash verification for WasmBox tool binaries.
use sha2::{Digest, Sha256};use subtle::ConstantTimeEq;use thiserror::Error;
#[derive(Debug, Error)]pub enum VerifyError { #[error("hash mismatch: expected {expected}, got {actual}")] HashMismatch { expected: String, actual: String },
#[error("invalid hash format: {0}")] InvalidFormat(String),
#[error("io error: {0}")] Io(#[from] std::io::Error),}
/// Compute the SHA-256 hash of bytes, returning a `sha256:hex` string.pub fn hash_bytes(data: &[u8]) -> String { let mut hasher = Sha256::new(); hasher.update(data); let result = hasher.finalize(); format!("sha256:{}", hex::encode(result))}
/// Compute the SHA-256 hash of a file.pub fn hash_file(path: &std::path::Path) -> Result<String, VerifyError> { let data = std::fs::read(path)?; Ok(hash_bytes(&data))}
/// Verify that a binary's hash matches the expected hash (constant-time comparison).pub fn verify_hash(data: &[u8], expected: &str) -> Result<(), VerifyError> { let expected_hex = expected .strip_prefix("sha256:") .ok_or_else(|| VerifyError::InvalidFormat("hash must start with 'sha256:'".into()))?;
let expected_bytes = hex::decode(expected_hex).map_err(|e| VerifyError::InvalidFormat(e.to_string()))?;
let mut hasher = Sha256::new(); hasher.update(data); let actual = hasher.finalize();
if actual.as_slice().ct_eq(&expected_bytes).into() { Ok(()) } else { Err(VerifyError::HashMismatch { expected: expected.to_string(), actual: format!("sha256:{}", hex::encode(actual)), }) }}
/// Verify that a file's hash matches the expected hash.pub fn verify_file(path: &std::path::Path, expected: &str) -> Result<(), VerifyError> { let data = std::fs::read(path)?; verify_hash(&data, expected)}
#[cfg(test)]mod tests { use super::*;
#[test] fn hash_and_verify_roundtrip() { let data = b"hello wasmbox"; let hash = hash_bytes(data); assert!(hash.starts_with("sha256:")); verify_hash(data, &hash).unwrap(); }
#[test] fn verify_mismatch() { let data = b"hello wasmbox"; let bad_hash = "sha256:0000000000000000000000000000000000000000000000000000000000000000"; assert!(verify_hash(data, bad_hash).is_err()); }
#[test] fn verify_invalid_format() { assert!(verify_hash(b"data", "md5:abc").is_err()); }}