50 lines
1.6 KiB
Rust
50 lines
1.6 KiB
Rust
use doot_core::{Config, encryption::AgeEncryption};
|
|
use std::io::Write;
|
|
use std::path::PathBuf;
|
|
|
|
/// Extracts the AGE-SECRET-KEY line from identity file content (filters comments).
|
|
fn extract_identity_key(raw: &str) -> String {
|
|
raw.lines()
|
|
.find(|line| line.starts_with("AGE-SECRET-KEY-"))
|
|
.map(|s| s.trim().to_string())
|
|
.unwrap_or_else(|| raw.trim().to_string())
|
|
}
|
|
|
|
/// Decrypts an age-encrypted file to stdout (default) or to a file with --output.
|
|
#[tracing::instrument(skip_all, fields(file = %file.display()))]
|
|
pub fn run(
|
|
file: PathBuf,
|
|
identity: Option<PathBuf>,
|
|
output: Option<PathBuf>,
|
|
) -> anyhow::Result<()> {
|
|
let config = Config::default();
|
|
let identity_raw = if let Some(path) = identity {
|
|
std::fs::read_to_string(&path)?
|
|
} else if let Ok(key) = std::env::var("DOOT_AGE_IDENTITY") {
|
|
key
|
|
} else if config.identity_file.exists() {
|
|
std::fs::read_to_string(&config.identity_file)?
|
|
} else {
|
|
anyhow::bail!(
|
|
"no identity specified. use --identity, DOOT_AGE_IDENTITY env var, or {}",
|
|
config.identity_file.display()
|
|
);
|
|
};
|
|
|
|
let identity_key = extract_identity_key(&identity_raw);
|
|
|
|
tracing::debug!(file = %file.display(), "decrypting file");
|
|
|
|
let encryption = AgeEncryption::new().with_identity(&identity_key)?;
|
|
let data = std::fs::read(&file)?;
|
|
let decrypted = encryption.decrypt(&data)?;
|
|
|
|
if let Some(out_path) = output {
|
|
std::fs::write(&out_path, &decrypted)?;
|
|
eprintln!("decrypted {} -> {}", file.display(), out_path.display());
|
|
} else {
|
|
std::io::stdout().write_all(&decrypted)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|