Files
s390-tools/rust/pvsecret/src/cmd/retr.rs
T
Steffen Eiden ff04f76257 rust/pv*: Allow the use of non-hashes secret IDs
Secret IDs identify a secret in the store. Tooling (pvsecret) calculates
them by hashing a user-defined string. With this patch it is now
possible to skip the hash step and directly use the input string as the
ID. Up to the first 31 bytes of the input ASCII-string are used. The last byte
is the NUL char. During list pvsecret tries to interpret the secret
as ASCII string and if possible displays the ASCII characters alongside
the hex number.

Also, use the Upper/Lower Hex formatters for the hexstring formatting of
SecretId. Display will, additionally show the ASCII representation if
applicable.

While at it, use Self wherever possible.

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>
2024-12-20 13:01:15 +01:00

69 lines
2.1 KiB
Rust

// SPDX-License-Identifier: MIT
//
// Copyright IBM Corp. 2024
use super::list::list_uvc;
use crate::cli::{RetrInpFmt, RetrOutFmt, RetrSecretOptions};
use anyhow::{anyhow, bail, Context, Result};
use log::{debug, info};
use pv::{
misc::open_file,
misc::write,
secret::{GuestSecret, RetrievedSecret},
uv::{RetrieveCmd, SecretId, UvDevice},
};
use utils::get_writer_from_cli_file_arg;
fn retrieve(id: &SecretId) -> Result<RetrievedSecret> {
let uv = UvDevice::open()?;
let secrets = list_uvc(&uv)?;
let secret = match secrets.find(id) {
Some(s) => s,
// hash it + try again if it is ASCII-representable
None => match id.as_ascii() {
Some(s) => secrets.find(&GuestSecret::name_to_id(s)?),
None => None,
}
.ok_or(anyhow!(
"The UV secret-store has no secret with the ID {id}"
))?,
};
info!("Try to retrieve secret at index: {}", secret.index());
debug!("Try to retrieve: {secret:?}");
let mut uv_cmd = RetrieveCmd::from_entry(secret)?;
uv.send_cmd(&mut uv_cmd)?;
Ok(RetrievedSecret::from_cmd(uv_cmd))
}
pub fn retr(opt: &RetrSecretOptions) -> Result<()> {
let mut output = get_writer_from_cli_file_arg(&opt.output)?;
let id = match &opt.inform {
RetrInpFmt::Yaml => match serde_yaml::from_reader(&mut open_file(&opt.input)?)? {
GuestSecret::Retrievable { id, .. } => id,
gs => bail!("The file contains a {gs}-secret, which is not retrievable."),
},
RetrInpFmt::Hex => {
serde_yaml::from_str(&opt.input).context("Cannot parse SecretId information")?
}
RetrInpFmt::Name => SecretId::from_string(&opt.input),
};
let retr_secret =
retrieve(&id).context("Could not retrieve the secret from the UV secret store.")?;
let out_data = match opt.outform {
RetrOutFmt::Bin => retr_secret.into_bytes(),
RetrOutFmt::Pem => retr_secret.to_pem()?.into_bytes(),
};
write(
&mut output,
out_data.value(),
&opt.output,
"IBM Protected Key",
)?;
Ok(())
}