lanzaboote/rust/lanzatool/src/install.rs

111 lines
3.0 KiB
Rust
Raw Normal View History

2022-11-23 09:26:26 -05:00
use std::fs;
2022-11-25 07:07:04 -05:00
use std::path::{Path, PathBuf};
2022-11-23 09:26:26 -05:00
2022-11-24 07:33:01 -05:00
use anyhow::{Context, Result};
2022-11-23 09:26:26 -05:00
use crate::bootspec::Bootspec;
use crate::esp::EspPaths;
2022-11-23 14:40:01 -05:00
use crate::pe;
use crate::signer::Signer;
2022-11-23 14:40:01 -05:00
pub fn install(
public_key: &Path,
private_key: &Path,
2022-11-25 07:08:37 -05:00
_pki_bundle: Option<PathBuf>,
2022-11-24 08:12:00 -05:00
_auto_enroll: bool,
2022-11-23 14:40:01 -05:00
bootspec: &Path,
lanzaboote_stub: &Path,
initrd_stub: &Path,
) -> Result<()> {
2022-11-24 07:33:01 -05:00
println!("Reading bootspec...");
let bootspec_doc: Bootspec =
serde_json::from_slice(&fs::read(bootspec).context("Failed to read bootspec file")?)
.context("Failed to parse bootspec json")?;
2022-11-23 09:26:26 -05:00
2022-11-24 06:26:32 -05:00
let esp_paths = EspPaths::new(&bootspec_doc.extension.esp);
2022-11-23 09:26:26 -05:00
2022-11-24 07:33:01 -05:00
println!("Assembling lanzaboote image...");
2022-11-25 07:07:04 -05:00
let kernel_cmdline = assemble_kernel_cmdline(bootspec_doc.init, bootspec_doc.kernel_params);
2022-11-24 07:33:01 -05:00
2022-11-23 14:40:01 -05:00
let lanzaboote_image = pe::assemble_image(
lanzaboote_stub,
2022-11-24 06:26:32 -05:00
&bootspec_doc.extension.os_release,
2022-11-24 10:51:43 -05:00
&kernel_cmdline,
2022-11-23 09:26:26 -05:00
&esp_paths.kernel,
&esp_paths.initrd,
2022-11-24 11:14:55 -05:00
&esp_paths.esp,
2022-11-23 09:26:26 -05:00
)
2022-11-24 07:33:01 -05:00
.context("Failed to assemble stub")?;
2022-11-23 09:26:26 -05:00
2022-11-24 07:33:01 -05:00
println!("Wrapping initrd into a PE binary...");
2022-11-23 14:40:01 -05:00
2022-11-24 07:33:01 -05:00
let wrapped_initrd =
pe::wrap_initrd(initrd_stub, &bootspec_doc.initrd).context("Failed to assemble stub")?;
2022-11-24 07:33:01 -05:00
println!("Copy files to EFI system partition...");
2022-11-23 09:26:26 -05:00
let systemd_boot = bootspec_doc
.extension
.systemd
.join("lib/systemd/boot/efi/systemd-bootx64.efi");
2022-11-24 07:33:01 -05:00
let files_to_copy = [
(bootspec_doc.kernel, &esp_paths.kernel),
(wrapped_initrd, &esp_paths.initrd),
(lanzaboote_image, &esp_paths.lanzaboote_image),
(systemd_boot.clone(), &esp_paths.efi_fallback),
(systemd_boot, &esp_paths.systemd_boot),
2022-11-24 07:33:01 -05:00
];
for (source, target) in files_to_copy {
copy(&source, &target)?;
}
2022-11-25 07:07:04 -05:00
println!("Signing files...");
let signer = Signer::new(&public_key, &private_key);
let files_to_sign = [
&esp_paths.efi_fallback,
&esp_paths.systemd_boot,
&esp_paths.lanzaboote_image,
&esp_paths.kernel,
&esp_paths.initrd,
];
for file in files_to_sign {
signer
.sign_file(&file)
.with_context(|| format!("Failed to sign file {}", &file.display()))?;
}
2022-11-24 07:33:01 -05:00
println!(
"Succesfully installed lanzaboote to '{}'",
esp_paths.esp.display()
);
2022-11-25 07:07:04 -05:00
2022-11-24 07:33:01 -05:00
Ok(())
}
2022-11-23 09:26:26 -05:00
2022-11-25 07:07:04 -05:00
fn assemble_kernel_cmdline(init: PathBuf, kernel_params: Vec<String>) -> Vec<String> {
let init_string = init
.into_os_string()
.into_string()
.expect("Failed to convert init path to string");
let mut kernel_cmdline: Vec<String> = vec![format!("init={}", init_string)];
kernel_cmdline.extend(kernel_params);
kernel_cmdline
}
2022-11-24 07:33:01 -05:00
fn copy(from: &Path, to: &Path) -> Result<()> {
match to.parent() {
Some(parent) => fs::create_dir_all(parent).unwrap_or(()),
_ => (),
};
fs::copy(from, to)
.with_context(|| format!("Failed to copy from {} to {}", from.display(), to.display()))?;
2022-11-23 09:26:26 -05:00
Ok(())
}