2024-08-06 20:23:08 -07:00

95 lines
2.4 KiB
Rust

use std::{
fs::File, io, sync::Arc
};
use tokio::sync::RwLock;
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
use trie::Trie;
pub struct Certificate {
pub certs:Vec<CertificateDer<'static>>,
pub key:PrivateKeyDer<'static>,
}
pub struct CertificateStore {
certs:Trie<Arc<Certificate>>,
}
impl CertificateStore {
pub fn new() -> Self
{
Self {
certs:Trie::<Arc<Certificate>>::new(),
}
}
pub fn add(&mut self, domain:&str, cert_file:&str, key_file:&str) -> Result<(),()>
{
// load certificate file
let certs = match File::open(cert_file) {
Ok(fcert) => {
let mut reader = io::BufReader::new(fcert);
let mut certificates = Vec::<CertificateDer>::new();
for result in rustls_pemfile::certs(&mut reader) {
match result {
Ok(certificate) => {
certificates.push(certificate);
}
Err(_) => { }
}
}
Ok(certificates)
}
Err(_) => Err(())
};
// load private key file
let key = match File::open(key_file) {
Ok(fkey) => {
let mut reader = io::BufReader::new(fkey);
match rustls_pemfile::private_key(&mut reader) {
Ok(result) => match result {
Some(key) => Ok(key),
None => Err(())
}
Err(_) => Err(())
}
}
Err(_) => Err(())
};
if certs.is_ok() && key.is_ok() {
self.certs.set(domain, Arc::new(Certificate {
certs:certs.unwrap(),
key:key.unwrap(),
}));
Ok(())
}
else {
Err(())
}
}
pub fn remove(&mut self, domain:&str) -> Result<(),()>
{
if self.certs.unset(domain) {
Ok(())
}
else {
Err(())
}
}
pub fn get(&self, domain:&str) -> Result<Arc<Certificate>, ()>
{
match self.certs.get(domain) {
Some(certs) => Ok(certs),
None => Err(())
}
}
pub fn to_share(self) -> Arc<RwLock<Self>>
{
Arc::new(RwLock::new(self))
}
}