git.delta.rocks / fleet / refs/heads / push-kyumtlkprzyo

difftreelog

source

crates/fleet-usb/src/manifest.rs1.9 KiBsourcehistory
1use std::io::{Read as _, Write as _};23use age::{Identity, Recipient};4use anyhow::{Context as _, Result, anyhow, bail};5use camino::Utf8PathBuf;6use serde::{Deserialize, Serialize};78use crate::MANIFEST_VERSION;910#[derive(Serialize, Deserialize, Debug, Clone)]11#[serde(rename_all = "camelCase")]12pub struct Manifest {13	pub version: u32,14	pub host: String,15	pub toplevel: Utf8PathBuf,16	pub paths: Vec<PathEntry>,17}1819#[derive(Serialize, Deserialize, Debug, Clone)]20#[serde(rename_all = "camelCase")]21pub struct PathEntry {22	pub store_path: Utf8PathBuf,23	pub nar_hash: String,24	pub nar_size: u64,25	pub references: Vec<Utf8PathBuf>,26	pub sigs: Vec<String>,27	pub compression: String,28	pub key: String,29	pub chunks: Vec<String>,30}3132pub fn encrypt_manifest<'r>(33	manifest: &Manifest,34	recipients: impl Iterator<Item = &'r dyn Recipient>,35) -> Result<Vec<u8>> {36	let json = serde_json::to_vec(manifest)?;37	let mut out = Vec::new();38	let mut encryptor = age::Encryptor::with_recipients(recipients)39		.map_err(|e| anyhow!("no recipients: {e}"))?40		.wrap_output(&mut out)41		.context("age encrypt")?;42	encryptor.write_all(&json)?;43	encryptor.finish()?;44	Ok(out)45}4647/// Ok(None) means the manifest is valid but encrypted for a different host.48pub fn decrypt_manifest(data: &[u8], identity: &dyn Identity) -> Result<Option<Manifest>> {49	let decryptor = age::Decryptor::new(data).context("age decrypt")?;50	let mut reader = match decryptor.decrypt(std::iter::once(identity)) {51		Ok(reader) => reader,52		Err(age::DecryptError::NoMatchingKeys) => return Ok(None),53		Err(e) => return Err(e).context("decrypting manifest"),54	};55	let mut json = Vec::new();56	reader.read_to_end(&mut json)?;57	let manifest: Manifest = serde_json::from_slice(&json).context("manifest json")?;58	if manifest.version != MANIFEST_VERSION {59		bail!(60			"unsupported manifest version {}, this fleet-usbd supports {MANIFEST_VERSION}",61			manifest.version62		);63	}64	Ok(Some(manifest))65}