You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.7 KiB
68 lines
2.7 KiB
//! AES file container operations
|
|
//!
|
|
//! Should operate on streams to produce/consume instances of `format::key::aes::AesBody`.
|
|
use super::*;
|
|
use std::{
|
|
path::Path,
|
|
};
|
|
use tokio::{
|
|
io::BufReader,
|
|
fs::OpenOptions,
|
|
};
|
|
|
|
/// Read an `AesBody` from a file.
|
|
///
|
|
/// Detect the container type if possible and then decode the AES key. Returning it as `format::key::aes::AesBody`.
|
|
#[instrument(skip(path), err, fields(path = ?path.as_ref()))]
|
|
pub async fn read_aes_container(path: impl AsRef<Path>, passwd: (config::op::Password, Option<&str>)) -> eyre::Result<format::key::aes::AesBody>
|
|
{
|
|
// password function
|
|
let passwd = passwd.0.into_password(passwd.1.unwrap_or("Enter password for input key: "))?;
|
|
macro_rules! passwdfn {
|
|
() => (|salt| passwd.as_ref().map(|string| crypto::password::Password::derive(string, salt)))
|
|
}
|
|
// read from `path`
|
|
use config::op::KeyFormat;
|
|
let aesbody = match resolve::find_key_format(&path, false).await
|
|
.wrap_err(eyre!("Failed to detect file format for key"))
|
|
.with_section(|| format!("{:?}", path.as_ref()).header("Path was"))
|
|
.with_suggestion(|| "Are you sure this file is valid?")? {
|
|
#[cold] KeyFormat::PEM => unreachable!(),
|
|
other => {
|
|
let mut file = OpenOptions::new()
|
|
.read(true)
|
|
.open(path).await
|
|
.wrap_err(eyre!("Failed to open file for reading a second time."))
|
|
.with_suggestion(|| "Has the file just been/is being modified as we are reading it?")
|
|
.with_section(|| format!("{:?}", other).header("File format was successfully detected as"))?;
|
|
match other {
|
|
KeyFormat::Bin => {
|
|
let sh = format::SuperHeader::<format::key::KeyHeader>::read_bytes(&mut file, passwdfn!()).await
|
|
.wrap_err(eyre!("Failed to read key super-header"))?;
|
|
trace!("Read super {:?}", sh);
|
|
let h = format::key::KeyHeader::read_bytes(&mut file, passwdfn!()).await
|
|
.wrap_err(eyre!("Failed to read key header"))?;
|
|
trace!("Read header {:?}", h);
|
|
format::key::aes::AesBody::read_bytes(&mut file, h.body_key()).await
|
|
.wrap_err(eyre!("Failed to read key body"))?
|
|
},
|
|
KeyFormat::Text => {
|
|
let mut file = BufReader::new(file);
|
|
let sh = format::SuperHeader::<format::key::KeyHeader>::read_text(&mut file, passwdfn!()).await
|
|
.wrap_err(eyre!("Failed to read key super-header"))?;
|
|
trace!("Read super {:?}", sh);
|
|
let h = format::key::KeyHeader::read_text(&mut file, passwdfn!()).await
|
|
.wrap_err(eyre!("Failed to read key header"))?;
|
|
trace!("Read header {:?}", h);
|
|
format::key::aes::AesBody::read_text(&mut file, h.body_key()).await
|
|
.wrap_err(eyre!("Failed to read key body"))?
|
|
},
|
|
#[cold] _ => unreachable!(),
|
|
}
|
|
},
|
|
};
|
|
debug!("Read body {:?}", aesbody);
|
|
|
|
Ok(aesbody)
|
|
}
|