26af08e
use config::app::{AppConfig, AppKeyAlgorithm, AppKeyConfig, SecretMaterial};
use crate::error::{CryptError, CryptResult};
use crate::key::{RsaDecryptor, RsaEncryptor, RsaKeyPair};
pub fn encryptor(config: &AppConfig) -> CryptResult<RsaEncryptor> {
let key = config
.encryption_key()
.ok_or_else(|| CryptError::KeyNotFound(config.active_key_id.clone()))?;
encryptor_for(key)
}
pub fn encryptor_for(key: &AppKeyConfig) -> CryptResult<RsaEncryptor> {
check_algorithm(key)?;
let pem = resolve(&key.public_key, &key.key_id)?;
RsaEncryptor::from_public_pem(key.key_id.clone(), &pem)
}
pub fn encryptor_from_public_pem(
key_id: impl Into<String>,
pem: &str,
) -> CryptResult<RsaEncryptor> {
RsaEncryptor::from_public_pem(key_id, pem)
}
pub fn decryptor(config: &AppConfig) -> CryptResult<RsaDecryptor> {
let mut keys = Vec::new();
for key in config.decryption_keys() {
check_algorithm(key)?;
let private = key
.private_key
.as_ref()
.ok_or_else(|| CryptError::KeyNotFound(key.key_id.clone()))?;
let private_pem = resolve(private, &key.key_id)?;
let public_pem = resolve(&key.public_key, &key.key_id)?;
keys.push(RsaKeyPair::from_pem_pair(
key.key_id.clone(),
&private_pem,
&public_pem,
)?);
}
RsaDecryptor::new(keys)
}
pub fn fingerprint_for(key: &AppKeyConfig) -> CryptResult<String> {
Ok(encryptor_for(key)?.fingerprint())
}
fn resolve(material: &SecretMaterial, key_id: &str) -> CryptResult<String> {
material
.resolve()
.map_err(|error| CryptError::Config(format!("key `{key_id}`: {error}")))
}
fn check_algorithm(key: &AppKeyConfig) -> CryptResult<()> {
match key.algorithm {
AppKeyAlgorithm::RsaOaep256A256Gcm => Ok(()),
}
}