use crate::tls::Error;
use crate::x509::{AnyPublicKey, Certificate};
use alloc::vec::Vec;
#[derive(Clone)]
pub(crate) struct TrustAnchor {
pub(crate) subject_der: Vec<u8>,
pub(crate) key: AnyPublicKey,
}
#[derive(Clone, Default)]
pub struct RootCertStore {
anchors: Vec<TrustAnchor>,
}
impl RootCertStore {
pub fn new() -> Self {
RootCertStore {
anchors: Vec::new(),
}
}
pub fn add_der(&mut self, der: Vec<u8>) -> Result<(), Error> {
let cert = Certificate::from_der(der).map_err(|_| Error::BadCertificate)?;
let subject_der = cert
.subject_der()
.map_err(|_| Error::BadCertificate)?
.to_vec();
let key = cert
.subject_public_key()
.map_err(|_| Error::BadCertificate)?;
self.anchors.push(TrustAnchor { subject_der, key });
Ok(())
}
pub fn add_pem(&mut self, pem: &str) -> Result<(), Error> {
let cert = Certificate::from_pem(pem).map_err(|_| Error::BadCertificate)?;
self.add_der(cert.to_der().to_vec())
}
pub fn len(&self) -> usize {
self.anchors.len()
}
pub fn is_empty(&self) -> bool {
self.anchors.is_empty()
}
pub fn clone_store(&self) -> Self {
self.clone()
}
pub(crate) fn anchors_with_subject<'a>(
&'a self,
name_der: &'a [u8],
) -> impl Iterator<Item = &'a TrustAnchor> + 'a {
self.anchors
.iter()
.filter(move |a| a.subject_der.as_slice() == name_der)
}
}