1use 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#[derive(Debug, Clone)]
22pub(crate) struct ConsensusMeta {
23 lifetime: Lifetime,
25 sha3_256_of_signed: [u8; 32],
28 sha3_256_of_whole: [u8; 32],
31}
32
33impl ConsensusMeta {
34 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 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 #[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 pub(crate) fn lifetime(&self) -> &Lifetime {
67 &self.lifetime
68 }
69 pub(crate) fn sha3_256_of_signed(&self) -> &[u8; 32] {
71 &self.sha3_256_of_signed
72 }
73 pub(crate) fn sha3_256_of_whole(&self) -> &[u8; 32] {
75 &self.sha3_256_of_whole
76 }
77}
78
79fn 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#[derive(Clone, Debug)]
95pub(crate) struct AuthCertMeta {
96 ids: AuthCertKeyIds,
98 published: SystemTime,
100 expires: SystemTime,
102}
103
104impl AuthCertMeta {
105 pub(crate) fn new(ids: AuthCertKeyIds, published: SystemTime, expires: SystemTime) -> Self {
107 AuthCertMeta {
108 ids,
109 published,
110 expires,
111 }
112 }
113
114 pub(crate) fn from_authcert(cert: &AuthCert) -> Self {
116 AuthCertMeta::new(*cert.key_ids(), cert.published(), cert.expires())
117 }
118
119 pub(crate) fn key_ids(&self) -> &AuthCertKeyIds {
121 &self.ids
122 }
123 pub(crate) fn published(&self) -> SystemTime {
125 self.published
126 }
127 pub(crate) fn expires(&self) -> SystemTime {
129 self.expires
130 }
131}
132
133#[cfg(test)]
134mod test {
135 #![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 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}