mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust: Add library for pv tools
Add a `pv` crate that bundles useful functions and structs for creating requests like `Attestation`, `Add Secret`, or even `Boot` a.k.a. Secure Execution Image. Note pv includes a subcrate `openssl_extensions` that (temporarily) bundles some needed `openssl-rust` functionalities that are not upstream yet. The plan is to remove these, when they become upstream. The pv crate has multiple features: * request - code to generate requests * uvsecret - code to access the UV-secret api with request enabled also generating requests is possible Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Acked-by: Jan Höppner <hoeppner@linux.ibm.com> Acked-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
e6add997eb
commit
c6f621d0dc
@@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Copyright IBM Corp. 2023
|
||||
|
||||
// DO NOT USE ANY OF THESE ITEMS IN PRODUCTION CODE
|
||||
// USED FOR INTERNAL UNIT AND FVT TESTING ONLY!!!
|
||||
use openssl::{
|
||||
bn::BigNum,
|
||||
ec::{EcGroup, EcKey},
|
||||
error::ErrorStack,
|
||||
nid::Nid,
|
||||
pkey::{PKey, Private, Public},
|
||||
x509::{X509Crl, X509},
|
||||
};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
/// TEST ONLY! Loads the specified asset into the binary at compile time.
|
||||
///
|
||||
/// For testing-assets only!
|
||||
/// The asset must be present at `{crate}/test/assets/{file}`
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! get_test_asset {
|
||||
($file:expr) => {
|
||||
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/assets/", $file))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_cert_asset_path<P: AsRef<Path>>(path: P) -> PathBuf {
|
||||
let mut p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
p.push("tests");
|
||||
p.push("assets");
|
||||
p.push("cert");
|
||||
p.push(path);
|
||||
println!("CERT path: {}", p.to_str().unwrap());
|
||||
p
|
||||
}
|
||||
|
||||
pub fn get_cert_asset_path_string(path: &'static str) -> String {
|
||||
get_cert_asset_path(path)
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap()
|
||||
}
|
||||
/// TEST ONLY! Load an cert
|
||||
///
|
||||
/// panic on errors
|
||||
pub fn get_cert_asset(path: &'static str) -> Vec<u8> {
|
||||
let p = get_cert_asset_path(path);
|
||||
fs::read(p).unwrap()
|
||||
}
|
||||
|
||||
/// TEST ONLY! Load cert found in the asset path
|
||||
///
|
||||
/// panic on errors
|
||||
pub fn load_gen_cert(asset_path: &'static str) -> X509 {
|
||||
let buf = get_cert_asset(asset_path);
|
||||
let mut cert = X509::from_der(&buf)
|
||||
.map(|crt| vec![crt])
|
||||
.or_else(|_| X509::stack_from_pem(&buf))
|
||||
.unwrap();
|
||||
assert_eq!(cert.len(), 1);
|
||||
cert.pop().unwrap()
|
||||
}
|
||||
|
||||
/// TEST ONLY! Load the crl found in the asset path
|
||||
///
|
||||
/// panic on errors
|
||||
pub fn load_gen_crl(asset_path: &'static str) -> X509Crl {
|
||||
let buf = get_cert_asset(asset_path);
|
||||
|
||||
X509Crl::from_der(&buf)
|
||||
.or_else(|_| X509Crl::from_pem(&buf))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// TEST ONLY! Get a fixed private/public pair and a fixed public key
|
||||
///
|
||||
/// Intened for TESTING only. All parts of the key including the private key are checked in git and
|
||||
/// visible for the public
|
||||
pub fn get_test_keys() -> (PKey<Private>, PKey<Public>) {
|
||||
let pub_key = get_test_asset!("keys/public_cust.bin");
|
||||
let priv_key = get_test_asset!("keys/private_cust.bin");
|
||||
let host_key = get_test_asset!("keys/host.pem.crt");
|
||||
|
||||
assert_eq!(pub_key.len(), 160);
|
||||
assert_eq!(priv_key.len(), 80);
|
||||
|
||||
let cust_key = get_keypair(pub_key, priv_key).unwrap();
|
||||
let host_key = X509::from_pem(host_key).unwrap().public_key().unwrap();
|
||||
|
||||
(cust_key, host_key)
|
||||
}
|
||||
|
||||
fn read_ecdh_pubkey(coords: &[u8]) -> Result<PKey<Public>, ErrorStack> {
|
||||
assert!(coords.len() == 160);
|
||||
let x = BigNum::from_slice(&coords[..80])?;
|
||||
let y = BigNum::from_slice(&coords[80..])?;
|
||||
let group = EcGroup::from_curve_name(Nid::SECP521R1)?;
|
||||
|
||||
let key = EcKey::from_public_key_affine_coordinates(&group, &x, &y)?;
|
||||
PKey::from_ec_key(key)
|
||||
}
|
||||
|
||||
fn get_keypair(pub_coords: &[u8], priv_num: &[u8]) -> Result<PKey<Private>, ErrorStack> {
|
||||
assert!(pub_coords.len() == 160);
|
||||
assert!(priv_num.len() == 80);
|
||||
let pub_key = read_ecdh_pubkey(pub_coords)?;
|
||||
let pub_key = pub_key.ec_key()?;
|
||||
let pub_key = pub_key.public_key();
|
||||
let priv_key = BigNum::from_slice(priv_num)?;
|
||||
let group = EcGroup::from_curve_name(Nid::SECP521R1)?;
|
||||
|
||||
let key = EcKey::from_private_components(&group, &priv_key, pub_key)?;
|
||||
key.check_key()?;
|
||||
PKey::from_ec_key(key)
|
||||
}
|
||||
Reference in New Issue
Block a user