use super::{
ConditionalError, ConditionalPlacement, ExclusivePlacement, ExclusivityError, Index, Placement,
TimestampPlacement, TimestampPlacementError, conditional_placement, exclusivity,
timestamp_placement,
};
use crate::Xades;
use crate::pki::CounterPaths;
use crate::prepare::Prepared;
use crate::xml::{Access, Xml};
use structured_asn1::memory::Work;
use structured_ltv::baseline::X509Material;
use structured_ltv::material::{Incorporation, IncorporationError, artifact_uses, incorporation};
use structured_ltv::pki::{ParticipantClosure, ParticipantRequirements, UsesError, authority_uses};
pub struct Checks<'closure, 'requirements, 'view, 'certificate, 'document, N, D, G> {
presence: Incorporation<'certificate, 'document, N, D, G, Placement<N>>,
conditional: ConditionalPlacement<'certificate, 'document, N, D, G>,
exclusive: ExclusivePlacement<'certificate, 'document, N, D, G>,
timestamps:
TimestampPlacement<'closure, 'requirements, 'view, 'certificate, 'document, N, D, G>,
}
impl<N: Copy, D: Copy, G: Copy> Checks<'_, '_, '_, '_, '_, N, D, G> {
#[must_use]
pub fn presence(&self) -> &Incorporation<'_, '_, N, D, G, Placement<N>> {
&self.presence
}
#[must_use]
pub fn conditional(&self) -> &ConditionalPlacement<'_, '_, N, D, G> {
&self.conditional
}
#[must_use]
pub fn exclusive(&self) -> &ExclusivePlacement<'_, '_, N, D, G> {
&self.exclusive
}
#[must_use]
pub fn timestamps(&self) -> &TimestampPlacement<'_, '_, '_, '_, '_, N, D, G> {
&self.timestamps
}
#[must_use]
pub fn all_x509_requirements_met(&self) -> bool {
self.presence.all_present()
&& self.conditional.findings().is_empty()
&& self.exclusive.findings().is_empty()
&& self.timestamps.findings().is_empty()
}
}
impl<'v, 'd, N: Copy, D: Copy, G: Copy> X509Material<'v, 'd>
for Checks<'_, '_, 'v, '_, 'd, N, D, G>
{
type Id = N;
type Document = D;
type Generation = G;
type Issuer = Xades;
fn requirements(&self) -> &ParticipantRequirements<'v, 'd, N, D, G, Xades> {
self.timestamps.inputs().requirements()
}
fn all_x509_requirements_met(&self) -> bool {
Checks::all_x509_requirements_met(self)
}
}
#[derive(Debug)]
pub enum CheckError<'certificate, 'document, E, N> {
Conditional(ConditionalError<E, N>),
Uses(UsesError<N>),
Presence(IncorporationError<N>),
Exclusive(ExclusivityError<'certificate, 'document, N>),
Timestamp(TimestampPlacementError<N>),
}
pub type CheckResult<'closure, 'requirements, 'view, 'certificate, 'document, X> = Result<
Checks<
'closure,
'requirements,
'view,
'certificate,
'document,
<X as Xml>::Id,
<X as Xml>::Document,
<X as Xml>::Generation,
>,
CheckError<'certificate, 'document, <X as Xml>::Error, <X as Xml>::Id>,
>;
pub fn check_participants<
'closure,
'requirements,
'view,
'certificate,
'document,
X: Xml,
W: Work,
Q: Work,
>(
prepared: &Prepared<X>,
inputs: &'closure ParticipantClosure<
'requirements,
'view,
'certificate,
'document,
X::Id,
X::Document,
X::Generation,
Xades,
>,
counters: &CounterPaths<'_, 'document, X::Id, X::Document, X::Generation>,
index: &Index<'_, X::Id, X::Document, X::Generation, W>,
access: &Access<'_, X, Q>,
) -> CheckResult<'closure, 'requirements, 'view, 'certificate, 'document, X> {
let conditional = conditional_placement(prepared, inputs, counters, index, access)
.map_err(CheckError::Conditional)?;
let purposes = authority_uses(inputs, access).map_err(CheckError::Uses)?;
let artifacts = artifact_uses(&purposes, access).map_err(CheckError::Uses)?;
let presence = incorporation(&artifacts, index, access).map_err(CheckError::Presence)?;
let exclusive = exclusivity(&artifacts, index, access).map_err(CheckError::Exclusive)?;
let timestamps = timestamp_placement(inputs, index, access).map_err(CheckError::Timestamp)?;
Ok(Checks {
presence,
conditional,
exclusive,
timestamps,
})
}