use shared libs, enabling openssl in init

This commit is contained in:
Mikaël Cluseau
2025-07-21 03:25:48 +02:00
parent e484802284
commit 0d9d087afd
5 changed files with 551 additions and 89 deletions

View File

@ -1,8 +1,8 @@
use eyre::{Result, format_err};
use eyre::{format_err, Result};
use log::{info, warn};
use tokio::{
fs,
io::{AsyncBufReadExt, BufReader},
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
};
use dkl::{
@ -77,42 +77,36 @@ impl Verifier {
return Ok(Self { pubkey: None });
};
use base64::{Engine, prelude::BASE64_STANDARD};
use base64::{prelude::BASE64_STANDARD, Engine};
let pubkey = BASE64_STANDARD.decode(pubkey)?;
let pubkey = Some(pubkey);
return Ok(Self { pubkey });
}
async fn verify_path(&self, path: &str) -> Result<()> {
async fn verify_path(&self, path: &str) -> Result<Vec<u8>> {
let data = (fs::read(path).await).map_err(|e| format_err!("failed to read {path}: {e}"))?;
let Some(ref pubkey) = self.pubkey else {
return Ok(());
return Ok(data);
};
info!("verifying {path}");
let mut pubkey = std::io::Cursor::new(pubkey);
let sig = &format!("{path}.sig");
let sig = (fs::read(sig).await).map_err(|e| format_err!("failed to read {sig}: {e}"))?;
let sig = format!("{path}.sig");
use openssl::{hash::MessageDigest, pkey::PKey, sign::Verifier};
let pubkey = PKey::public_key_from_der(pubkey)?;
use std::process::Stdio;
use tokio::process::Command;
let sig_ok = Verifier::new(MessageDigest::sha512(), &pubkey)?
.verify_oneshot(&sig, &data)
.map_err(|e| format_err!("verify failed: {e}"))?;
let mut openssl = Command::new("openssl")
.stdin(Stdio::piped())
.args(&["dgst", "-sha512", "-verify", "/dev/stdin"])
.args(&["-signature", &sig, path])
.spawn()?;
tokio::io::copy(&mut pubkey, openssl.stdin.as_mut().unwrap()).await?;
let status = openssl.wait().await?;
if status.success() {
Ok(())
if sig_ok {
Ok(data)
} else {
Err(format_err!(
"signature verification failed for {path}: {status}"
))
Err(format_err!("signature verification failed for {path}"))
}
}
}
@ -145,9 +139,7 @@ async fn seed_config(
return Err(format_err!("{cfg_path} does not exist after seeding"));
}
verifier.verify_path(&cfg_path).await?;
Ok(fs::read(cfg_path).await?)
verifier.verify_path(&cfg_path).await
}
async fn fetch_bootstrap(seed_url: &str, output_file: &str) -> Result<()> {
@ -186,19 +178,24 @@ async fn mount_system(cfg: &dkl::Config, bs_dir: &str, verifier: &Verifier) {
let mut lower_dir = String::new();
for layer in &cfg.layers {
let src = if layer == "modules" {
"/modules.sqfs".to_string()
} else {
let p = format!("{bs_dir}/{layer}.fs");
retry(async || verifier.verify_path(&p).await).await;
p
};
let src = retry(async || {
if layer == "modules" {
(fs::read("/modules.sqfs").await)
.map_err(|e| format_err!("read /modules.sqfs failed: {e}"))
} else {
verifier.verify_path(&format!("{bs_dir}/{layer}.fs")).await
}
})
.await;
let tgt = &format!("{mem_dir}/{layer}.fs");
retry(async || {
info!("copying layer {layer} from {src}");
fs::copy(&src, tgt).await?;
Ok(())
info!("copying layer {layer}");
let mut out = (fs::File::create(tgt).await)
.map_err(|e| format_err!("create {tgt} failed: {e}"))?;
(out.write_all(&src).await).map_err(|e| format_err!("write failed: {e}"))?;
(out.flush().await).map_err(|e| format_err!("write failed: {e}"))
})
.await;