#[cfg(feature = "openssl")]
use openssl::x509::X509;
use super::*;
#[derive(Clone, Debug)]
pub struct Chain {
pub ark: Certificate,
pub ask: Certificate,
}
impl<'a> Verifiable for &'a Chain {
type Output = &'a Certificate;
fn verify(self) -> Result<Self::Output> {
(&self.ark, &self.ark).verify()?;
(&self.ark, &self.ask).verify()?;
Ok(&self.ask)
}
}
#[cfg(feature = "openssl")]
impl From<(X509, X509)> for Chain {
fn from(value: (X509, X509)) -> Self {
Self {
ark: value.1.into(),
ask: value.0.into(),
}
}
}
#[cfg(feature = "openssl")]
impl From<(&X509, &X509)> for Chain {
fn from(value: (&X509, &X509)) -> Self {
(value.0.clone(), value.1.clone()).into()
}
}
#[cfg(feature = "openssl")]
impl<'a: 'b, 'b> From<&'a Chain> for (&'b X509, &'b X509) {
fn from(value: &'a Chain) -> Self {
((&value.ask).into(), (&value.ark).into())
}
}
#[cfg(feature = "openssl")]
impl From<&[X509]> for Chain {
fn from(value: &[X509]) -> Self {
(&value[0], &value[1]).into()
}
}
impl From<(Certificate, Certificate)> for Chain {
fn from(value: (Certificate, Certificate)) -> Self {
Self {
ark: value.1,
ask: value.0,
}
}
}
impl From<(&Certificate, &Certificate)> for Chain {
fn from(value: (&Certificate, &Certificate)) -> Self {
Self {
ark: value.1.clone(),
ask: value.0.clone(),
}
}
}
impl<'a: 'b, 'b> From<&'a Chain> for (&'b Certificate, &'b Certificate) {
fn from(value: &'a Chain) -> Self {
(&value.ask, &value.ark)
}
}
impl From<&[Certificate]> for Chain {
fn from(value: &[Certificate]) -> Self {
(&value[0], &value[1]).into()
}
}
impl Chain {
pub fn from_pem(ark: &[u8], ask: &[u8]) -> Result<Self> {
Ok(Self {
ark: Certificate::from_pem(ark)?,
ask: Certificate::from_pem(ask)?,
})
}
pub fn from_der(ark: &[u8], ask: &[u8]) -> Result<Self> {
Ok(Self {
ark: Certificate::from_der(ark)?,
ask: Certificate::from_der(ask)?,
})
}
#[cfg(feature = "openssl")]
pub fn from_pem_bytes(stack: &[u8]) -> Result<Self> {
let certificates = X509::stack_from_pem(stack)?;
let ark_cert = &certificates[1];
let ask_cert = &certificates[0];
Ok(Self {
ark: ark_cert.into(),
ask: ask_cert.into(),
})
}
}
mod tests {
#[test]
fn milan_ca_chain_verifiable() {
use crate::certs::snp::{builtin::milan, ca::*, Verifiable};
let chain = Chain {
ark: milan::ark().unwrap(),
ask: milan::ask().unwrap(),
};
chain.verify().unwrap();
}
#[test]
fn genoa_ca_chain_verifiable() {
use crate::certs::snp::{builtin::genoa, ca::*, Verifiable};
let chain = Chain {
ark: genoa::ark().unwrap(),
ask: genoa::ask().unwrap(),
};
chain.verify().unwrap();
}
}