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.
91 lines
2.4 KiB
91 lines
2.4 KiB
use crate::domain::tls::{Certificate, PrivateKey};
|
|
use crate::error::unexpected::{self, Mappable};
|
|
use crate::{domain, util};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::{fs, path};
|
|
|
|
pub trait Store {
|
|
fn get_certificate(
|
|
&self,
|
|
domain: &domain::Name,
|
|
) -> unexpected::Result<Option<(PrivateKey, Certificate)>>;
|
|
|
|
fn set_certificate(
|
|
&self,
|
|
domain: &domain::Name,
|
|
pkey: PrivateKey,
|
|
cert: Certificate,
|
|
) -> unexpected::Result<()>;
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
struct StoredPKeyCert {
|
|
private_key: PrivateKey,
|
|
cert: Certificate,
|
|
}
|
|
|
|
pub struct FSStore {
|
|
cert_dir_path: path::PathBuf,
|
|
}
|
|
|
|
impl FSStore {
|
|
pub fn new(dir_path: &path::Path) -> unexpected::Result<Self> {
|
|
let cert_dir_path = dir_path.join("certificates");
|
|
fs::create_dir_all(&cert_dir_path)
|
|
.map_unexpected_while(|| format!("creating dir {}", cert_dir_path.display()))?;
|
|
|
|
Ok(Self { cert_dir_path })
|
|
}
|
|
|
|
fn pkey_cert_path(&self, domain: &domain::Name) -> path::PathBuf {
|
|
let mut domain = domain.as_str().to_string();
|
|
domain.push_str(".json");
|
|
self.cert_dir_path.join(domain)
|
|
}
|
|
}
|
|
|
|
impl Store for FSStore {
|
|
fn get_certificate(
|
|
&self,
|
|
domain: &domain::Name,
|
|
) -> unexpected::Result<Option<(PrivateKey, Certificate)>> {
|
|
let path = self.pkey_cert_path(domain);
|
|
|
|
let file = match util::open_file(path.as_path())
|
|
.map_unexpected_while(|| format!("opening file {}", path.display()))?
|
|
{
|
|
Some(file) => file,
|
|
None => {
|
|
return Ok(None);
|
|
}
|
|
};
|
|
|
|
let stored: StoredPKeyCert =
|
|
serde_json::from_reader(file).or_unexpected_while("parsing json")?;
|
|
|
|
Ok(Some((stored.private_key, stored.cert)))
|
|
}
|
|
|
|
fn set_certificate(
|
|
&self,
|
|
domain: &domain::Name,
|
|
pkey: PrivateKey,
|
|
cert: Certificate,
|
|
) -> unexpected::Result<()> {
|
|
let path = self.pkey_cert_path(domain);
|
|
|
|
let file = fs::File::create(path.as_path())
|
|
.map_unexpected_while(|| format!("creating file {}", path.display()))?;
|
|
|
|
let stored = StoredPKeyCert {
|
|
private_key: pkey,
|
|
cert,
|
|
};
|
|
|
|
serde_json::to_writer(file, &stored).or_unexpected_while("writing cert to file")?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|