Skip to main content

structured_xades/produce/
timestamp.rs

1//! Completed-response construction, distinct from an attained baseline grade.
2
3use super::{Emit, Error, Work, Writer, XADES};
4use crate::timestamp::XADES_141;
5
6/// New unsigned timestamp property to append at the staged tail.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum TimestampKind {
9    /// Single-token `SignatureTimeStamp` for B-T.
10    Signature,
11    /// `ArchiveTimeStamp` in the v1.4.1 namespace for B-LTA or renewal.
12    Archive,
13}
14
15/// Original token accepted by the request-bound common checker for the exact
16/// proposed input. Only the augmentation operation constructs this association.
17/// It is not trust, revocation chronology or a complete B-T/LTA assessment.
18pub struct Timestamp<'a, D, G, N> {
19    pub(super) snapshot: crate::xml::Snapshot<D, G>,
20    pub(super) signature: N,
21    pub(super) method: N,
22    pub(super) kind: TimestampKind,
23    pub(super) token: &'a structured_asn1::Element<'a>,
24    pub(super) producer: structured_pkix::algorithm::Producer<'a>,
25    pub(super) evidence: &'a structured_cms::timestamp::Evidence,
26}
27impl<D: Copy, G: Copy, N: Copy> Timestamp<'_, D, G, N> {
28    /// Mathematical token/authority/input facts retained by the existing checker.
29    #[must_use]
30    pub fn evidence(&self) -> &structured_cms::timestamp::Evidence {
31        self.evidence
32    }
33    /// Exact snapshot used to compute and check this token's input.
34    #[must_use]
35    pub fn snapshot(&self) -> crate::xml::Snapshot<D, G> {
36        self.snapshot
37    }
38    /// Actual method node used for reference replay and canonicalization.
39    #[must_use]
40    pub fn method(&self) -> N {
41        self.method
42    }
43
44    pub(super) fn write<B: Writer, W: Work>(
45        &self,
46        writer: &mut B,
47        work: &W,
48        method: impl FnOnce(&mut B, &structured_asn1::memory::Execution<'_>) -> Result<(), B::Error>,
49    ) -> Result<(), Error<B::Error>> {
50        let scoped = self.producer.execution_in(work);
51        let mut emit = Emit {
52            writer,
53            work: &scoped,
54        };
55        let (namespace, local) = match self.kind {
56            TimestampKind::Signature => (XADES, "SignatureTimeStamp"),
57            TimestampKind::Archive => (XADES_141, "ArchiveTimeStamp"),
58        };
59        emit.begin(namespace, local)?;
60        // Method XML (including PrefixList) must be copied by its XML owner,
61        // never reconstructed from only a URI or an invented ASN.1 identifier.
62        scoped.charge_work(1).map_err(Error::Resource)?;
63        method(emit.writer, &scoped).map_err(Error::Writer)?;
64        emit.binary(XADES, "EncapsulatedTimeStamp", self.token.as_bytes())?;
65        emit.end()
66    }
67}