mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
pv: Refactor 'get_verified_hkds'
Get rid of 'read_hkd' by refactoring the 'get_verified_hkds' function. For this a new HkdLoader::load_and_verify is introduced that is a reworked version of the original code. In addition, add test cases for testing all the edge cases. Assisted-by: IBM Bob:1.0.6 Signed-off-by: Marc Hartmayer <marc@linux.ibm.com> Reviewed-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
committed by
Steffen Eiden
parent
1aa1558f91
commit
0263637d9f
@@ -10,13 +10,12 @@ use std::str::FromStr;
|
||||
|
||||
use clap::builder::{EnumValueParser, PossibleValue, TypedValueParser};
|
||||
use clap::{Arg, ArgAction, ArgGroup, Args, Command, ValueEnum, ValueHint};
|
||||
use log::{info, warn, LevelFilter};
|
||||
use openssl::Nid;
|
||||
use pv::misc::{create_file, open_file, read_certs, read_file};
|
||||
use pv::request::openssl::pkey::{KeyType, PKeyRef, Public};
|
||||
use pv::request::{openssl, HkdVerifier, HostKey, HybridPKey};
|
||||
use pv::{Error, Result};
|
||||
use utils_macros::{ValueEnumDisplay, ValueEnumFromStr};
|
||||
use log::LevelFilter;
|
||||
use pv::misc::{create_file, open_file};
|
||||
use pv::request::{HkdVerifier, HostKey};
|
||||
use pv::Result;
|
||||
|
||||
use crate::hkd::{HkdLoader, HkdVersionSelection};
|
||||
|
||||
/// Generic version selection for CLI
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@@ -133,17 +132,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Host key document version for CLI
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, ValueEnumDisplay, ValueEnumFromStr)]
|
||||
pub enum HkdVersion {
|
||||
/// Version 1 - uses traditional cryptographic keys
|
||||
Classical,
|
||||
/// Version 2 - uses hybrid (post-quantum) cryptographic keys
|
||||
Hybrid,
|
||||
}
|
||||
|
||||
pub type HkdVersionSelection = AutoOrExplicit<HkdVersion>;
|
||||
|
||||
/// CLI Argument collection for handling host-keys, IBM signing keys, and certificates.
|
||||
#[derive(Args, Debug, Clone, PartialEq, Eq, Default)]
|
||||
#[command(
|
||||
@@ -239,21 +227,6 @@ impl CertificateOptions {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_ec_p521_key(key: &PKeyRef<Public>) -> bool {
|
||||
if key.id() == openssl::pkey::Id::EC {
|
||||
let ec_key = key.ec_key().unwrap();
|
||||
let group = ec_key.group();
|
||||
let curve_nid = group.curve_name().unwrap();
|
||||
curve_nid == Nid::SECP521R1
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_mlkem1024_key(key: &PKeyRef<Public>) -> bool {
|
||||
key.is_a(KeyType::ML_KEM_1024)
|
||||
}
|
||||
|
||||
/// Read the hybrid host-keys specified and verifies them if required
|
||||
///
|
||||
/// - `protectee`: what you want to create. e.g. add-secret request or SE-image
|
||||
@@ -273,67 +246,8 @@ impl CertificateOptions {
|
||||
|
||||
let mut res = Vec::with_capacity(hkds.len());
|
||||
for hkd in hkds {
|
||||
let hk = read_file(hkd, "host-key document")?;
|
||||
let certs = read_certs(&hk).map_err(|source| Error::HkdNotPemOrDer {
|
||||
hkd: hkd.display().to_string(),
|
||||
source,
|
||||
})?;
|
||||
if certs.is_empty() {
|
||||
return Err(Error::NoHkdInFile(hkd.display().to_string()));
|
||||
}
|
||||
let required_cert_count = match requested_version {
|
||||
HkdVersionSelection::Auto => {
|
||||
info!("Auto-detecting version of the host-key document format");
|
||||
match certs.len() {
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
_ => {
|
||||
warn!(
|
||||
"The host-key document in '{}' contains more than two certificates!",
|
||||
hkd.display()
|
||||
);
|
||||
return Err(Error::WrongNumberOfKeys(hkd.display().to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
HkdVersionSelection::Explicit(HkdVersion::Classical) => {
|
||||
info!("Using version 1 of the host-key document format");
|
||||
1
|
||||
}
|
||||
HkdVersionSelection::Explicit(HkdVersion::Hybrid) => {
|
||||
info!("Using version 2 of the host-key document format");
|
||||
2
|
||||
}
|
||||
};
|
||||
if required_cert_count != certs.len() {
|
||||
return Err(Error::WrongNumberOfKeys(hkd.display().to_string()));
|
||||
}
|
||||
let c1 = certs.first().unwrap();
|
||||
if !Self::is_ec_p521_key(c1.public_key()?.as_ref()) {
|
||||
return Err(Error::InvalidHkd(
|
||||
"First key must be a EC-p521 key".to_string(),
|
||||
));
|
||||
}
|
||||
verifier.verify(c1)?;
|
||||
match certs.len() {
|
||||
1 => {
|
||||
res.push(HostKey::V1(c1.public_key()?));
|
||||
}
|
||||
2 => {
|
||||
let c2 = &certs[1];
|
||||
if !Self::is_mlkem1024_key(c2.public_key()?.as_ref()) {
|
||||
return Err(Error::InvalidHkd(
|
||||
"Second key must be a ML-KEM 1024 key".to_string(),
|
||||
));
|
||||
}
|
||||
verifier.verify(c2)?;
|
||||
res.push(HostKey::V2(HybridPKey::new(
|
||||
c1.public_key()?,
|
||||
c2.public_key()?,
|
||||
)?))
|
||||
}
|
||||
_ => unreachable!("Already checked"),
|
||||
}
|
||||
let host_key = HkdLoader::load_and_verify(hkd, verifier.as_ref(), requested_version)?;
|
||||
res.push(host_key);
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user