Skip to main content

structured_cms/timestamp/
policy_accuracy.rs

1//! Explicit caller-established policy accuracy, never document discovery.
2
3use super::Accuracy;
4use core::fmt;
5use structured_asn1::Oid;
6
7/// Trusted accuracy for an explicitly identified TSA policy.
8/// The caller authenticates this policy and its association with the selected
9/// TSA. The checker compares its identifier to the signed `TSTInfo` policy.
10#[derive(Debug, Clone, Copy)]
11pub struct PolicyAccuracy<'a> {
12    policy: Oid<'a>,
13    accuracy: Accuracy,
14}
15
16/// A fractional accuracy component exceeds its decomposed 0..=999 range.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct InvalidPolicyAccuracy;
19
20impl fmt::Display for InvalidPolicyAccuracy {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        f.write_str("policy accuracy fractional component exceeds 999")
23    }
24}
25impl core::error::Error for InvalidPolicyAccuracy {}
26
27impl<'a> PolicyAccuracy<'a> {
28    /// Bind a caller-established deviation to its policy identifier. Zero
29    /// denotes an omitted component, not an implicit whole-accuracy default.
30    pub const fn new(policy: Oid<'a>, accuracy: Accuracy) -> Result<Self, InvalidPolicyAccuracy> {
31        if accuracy.millis() > 999 || accuracy.micros() > 999 {
32            return Err(InvalidPolicyAccuracy);
33        }
34        Ok(Self { policy, accuracy })
35    }
36    /// Identifier whose equality the checker requires, even if the token
37    /// already declares accuracy and therefore takes precedence.
38    #[must_use]
39    pub const fn policy(self) -> Oid<'a> {
40        self.policy
41    }
42    /// Explicit trusted deviation; no signature or trust verdict is implied.
43    #[must_use]
44    pub const fn accuracy(self) -> Accuracy {
45        self.accuracy
46    }
47}
48
49/// Effective deviation with its original source kept explicit.
50#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub enum EffectiveAccuracy {
52    /// Accuracy declared in the signed `TSTInfo`.
53    Token(Accuracy),
54    /// Accuracy supplied by the caller for the matching signed TSA policy.
55    CallerPolicy(Accuracy),
56}
57impl EffectiveAccuracy {
58    /// Deviation to use for generation interval arithmetic.
59    #[must_use]
60    pub const fn accuracy(self) -> Accuracy {
61        match self {
62            Self::Token(value) | Self::CallerPolicy(value) => value,
63        }
64    }
65}