use std::path::Path;
use secrecy::{ExposeSecret, SecretString};
use crate::core::crypto;
use crate::error::VaultError;
pub fn save_private_key(path: &Path, key: &SecretString) -> Result<(), VaultError> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(path, key.expose_secret())?;
set_permissions_600(path)?;
Ok(())
}
pub fn save_public_key(path: &Path, key: &str) -> Result<(), VaultError> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(path, key)?;
Ok(())
}
pub fn load_public_key(path: &Path) -> Result<String, VaultError> {
let key = std::fs::read_to_string(path)?.trim().to_string();
Ok(key)
}
pub fn load_private_key(path: &Path) -> Result<SecretString, VaultError> {
let key = std::fs::read_to_string(path)?.trim().to_string();
Ok(SecretString::from(key))
}
pub fn create_escrow(
agent_private_key: &SecretString,
owner_pub_key: &str,
escrow_path: &Path,
) -> Result<(), VaultError> {
let owner_recipient = crypto::parse_recipient(owner_pub_key)?;
let encrypted = crypto::encrypt(agent_private_key.expose_secret().as_bytes(), &[owner_recipient])?;
if let Some(parent) = escrow_path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(escrow_path, encrypted)?;
Ok(())
}
pub fn recover_from_escrow(
escrow_path: &Path,
owner_private_key: &SecretString,
) -> Result<SecretString, VaultError> {
let ciphertext = std::fs::read(escrow_path)?;
let identity = crypto::parse_identity(owner_private_key.expose_secret())?;
crypto::decrypt(&ciphertext, &identity)
}
#[cfg(unix)]
fn set_permissions_600(path: &Path) -> Result<(), VaultError> {
use std::os::unix::fs::PermissionsExt;
let perms = std::fs::Permissions::from_mode(0o600);
std::fs::set_permissions(path, perms)?;
Ok(())
}
#[cfg(not(unix))]
fn set_permissions_600(_path: &Path) -> Result<(), VaultError> {
Ok(())
}