use base64::{engine::general_purpose::STANDARD, Engine as _}; use minisign_verify::{PublicKey, Signature}; use serde_json::Value; use std::{env, fs, path::Path}; fn decode_outer_base64(value: &str, label: &str) -> Result { let bytes = STANDARD .decode(value.trim()) .map_err(|error| format!("{label}_BASE64_INVALID: {error}"))?; String::from_utf8(bytes).map_err(|error| format!("{label}_UTF8_INVALID: {error}")) } fn main() -> Result<(), String> { let arguments: Vec = env::args().collect(); let [_, trust_path, updater_path, signature_path] = arguments.as_slice() else { return Err( "USAGE: verify_updater_signature " .to_string(), ); }; let trust: Value = serde_json::from_str( &fs::read_to_string(trust_path) .map_err(|error| format!("RELEASE_TRUST_READ_FAILED: {error}"))?, ) .map_err(|error| format!("RELEASE_TRUST_JSON_INVALID: {error}"))?; let encoded_public_key = trust .get("publicKey") .and_then(Value::as_str) .ok_or_else(|| "RELEASE_TRUST_PUBLIC_KEY_MISSING".to_string())?; let public_key = PublicKey::decode(&decode_outer_base64( encoded_public_key, "RELEASE_TRUST_PUBLIC_KEY", )?) .map_err(|error| format!("RELEASE_TRUST_PUBLIC_KEY_INVALID: {error}"))?; let signature = Signature::decode(&decode_outer_base64( &fs::read_to_string(signature_path) .map_err(|error| format!("UPDATER_SIGNATURE_READ_FAILED: {error}"))?, "UPDATER_SIGNATURE", )?) .map_err(|error| format!("UPDATER_SIGNATURE_INVALID: {error}"))?; let updater = fs::read(Path::new(updater_path)) .map_err(|error| format!("UPDATER_ARTIFACT_READ_FAILED: {error}"))?; public_key .verify(&updater, &signature, true) .map_err(|error| format!("UPDATER_SIGNATURE_VERIFICATION_FAILED: {error}"))?; println!("HOLOLAKE_UPDATER_SIGNATURE_VERIFIED"); Ok(()) }