use const_oid::AssociatedOid;
use der::{Sequence, ValueOrd, asn1::OctetString};
use spki::ObjectIdentifier;
pub mod pkix;
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
#[allow(missing_docs)]
pub struct Extension {
pub extn_id: ObjectIdentifier,
#[asn1(default = "Default::default")]
pub critical: bool,
pub extn_value: OctetString,
}
impl ToExtension for Extension {
type Error = der::Error;
fn to_extension(
self,
_subject: &crate::name::Name,
_extensions: &[Extension],
) -> Result<Extension, Self::Error> {
Ok(self)
}
}
pub type Extensions = alloc::vec::Vec<Extension>;
pub trait Criticality {
fn criticality(&self, subject: &crate::name::Name, extensions: &[Extension]) -> bool;
}
pub trait ToExtension {
type Error;
fn to_extension(
self,
subject: &crate::name::Name,
extensions: &[Extension],
) -> Result<Extension, Self::Error>;
}
impl<T: Criticality + AssociatedOid + der::Encode> ToExtension for &T {
type Error = der::Error;
fn to_extension(
self,
subject: &crate::name::Name,
extensions: &[Extension],
) -> Result<Extension, Self::Error> {
let criticality = self.criticality(subject, extensions);
(criticality, self).to_extension(subject, extensions)
}
}
impl<T: Criticality + der::Encode> ToExtension for (ObjectIdentifier, &T) {
type Error = der::Error;
fn to_extension(
self,
subject: &crate::name::Name,
extensions: &[Extension],
) -> Result<Extension, Self::Error> {
let criticality = self.1.criticality(subject, extensions);
(self.0, criticality, self.1).to_extension(subject, extensions)
}
}
impl<T: AssociatedOid + der::Encode> ToExtension for (bool, &T) {
type Error = der::Error;
fn to_extension(
self,
subject: &crate::name::Name,
extensions: &[Extension],
) -> Result<Extension, Self::Error> {
(T::OID, self.0, self.1).to_extension(subject, extensions)
}
}
impl<T: der::Encode> ToExtension for (ObjectIdentifier, bool, &T) {
type Error = der::Error;
fn to_extension(
self,
_subject: &crate::name::Name,
_extensions: &[Extension],
) -> Result<Extension, Self::Error> {
Ok(Extension {
extn_id: self.0,
critical: self.1,
extn_value: OctetString::new(self.2.to_der()?)?,
})
}
}