tor_netdoc/parse2/poc/netstatus/
flavoured.rs1use super::super::*;
15
16const TOPLEVEL_DOCTYPE_FOR_ERROR: &str =
18 ns_expr!("NetworkStatusVote", "NetworkStatusNs", "NetworkStatusMd",);
19
20pub type Router = ns_type!(
22 crate::doc::netstatus::VoteRouterStatus,
23 crate::doc::netstatus::PlainRouterStatus,
24 crate::doc::netstatus::MdRouterStatus,
25);
26
27pub type NddDirectoryFooter = ns_type!(
29 crate::doc::netstatus::VoteFooter,
30 crate::doc::netstatus::PlainFooter,
31 crate::doc::netstatus::MdFooter,
32);
33
34pub type NetworkStatusSignatures = ns_type!(
36 crate::doc::netstatus::vote::NetworkStatusSignatures,
37 crate::doc::netstatus::plain::NetworkStatusSignatures,
38 crate::doc::netstatus::md::NetworkStatusSignatures,
39);
40
41pub type NetworkStatusVersionItem = ns_type!(
43 crate::doc::netstatus::vote::NetworkStatusVersionItem,
44 crate::doc::netstatus::plain::NetworkStatusVersionItem,
45 crate::doc::netstatus::md::NetworkStatusVersionItem,
46);
47
48#[derive(Deftly, Clone, Debug)]
53#[derive_deftly(NetdocParseableUnverified)]
54#[deftly(netdoc(doctype_for_error = TOPLEVEL_DOCTYPE_FOR_ERROR))]
55#[non_exhaustive]
56pub struct NetworkStatus {
57 pub network_status_version: NetworkStatusVersionItem,
59
60 pub vote_status: NdiVoteStatus,
62
63 pub published: ns_type!((NdaSystemTimeDeprecatedSyntax,), Option<Void>,),
65
66 pub valid_after: (NdaSystemTimeDeprecatedSyntax,),
68
69 pub valid_until: (NdaSystemTimeDeprecatedSyntax,),
71
72 pub voting_delay: NdiVotingDelay,
74
75 #[deftly(netdoc(default))]
77 pub params: NdiParams,
78
79 #[deftly(netdoc(subdoc))]
81 pub authority: NddAuthoritySection,
82
83 #[deftly(netdoc(subdoc))]
85 pub r: Vec<Router>,
86
87 #[deftly(netdoc(subdoc))]
89 pub directory_footer: Option<NddDirectoryFooter>,
90}
91
92#[derive(Deftly, Clone, Debug, Hash, Eq, PartialEq)]
98#[derive_deftly(ItemValueParseable)]
99#[non_exhaustive]
100pub struct NdiVoteStatus {
101 pub status: ns_type!(VoteStatusVote, VoteStatusConsensus, VoteStatusConsensus),
103}
104
105#[derive(Deftly, Clone, Debug, Hash, Eq, PartialEq)]
107#[derive_deftly(ItemValueParseable)]
108#[non_exhaustive]
109pub struct NdiVotingDelay {
110 pub vote_seconds: u32,
112 pub dist_seconds: u32,
114}
115
116#[derive(Deftly, Clone, Debug)]
118#[derive_deftly(ItemValueParseable)]
119#[non_exhaustive]
120pub struct NdiAuthorityDirSource {
121 pub nickname: types::Nickname,
123 pub h_p_auth_id_rsa: types::Fingerprint,
125}
126
127ns_choose! { (
128 use VoteAuthoritySection as NddAuthoritySection;
129)(
130 use ConsensusAuthoritySection as NddAuthoritySection;
131)}
132
133ns_choose! { (
134 impl NetworkStatusUnverified {
135 pub fn verify_selfcert(
142 self,
143 now: SystemTime,
144 ) -> Result<(NetworkStatus, SignaturesData<NetworkStatusUnverified>), VF> {
145 let validity = *self.body.published.0 ..= *self.body.valid_until.0;
146 check_validity_time(now, validity)?;
147
148 let cert = self.body.parse_authcert()?.verify_selfcert(now)?;
149
150 netstatus::verify_general_timeless(
151 &self.sigs.hashes,
152 slice::from_ref(&self.sigs.sigs.directory_signature),
153 &[*cert.fingerprint],
154 &[&cert],
155 )?;
156
157 Ok(self.unwrap_unverified())
158 }
159 }
160
161 impl NetworkStatus {
162 fn parse_authcert(&self) -> Result<crate::doc::authcert::AuthCertUnverified, EP> {
166 let cert_input = ParseInput::new(
167 self.authority.cert.raw_unverified().as_str(),
168 "<embedded auth cert>",
169 );
170 parse_netdoc(&cert_input).map_err(|e| e.problem)
171 }
172
173 pub fn h_kp_auth_id_rsa(&self) -> pk::rsa::RsaIdentity {
185 *self.parse_authcert()
186 .expect("was verified already!")
190 .inspect_unverified()
191 .0
192 .fingerprint
193 }
194 }
195) (
196 impl NetworkStatusUnverified {
197 pub fn verify(
213 self,
214 now: SystemTime,
215 authorities: &[pk::rsa::RsaIdentity],
216 certs: &[&DirAuthKeyCert],
217 ) -> Result<(NetworkStatus, SignaturesData<NetworkStatusUnverified>), VF> {
218 let validity_start = self.body.valid_after.0
219 .checked_sub(Duration::from_secs(self.body.voting_delay.dist_seconds.into()))
220 .ok_or(VF::Other)?;
221 check_validity_time(now, validity_start..= *self.body.valid_until.0)?;
222
223 netstatus::verify_general_timeless(
224 &self.sigs.hashes,
225 &self.sigs.sigs.directory_signature,
226 authorities,
227 certs,
228 )?;
229
230 Ok(self.unwrap_unverified())
231 }
232 }
233)}