use super::cert::Certificate;
use super::*;
use crate::certs::Usage;
use serde::{Deserialize, Serialize};
use std::io::{Error, ErrorKind, Result};
#[repr(C)]
#[derive(Deserialize, Serialize)]
pub struct Chain {
pub pdh: Certificate,
pub pek: Certificate,
pub oca: Certificate,
pub cek: Certificate,
}
impl codicon::Decoder<()> for Chain {
type Error = Error;
fn decode(mut reader: impl Read, _: ()) -> Result<Self> {
let pdh = Certificate::decode(&mut reader, ())?;
if Usage::try_from(&pdh)? != Usage::PDH {
return Err(ErrorKind::InvalidInput.into());
}
let pek = Certificate::decode(&mut reader, ())?;
if Usage::try_from(&pek)? != Usage::PEK {
return Err(ErrorKind::InvalidInput.into());
}
let oca = Certificate::decode(&mut reader, ())?;
if Usage::try_from(&oca)? != Usage::OCA {
return Err(ErrorKind::InvalidInput.into());
}
let cek = Certificate::decode(&mut reader, ())?;
if Usage::try_from(&cek)? != Usage::CEK {
return Err(ErrorKind::InvalidInput.into());
}
Ok(Self { pdh, pek, oca, cek })
}
}
impl codicon::Encoder<()> for Chain {
type Error = Error;
fn encode(&self, mut writer: impl Write, _: ()) -> Result<()> {
self.pdh.encode(&mut writer, crate::Body)?;
self.pek.encode(&mut writer, crate::Body)?;
self.oca.encode(&mut writer, crate::Body)?;
self.cek.encode(&mut writer, crate::Body)
}
}
impl<'a> Verifiable for &'a Chain {
type Output = &'a Certificate;
fn verify(self) -> Result<Self::Output> {
(&self.oca, &self.oca).verify()?;
(&self.oca, &self.pek).verify()?;
(&self.cek, &self.pek).verify()?;
(&self.pek, &self.pdh).verify()?;
Ok(&self.pdh)
}
}