use super::OtherRevocationInfo;
use structured_asn1::{Element, Oid, Reader, Tag, universal};
use structured_pkix::{crl::CertificateList, ocsp::BasicResponse};
pub enum Reading<'a> {
Crl(CertificateList<'a>),
Ocsp(BasicResponse<'a>),
Open {
format: Oid<'a>,
},
}
#[derive(Debug)]
pub enum Error {
Cms(crate::Error),
Pkix(structured_pkix::Error),
}
impl Error {
#[must_use]
pub fn is_terminal(&self) -> bool {
match self {
Self::Cms(cause) => cause.is_terminal(),
Self::Pkix(cause) => {
cause.is_resource() || cause.code() == structured_pkix::ErrorCode::ForeignReader
}
}
}
}
pub fn read<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Reading<'a>, Error> {
if element.tag() == Tag::constructed(universal::SEQUENCE) {
return CertificateList::read_element(parent, element)
.map(Reading::Crl)
.map_err(Error::Pkix);
}
let other = OtherRevocationInfo::read(parent, element).map_err(Error::Cms)?;
let format = other.kind();
let Some(response) = other.ocsp().map_err(Error::Cms)? else {
return Ok(Reading::Open { format });
};
let Some(value) = response.basic_in(parent).map_err(Error::Pkix)? else {
return Ok(Reading::Open { format });
};
Ok(Reading::Ocsp(value))
}