use crate::OcspGeneralizedTime;
use alloc::vec::Vec;
use const_oid::{
db::rfc6960::{
ID_PKIX_OCSP_ARCHIVE_CUTOFF, ID_PKIX_OCSP_CRL, ID_PKIX_OCSP_NONCE,
ID_PKIX_OCSP_PREF_SIG_ALGS, ID_PKIX_OCSP_RESPONSE, ID_PKIX_OCSP_SERVICE_LOCATOR,
},
AssociatedOid,
};
use der::{
asn1::{Ia5String, ObjectIdentifier, OctetString, Uint},
Sequence, ValueOrd,
};
use spki::AlgorithmIdentifierOwned;
use x509_cert::{
ext::{pkix::AuthorityInfoAccessSyntax, AsExtension, Extension},
impl_newtype,
name::Name,
};
#[cfg(feature = "rand")]
use rand_core::CryptoRngCore;
macro_rules! impl_extension {
($newtype:ty, critical = $critical:expr) => {
impl AsExtension for $newtype {
fn critical(&self, _subject: &Name, _extensions: &[Extension]) -> bool {
$critical
}
}
};
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Nonce(pub OctetString);
impl_newtype!(Nonce, OctetString);
impl_extension!(Nonce, critical = false);
impl AssociatedOid for Nonce {
const OID: ObjectIdentifier = ID_PKIX_OCSP_NONCE;
}
impl Nonce {
pub fn new(bytes: impl Into<Vec<u8>>) -> Result<Self, der::Error> {
Ok(Self(OctetString::new(bytes)?))
}
#[cfg(feature = "rand")]
pub fn generate<R>(rng: &mut R, length: usize) -> Result<Self, der::Error>
where
R: CryptoRngCore,
{
let mut bytes = alloc::vec![0; length];
rng.fill_bytes(&mut bytes);
Self::new(bytes)
}
}
pub type CrlReferences = CrlId;
#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
#[allow(missing_docs)]
pub struct CrlId {
#[asn1(context_specific = "0", optional = "true", tag_mode = "EXPLICIT")]
pub crl_url: Option<Ia5String>,
#[asn1(context_specific = "1", optional = "true", tag_mode = "EXPLICIT")]
pub crl_num: Option<Uint>,
#[asn1(context_specific = "2", optional = "true", tag_mode = "EXPLICIT")]
pub crl_time: Option<OcspGeneralizedTime>,
}
impl_extension!(CrlId, critical = false);
impl AssociatedOid for CrlId {
const OID: ObjectIdentifier = ID_PKIX_OCSP_CRL;
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AcceptableResponses(pub Vec<ObjectIdentifier>);
impl_newtype!(AcceptableResponses, Vec<ObjectIdentifier>);
impl_extension!(AcceptableResponses, critical = true);
impl AssociatedOid for AcceptableResponses {
const OID: ObjectIdentifier = ID_PKIX_OCSP_RESPONSE;
}
pub struct ArchiveCutoff(pub OcspGeneralizedTime);
impl_newtype!(ArchiveCutoff, OcspGeneralizedTime);
impl_extension!(ArchiveCutoff, critical = false);
impl AssociatedOid for ArchiveCutoff {
const OID: ObjectIdentifier = ID_PKIX_OCSP_ARCHIVE_CUTOFF;
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub struct ServiceLocator {
pub issuer: Name,
pub locator: Option<AuthorityInfoAccessSyntax>,
}
impl AssociatedOid for ServiceLocator {
const OID: ObjectIdentifier = ID_PKIX_OCSP_SERVICE_LOCATOR;
}
impl_extension!(ServiceLocator, critical = false);
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PreferredSignatureAlgorithms(pub Vec<PreferredSignatureAlgorithm>);
impl_newtype!(
PreferredSignatureAlgorithms,
Vec<PreferredSignatureAlgorithm>
);
impl_extension!(PreferredSignatureAlgorithms, critical = false);
impl AssociatedOid for PreferredSignatureAlgorithms {
const OID: ObjectIdentifier = ID_PKIX_OCSP_PREF_SIG_ALGS;
}
#[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)]
#[allow(missing_docs)]
pub struct PreferredSignatureAlgorithm {
pub sig_identifier: AlgorithmIdentifierOwned,
pub cert_identifier: Option<AlgorithmIdentifierOwned>,
}