fips_core/peer/active/
rekey.rs1use super::*;
2
3impl ActivePeer {
4 pub fn session_established_at(&self) -> Instant {
8 self.session_established_at
9 }
10
11 #[cfg(test)]
12 pub(crate) fn set_session_established_at_for_test(&mut self, instant: Instant) {
13 self.session_established_at = instant;
14 }
15
16 pub fn rekey_jitter_secs(&self) -> i64 {
18 self.rekey_jitter_secs
19 }
20
21 pub fn current_k_bit(&self) -> bool {
23 self.current_k_bit
24 }
25
26 pub fn rekey_in_progress(&self) -> bool {
28 self.rekey_in_progress
29 }
30
31 pub fn set_rekey_in_progress(&mut self) {
33 self.rekey_in_progress = true;
34 }
35
36 pub fn is_rekey_dampened(&self, dampening_secs: u64) -> bool {
38 match self.last_peer_rekey {
39 Some(t) => t.elapsed().as_secs() < dampening_secs,
40 None => false,
41 }
42 }
43
44 pub fn record_peer_rekey(&mut self) {
46 self.last_peer_rekey = Some(Instant::now());
47 }
48
49 pub fn pending_our_index(&self) -> Option<SessionIndex> {
51 self.pending_our_index
52 }
53
54 pub fn pending_their_index(&self) -> Option<SessionIndex> {
56 self.pending_their_index
57 }
58
59 pub fn previous_our_index(&self) -> Option<SessionIndex> {
61 self.previous_our_index
62 }
63
64 pub fn previous_session(&self) -> Option<&NoiseSession> {
66 self.previous_session.as_ref()
67 }
68
69 pub fn previous_session_mut(&mut self) -> Option<&mut NoiseSession> {
71 self.previous_session.as_mut()
72 }
73
74 pub fn pending_new_session(&self) -> Option<&NoiseSession> {
76 self.pending_new_session.as_ref()
77 }
78
79 pub fn pending_rekey_initiator(&self) -> bool {
81 self.pending_rekey_initiator
82 }
83
84 pub fn pending_rekey_cutover_due(&self, delay: Duration) -> bool {
87 self.pending_rekey_initiator
88 && self
89 .pending_rekey_completed_at
90 .is_some_and(|completed| completed.elapsed() >= delay)
91 }
92
93 pub fn set_pending_session(
99 &mut self,
100 session: NoiseSession,
101 our_index: SessionIndex,
102 their_index: SessionIndex,
103 initiated_by_local: bool,
104 ) {
105 self.pending_new_session = Some(session);
106 self.pending_our_index = Some(our_index);
107 self.pending_their_index = Some(their_index);
108 self.pending_rekey_initiator = initiated_by_local;
109 self.pending_rekey_completed_at = Some(Instant::now());
110 self.rekey_in_progress = false;
111 self.rekey_our_index = None;
113 self.rekey_handshake = None;
114 self.rekey_msg1 = None;
115 self.rekey_msg1_next_resend = 0;
116 self.rekey_msg1_resend_count = 0;
117 }
118
119 pub fn cutover_to_new_session(&mut self) -> Option<SessionIndex> {
125 let new_session = self.pending_new_session.take()?;
126 let new_our_index = self.pending_our_index.take();
127 let new_their_index = self.pending_their_index.take();
128
129 self.previous_session = self.noise_session.take();
131 self.previous_our_index = self.our_index;
132 self.drain_started = Some(Instant::now());
133
134 self.noise_session = Some(new_session);
136 self.our_index = new_our_index;
137 self.their_index = new_their_index;
138 self.pending_rekey_initiator = false;
139 self.pending_rekey_completed_at = None;
140
141 self.current_k_bit = !self.current_k_bit;
143 self.session_established_at = Instant::now();
144 self.session_start = Instant::now();
145 self.session_generation = self.session_generation.wrapping_add(1).max(1);
146 self.rekey_in_progress = false;
147 self.rekey_msg1_resend_count = 0;
148 self.rekey_jitter_secs = draw_rekey_jitter();
149 self.last_heartbeat_sent = None;
150 self.reset_replay_suppressed();
151
152 self.previous_our_index
153 }
154
155 pub fn handle_peer_kbit_flip(&mut self) -> Option<SessionIndex> {
160 let new_session = self.pending_new_session.take()?;
161 let new_our_index = self.pending_our_index.take();
162 let new_their_index = self.pending_their_index.take();
163
164 self.previous_session = self.noise_session.take();
166 self.previous_our_index = self.our_index;
167 self.drain_started = Some(Instant::now());
168
169 self.noise_session = Some(new_session);
171 self.our_index = new_our_index;
172 self.their_index = new_their_index;
173 self.pending_rekey_initiator = false;
174 self.pending_rekey_completed_at = None;
175
176 self.current_k_bit = !self.current_k_bit;
178 self.session_established_at = Instant::now();
179 self.session_start = Instant::now();
180 self.session_generation = self.session_generation.wrapping_add(1).max(1);
181 self.rekey_in_progress = false;
182 self.rekey_msg1_resend_count = 0;
183 self.rekey_jitter_secs = draw_rekey_jitter();
184 self.last_heartbeat_sent = None;
185 self.reset_replay_suppressed();
186
187 self.previous_our_index
188 }
189
190 pub fn drain_expired(&self, drain_secs: u64) -> bool {
192 match self.drain_started {
193 Some(t) => t.elapsed().as_secs() >= drain_secs,
194 None => false,
195 }
196 }
197
198 pub fn is_draining(&self) -> bool {
200 self.drain_started.is_some()
201 }
202
203 pub fn complete_drain(&mut self) -> Option<SessionIndex> {
208 self.previous_session = None;
209 self.drain_started = None;
210 self.previous_our_index.take()
211 }
212
213 pub fn abandon_rekey(&mut self) -> Option<SessionIndex> {
219 self.rekey_handshake = None;
220 self.rekey_msg1 = None;
221 self.rekey_msg1_next_resend = 0;
222 self.rekey_msg1_resend_count = 0;
223 self.rekey_in_progress = false;
224 self.rekey_our_index.take().or_else(|| {
226 self.pending_new_session = None;
227 self.pending_their_index = None;
228 self.pending_rekey_initiator = false;
229 self.pending_rekey_completed_at = None;
230 self.pending_our_index.take()
231 })
232 }
233
234 pub fn set_rekey_state(
238 &mut self,
239 handshake: NoiseHandshakeState,
240 our_index: SessionIndex,
241 wire_msg1: Vec<u8>,
242 next_resend_ms: u64,
243 ) {
244 self.rekey_handshake = Some(handshake);
245 self.rekey_our_index = Some(our_index);
246 self.rekey_msg1 = Some(wire_msg1);
247 self.rekey_msg1_next_resend = next_resend_ms;
248 self.rekey_msg1_resend_count = 0;
249 self.rekey_in_progress = true;
250 }
251
252 pub fn rekey_our_index(&self) -> Option<SessionIndex> {
254 self.rekey_our_index
255 }
256
257 pub fn complete_rekey_msg2(
263 &mut self,
264 msg2_bytes: &[u8],
265 ) -> Result<(NoiseSession, Option<[u8; 8]>), NoiseError> {
266 let mut hs = self
267 .rekey_handshake
268 .take()
269 .ok_or_else(|| NoiseError::WrongState {
270 expected: "rekey handshake in progress".to_string(),
271 got: "no handshake state".to_string(),
272 })?;
273
274 hs.read_message_2(msg2_bytes)?;
275 let remote_epoch = hs.remote_epoch();
276 let session = hs.into_session()?;
277
278 self.rekey_msg1 = None;
280 self.rekey_msg1_next_resend = 0;
281 self.rekey_msg1_resend_count = 0;
282
283 Ok((session, remote_epoch))
284 }
285
286 pub fn needs_msg1_resend(&self, now_ms: u64) -> bool {
288 self.rekey_in_progress && self.rekey_msg1.is_some() && now_ms >= self.rekey_msg1_next_resend
289 }
290
291 pub fn rekey_msg1(&self) -> Option<&[u8]> {
293 self.rekey_msg1.as_deref()
294 }
295
296 pub fn set_msg1_next_resend(&mut self, next_ms: u64) {
298 self.rekey_msg1_next_resend = next_ms;
299 }
300
301 pub fn rekey_msg1_resend_count(&self) -> u32 {
303 self.rekey_msg1_resend_count
304 }
305
306 pub fn record_rekey_msg1_resend(&mut self, next_ms: u64) {
308 self.rekey_msg1_resend_count = self.rekey_msg1_resend_count.saturating_add(1);
309 self.rekey_msg1_next_resend = next_ms;
310 }
311}