rust/pvsecret: Add support for retrievable secrets

Support for creating and retrieving retrievable secrets.

Acked-by: Marc Hartmayer <marc@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Steffen Eiden
2024-02-19 15:15:16 +01:00
committed by Jan Höppner
parent a14f9d4edc
commit 93da795520
6 changed files with 230 additions and 10 deletions
+28 -2
View File
@@ -4,7 +4,6 @@
use std::path::Path;
use crate::cli::{AddSecretType, CreateSecretFlags, CreateSecretOpt};
use anyhow::{anyhow, bail, Context, Error, Result};
use log::{debug, info, trace, warn};
use pv::{
@@ -22,6 +21,8 @@ use pv::{
use serde_yaml::Value;
use utils::get_writer_from_cli_file_arg;
use crate::cli::{AddSecretType, CreateSecretFlags, CreateSecretOpt, RetrieveableSecretInpKind};
fn write_out<P, D>(path: &P, data: D, ctx: &str) -> pv::Result<()>
where
P: AsRef<Path>,
@@ -32,6 +33,23 @@ where
Ok(())
}
fn retrievable(name: &str, secret: &str, kind: &RetrieveableSecretInpKind) -> Result<GuestSecret> {
let secret_data = read_file(secret, &format!("retrievable {kind}"))?.into();
match kind {
RetrieveableSecretInpKind::Plain => GuestSecret::plaintext(name, secret_data),
RetrieveableSecretInpKind::Aes => GuestSecret::aes(name, secret_data),
RetrieveableSecretInpKind::AesXts => GuestSecret::aes_xts(name, secret_data),
RetrieveableSecretInpKind::HmacSha => GuestSecret::hmac_sha(name, secret_data),
RetrieveableSecretInpKind::Ec => GuestSecret::ec(
name,
read_private_key(secret_data.value())
.with_context(|| format!("Cannot read {secret} as {kind} from PEM or DER"))?,
),
}
.map_err(Error::from)
}
/// Prepare an add-secret request
pub fn create(opt: &CreateSecretOpt) -> Result<()> {
if pv_guest_bit_set() {
@@ -88,6 +106,9 @@ fn build_asrcb(opt: &CreateSecretOpt) -> Result<AddSecretRequest> {
input_secret: None,
..
} => GuestSecret::association(name, None)?,
AddSecretType::Retrievable {
name, secret, kind, ..
} => retrievable(name, secret, kind)?,
};
trace!("AddSecret: {secret:x?}");
@@ -136,7 +157,9 @@ fn build_asrcb(opt: &CreateSecretOpt) -> Result<AddSecretRequest> {
.as_ref()
.map(|p| read_file(p, "User-signing key"))
.transpose()?
.map(|buf| read_private_key(&buf))
.map(|buf| {
read_private_key(&buf).context("Cannot read {secret} as private key from PEM or DER")
})
.transpose()?;
if user_data.is_some() || user_key.is_some() {
@@ -258,6 +281,9 @@ fn write_secret<P: AsRef<Path>>(
write_out(path, guest_secret.confidential(), "Association secret")?
}
}
AddSecretType::Retrievable { name, stdout, .. } => {
write_yaml(name, guest_secret, stdout, outp_path)?
}
_ => (),
};
Ok(())