tor_dirmgr/
docmeta.rs

1//! Types to describe information about other downloaded directory
2//! documents, without necessarily having the full document.
3//!
4//! These types are all local within tor-dirmgr.  They're used so that
5//! the storage code doesn't need to know about all of the parsed
6//! types from tor-netdoc.
7
8use digest::Digest;
9use tor_llcrypto as ll;
10use tor_netdoc::doc::{
11    authcert::{AuthCert, AuthCertKeyIds},
12    netstatus::{Lifetime, MdConsensus, UnvalidatedMdConsensus},
13};
14
15use std::time::SystemTime;
16
17/// Information about a consensus that we have in storage.
18///
19/// This information is ordinarily derived from the consensus, but doesn't
20/// have to be.
21#[derive(Debug, Clone)]
22pub(crate) struct ConsensusMeta {
23    /// The time over which the consensus is valid.
24    lifetime: Lifetime,
25    /// A sha3-256 digest of the signed portion of the consensus: used for
26    /// fetching diffs.
27    sha3_256_of_signed: [u8; 32],
28    /// A sha3-256 digest of the entirety of the consensus: used for
29    /// naming the file.
30    sha3_256_of_whole: [u8; 32],
31}
32
33impl ConsensusMeta {
34    /// Create a new ConsensusMeta
35    pub(crate) fn new(
36        lifetime: Lifetime,
37        sha3_256_of_signed: [u8; 32],
38        sha3_256_of_whole: [u8; 32],
39    ) -> Self {
40        ConsensusMeta {
41            lifetime,
42            sha3_256_of_signed,
43            sha3_256_of_whole,
44        }
45    }
46    /// Derive a new ConsensusMeta from an UnvalidatedMdConsensus and the
47    /// text of its signed portion.
48    pub(crate) fn from_unvalidated(
49        signed_part: &str,
50        remainder: &str,
51        con: &UnvalidatedMdConsensus,
52    ) -> Self {
53        let lifetime = con.peek_lifetime().clone();
54        let (sd, wd) = sha3_dual(signed_part, remainder);
55        ConsensusMeta::new(lifetime, sd, wd)
56    }
57    /// Derive a new ConsensusMeta from a MdConsensus and the text of its
58    /// signed portion.
59    #[allow(unused)]
60    pub(crate) fn from_consensus(signed_part: &str, remainder: &str, con: &MdConsensus) -> Self {
61        let lifetime = con.lifetime().clone();
62        let (sd, wd) = sha3_dual(signed_part, remainder);
63        ConsensusMeta::new(lifetime, sd, wd)
64    }
65    /// Return the lifetime of this ConsensusMeta
66    pub(crate) fn lifetime(&self) -> &Lifetime {
67        &self.lifetime
68    }
69    /// Return the sha3-256 of the signed portion of this consensus.
70    pub(crate) fn sha3_256_of_signed(&self) -> &[u8; 32] {
71        &self.sha3_256_of_signed
72    }
73    /// Return the sha3-256 of the entirety of this consensus.
74    pub(crate) fn sha3_256_of_whole(&self) -> &[u8; 32] {
75        &self.sha3_256_of_whole
76    }
77}
78
79/// Compute the sha3-256 digests of signed_part on its own, and of
80/// signed_part concatenated with remainder.
81fn sha3_dual(signed_part: impl AsRef<[u8]>, remainder: impl AsRef<[u8]>) -> ([u8; 32], [u8; 32]) {
82    let mut d = ll::d::Sha3_256::new();
83    d.update(signed_part.as_ref());
84    let sha3_of_signed = d.clone().finalize().into();
85    d.update(remainder.as_ref());
86    let sha3_of_whole = d.finalize().into();
87    (sha3_of_signed, sha3_of_whole)
88}
89
90/// Information about an authority certificate that we have in storage.
91///
92/// This information is ordinarily derived from the authority cert, but it
93/// doesn't have to be.
94#[derive(Clone, Debug)]
95pub(crate) struct AuthCertMeta {
96    /// Key IDs (identity and signing) for the certificate.
97    ids: AuthCertKeyIds,
98    /// Time of publication.
99    published: SystemTime,
100    /// Expiration time.
101    expires: SystemTime,
102}
103
104impl AuthCertMeta {
105    /// Construct a new AuthCertMeta from its components
106    pub(crate) fn new(ids: AuthCertKeyIds, published: SystemTime, expires: SystemTime) -> Self {
107        AuthCertMeta {
108            ids,
109            published,
110            expires,
111        }
112    }
113
114    /// Construct a new AuthCertMeta from a certificate.
115    pub(crate) fn from_authcert(cert: &AuthCert) -> Self {
116        AuthCertMeta::new(*cert.key_ids(), cert.published(), cert.expires())
117    }
118
119    /// Return the key IDs for this certificate
120    pub(crate) fn key_ids(&self) -> &AuthCertKeyIds {
121        &self.ids
122    }
123    /// Return the published time for this certificate
124    pub(crate) fn published(&self) -> SystemTime {
125        self.published
126    }
127    /// Return the expiration time for this certificate
128    pub(crate) fn expires(&self) -> SystemTime {
129        self.expires
130    }
131}
132
133#[cfg(test)]
134mod test {
135    // @@ begin test lint list maintained by maint/add_warning @@
136    #![allow(clippy::bool_assert_comparison)]
137    #![allow(clippy::clone_on_copy)]
138    #![allow(clippy::dbg_macro)]
139    #![allow(clippy::mixed_attributes_style)]
140    #![allow(clippy::print_stderr)]
141    #![allow(clippy::print_stdout)]
142    #![allow(clippy::single_char_pattern)]
143    #![allow(clippy::unwrap_used)]
144    #![allow(clippy::unchecked_duration_subtraction)]
145    #![allow(clippy::useless_vec)]
146    #![allow(clippy::needless_pass_by_value)]
147    //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
148    use super::*;
149
150    #[test]
151    fn t_sha3_dual() {
152        let s = b"Loarax ipsum gruvvulus thneed amet, snergelly once-ler lerkim, sed do barbaloot tempor gluppitus ut labore et truffula magna aliqua. Ut enim ad grickle-grass veniam, quis miff-muffered ga-zumpco laboris nisi ut cruffulus ex ea schloppity consequat. Duis aute snarggle in swomeeswans in voluptate axe-hacker esse rippulus crummii eu moof nulla snuvv.";
153
154        let sha3_of_whole: [u8; 32] = ll::d::Sha3_256::digest(s).into();
155
156        for idx in 0..s.len() {
157            let sha3_of_part: [u8; 32] = ll::d::Sha3_256::digest(&s[..idx]).into();
158            let (a, b) = sha3_dual(&s[..idx], &s[idx..]);
159            assert_eq!(a, sha3_of_part);
160            assert_eq!(b, sha3_of_whole);
161        }
162    }
163}