Files
s390-tools/rust/pvimg/src/cmd/test.rs
Marc Hartmayer f8fb9ce32a rust: Run rustfmt with some experimental options
+ Sort and group the imports
+ Normalize and format comments (100 characters width)

Command used:

$ cargo +nightly fmt --

Acked-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Marc Hartmayer <marc@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2026-06-22 16:43:02 +02:00

120 lines
3.6 KiB
Rust

// SPDX-License-Identifier: MIT
//
// Copyright IBM Corp. 2024
use std::path::Path;
use anyhow::Result;
use log::{info, warn};
use pv::misc::{open_file, read_certs, read_file};
use pv::{FileAccessErrorType, PvCoreError};
use pvimg::error::{Error, OwnExitCode, PvError};
use pvimg::uvdata::{KeyExchangeTrait, SeHdr, UvKeyHashesV1};
use utils::HexSlice;
use crate::cli::TestArgs;
use crate::log_println;
/// Returns `Ok(true)` if at least one of the hashes is included.
fn hdr_test_target_hashes(hdr: &SeHdr, key_hashes: &Path) -> Result<bool> {
let file = open_file(key_hashes).map_err(|err| match err {
PvCoreError::FileAccess {
ref ty,
ref path,
ref source,
} if matches!(ty, FileAccessErrorType::Open)
&& source.kind() == std::io::ErrorKind::NotFound
&& path == Path::new(UvKeyHashesV1::SYS_UV_KEYS_ALL) =>
{
Error::UnavailableQueryUvKeyHashesSupport { source: err }
}
err => Error::PvCore(err),
})?;
let hashes = UvKeyHashesV1::read_from_io(file)?;
let mut contains = hdr.contains_hash(&hashes.pchkh);
if contains {
log_println!(
" ✓ Host key hash {:#} is included",
HexSlice::from(&hashes.pchkh)
);
}
if hdr.contains_hash(&hashes.pbhkh) {
log_println!(
" ✓ Backup host key hash {:#} is included",
HexSlice::from(&hashes.pbhkh)
);
contains = true;
};
for hash in hashes.res {
if hdr.contains_hash(&hash) {
log_println!(" ✓ Key hash {:#} is included", HexSlice::from(&hash));
contains = true;
}
}
if !contains {
warn!(" ✘ None of the key hashes is included");
}
Ok(contains)
}
/// Returns `Ok(true)` if at least one of the given public key of the host key
/// documents was used for the image creation or if no host key document was
/// specified.
fn hdr_test_hkd<P>(hdr: &SeHdr, host_key_documents: &[P]) -> Result<bool>
where
P: AsRef<Path>,
{
if host_key_documents.is_empty() {
return Ok(true);
}
let mut result = false;
for path in host_key_documents {
let hkd_path = path.as_ref();
let hkd_data = read_file(hkd_path, "host key document")?;
let certs = read_certs(&hkd_data)?;
if certs.is_empty() {
return Err(PvError::NoHkdInFile(hkd_path.display().to_string()).into());
}
if certs.len() != 1 {
warn!("The host key document in '{}' contains more than one certificate! Only the first certificate will be used.",
hkd_path.display());
}
// Panic: len is == 1 -> unwrap will succeed/not panic
let cert = certs.first().unwrap();
if hdr.contains(cert.public_key()?)? {
result = true;
log_println!(" ✓ Host key document '{}' is included", hkd_path.display());
} else {
log_println!(
" ✘ Host key document '{}' is not included",
hkd_path.display()
);
}
}
Ok(result)
}
pub fn test(opt: &TestArgs) -> Result<OwnExitCode> {
info!("Testing a Secure Execution image");
let mut input = open_file(&opt.input.path)?;
SeHdr::seek_sehdr(&mut input, None)?;
let hdr = SeHdr::try_from_io(input)?;
let mut success = hdr_test_hkd(&hdr, &opt.host_key_documents)?;
if let Some(path) = &opt.key_hashes {
success = hdr_test_target_hashes(&hdr, path)? && success;
}
Ok(if success {
OwnExitCode::Success
} else {
OwnExitCode::GenericError
})
}