Skip to main content

structured_pkix/ocsp/
freshness.rs

1//! Update-window facts; maximum age and clock tolerance remain caller policy.
2
3use super::SingleResponse;
4use crate::crl::{Freshness, update_window};
5use crate::temporal::{LeapTable, Reading, Uncertainty};
6use structured_asn1::memory::Work;
7
8/// The current UTC label's relation to one assertion's update window.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum UpdateWindow {
11    /// In [thisUpdate, nextUpdate), without claiming sufficient maximum age.
12    Within,
13    /// Current label precedes thisUpdate.
14    NotYetCurrent,
15    /// nextUpdate is at or before the current label; OCSP's endpoint is strict.
16    Stale,
17    /// No nextUpdate: no expiry or default TTL is invented. The responder may
18    /// have newer information continuously (RFC6960 §4.2.2.1).
19    NoNextUpdate,
20    /// The asserted update interval is empty or inverted.
21    InvalidUpdateOrder,
22    /// UTC correction evidence cannot establish a compared label.
23    Uncertain(Uncertainty),
24}
25
26impl SingleResponse<'_> {
27    /// Compare update labels using explicit UTC facts and the current account.
28    /// RFC6960 §3.2(5) leaves "sufficiently recent" to the client's acceptance
29    /// criteria; §3.2(6) requires nextUpdate, when present, greater than now.
30    /// This result never supplies a maximum age, clock or clock-skew allowance.
31    /// <https://www.rfc-editor.org/rfc/rfc6960#section-3.2>
32    pub fn update_window<W: Work>(
33        &self,
34        now: Reading,
35        utc: &LeapTable<'_>,
36        execution: &W,
37    ) -> crate::Result<UpdateWindow> {
38        Ok(
39            match update_window(
40                self.this_update,
41                self.next_update,
42                now,
43                utc,
44                execution,
45                ("ocspResponse.singleResponse.updateWindow", self.span.start),
46            )? {
47                Freshness::Current => UpdateWindow::Within,
48                Freshness::AtNextUpdate | Freshness::Stale => UpdateWindow::Stale,
49                Freshness::NotYetCurrent => UpdateWindow::NotYetCurrent,
50                Freshness::MissingNextUpdate => UpdateWindow::NoNextUpdate,
51                Freshness::InvalidUpdateOrder => UpdateWindow::InvalidUpdateOrder,
52                Freshness::Uncertain(reason) => UpdateWindow::Uncertain(reason),
53            },
54        )
55    }
56}