git.delta.rocks / fleet / refs/commits / 615754ca0747

difftreelog

source

crates/fleet-usb/src/manifest.rs1.7 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}4647pub fn decrypt_manifest(data: &[u8], identity: &dyn Identity) -> Result<Manifest> {48	let decryptor = age::Decryptor::new(data).context("age decrypt")?;49	let mut reader = decryptor50		.decrypt(std::iter::once(identity))51		.context("manifest is not encrypted for this identity")?;52	let mut json = Vec::new();53	reader.read_to_end(&mut json)?;54	let manifest: Manifest = serde_json::from_slice(&json).context("manifest json")?;55	if manifest.version != MANIFEST_VERSION {56		bail!(57			"unsupported manifest version {}, this fleet-usbd supports {MANIFEST_VERSION}",58			manifest.version59		);60	}61	Ok(manifest)62}