Skip to main content

structured_ltv/baseline/
material.rs

1//! Same-input composition of whole-signature validation-material facts.
2
3use super::{BasicStage, CredentialMaterial, Timed, X509Material};
4use crate::pki::ParticipantError;
5use crate::source::Query;
6use crate::timestamp::TimestampScope;
7
8/// Linked original time, X.509 and credential-format material reports. Public
9/// input slots cannot manufacture a fact: construction verifies their exact
10/// participant receipts, including selected path contexts. This is
11/// incorporation/placement, not Good status, chronology, algorithm longevity
12/// or caller trust, and cannot by itself assert B-LT acceptance.
13pub struct LongTerm<'a, T, M, C> {
14    timed: &'a T,
15    x509: &'a M,
16    credentials: &'a C,
17    material_complete: bool,
18}
19
20impl<T, M, C> LongTerm<'_, T, M, C> {
21    /// Original whole-token set and root signature-time static associations.
22    #[must_use]
23    pub fn timed(&self) -> &T {
24        self.timed
25    }
26    /// All original X.509 incorporation and placement findings.
27    #[must_use]
28    pub fn x509(&self) -> &M {
29        self.x509
30    }
31    /// Every actual credential's own format-material interpretation/findings.
32    #[must_use]
33    pub fn credentials(&self) -> &C {
34        self.credentials
35    }
36    /// Both complete material predicates, without erasing their detailed causes.
37    /// This constant-time getter does not rescan any untrusted catalogue.
38    #[must_use]
39    pub fn all_material_requirements_met(&self) -> bool {
40        self.material_complete
41    }
42}
43
44/// A different scope/input receipt is a processing refusal, not absent material.
45pub type MaterialResult<'a, T, M, C, N> = Result<LongTerm<'a, T, M, C>, ParticipantError<N>>;
46
47type TimedOf<'a, 'c, 'd, 'path, 'document, B, Q, I> = Timed<
48    'a,
49    'c,
50    'd,
51    B,
52    <B as BasicStage<'path, 'document>>::Signer,
53    <Q as Query>::Id,
54    <Q as Query>::Document,
55    <Q as Query>::Generation,
56    I,
57>;
58
59/// Link the SAME complete participant/status closure and authenticated
60/// credential catalogue to the root/counters/all-token time report. No source
61/// parse, signature, credential authentication, status evaluation or artifact
62/// lookup is repeated. Earlier-archive subsets cannot stand for whole B-LT.
63/// EN319132-1 V1.3.1 ยงยง5.4/6.3(x) require all validation material while keeping
64/// status usability and application trust distinct from incorporated presence.
65/// <https://www.etsi.org/deliver/etsi_en/319100_319199/31913201/01.03.01_60/en_31913201v010301p.pdf>
66pub fn long_term<'s, 'a, 'c, 'd, 'path, 'document, B, M, C, Q, I>(
67    timed: &'s TimedOf<'a, 'c, 'd, 'path, 'document, B, Q, I>,
68    x509: &'s M,
69    credentials: &'s C,
70    query: &Q,
71) -> MaterialResult<'s, TimedOf<'a, 'c, 'd, 'path, 'document, B, Q, I>, M, C, Q::Id>
72where
73    'document: 'path,
74    B: BasicStage<'path, 'document, Id = Q::Id, Document = Q::Document, Generation = Q::Generation>,
75    M: X509Material<
76            'path,
77            'document,
78            Id = Q::Id,
79            Document = Q::Document,
80            Generation = Q::Generation,
81            Issuer = I,
82        >,
83    C: CredentialMaterial<Id = Q::Id, Document = Q::Document, Generation = Q::Generation>,
84    Q: Query,
85{
86    let requirements = x509.requirements();
87    if !matches!(requirements.scope(), TimestampScope::All(_))
88        || !matches!(credentials.scope(), TimestampScope::All(_))
89    {
90        return Err(ParticipantError::Foreign {
91            signature: requirements.signature(),
92        });
93    }
94    let basic = timed.basic();
95    requirements.require_inputs(
96        basic.signer(),
97        basic.counters(),
98        credentials.credentials(),
99        timed.paths(),
100        query,
101    )?;
102    Ok(LongTerm {
103        timed,
104        x509,
105        credentials,
106        material_complete: x509.all_x509_requirements_met() && credentials.all_requirements_met(),
107    })
108}