1use alloc::boxed::Box;
11use alloc::vec::Vec;
12use core::{fmt, mem};
13
14use super::{
15 Connection, NeedsInput, SideCommonOutput, SideData, StateMachine, VerifySidePeerIdentity,
16};
17use crate::client::{ClientSide, ClientState};
18use crate::common_state::{Protocol, maybe_send_fatal_alert};
19use crate::crypto::VerifiedIdentity;
20use crate::error::Error;
21use crate::msgs::ServerExtensionsInput;
22use crate::quic::{FromConn, Quic, QuicEvent, QuicOutput};
23use crate::server::{
24 ChooseConfig, ClientHello, ServerConfig, ServerHandshake, ServerSide, ServerState,
25};
26use crate::sync::Arc;
27use crate::tracing::trace;
28
29pub(crate) enum Processed<Side: SideData, T: Transport> {
31 Progress(Connection<Side, T>),
33
34 EarlyData {
36 conn: Connection<Side, T>,
37 data: Vec<u8>,
38 },
39}
40
41impl<Side: SideData, T: Transport> Processed<Side, T> {
42 pub(crate) fn into_progress(self) -> Result<Connection<Side, T>, Error> {
44 match self {
45 Self::Progress(conn) => Ok(conn),
46 Self::EarlyData { .. } => Err(Error::Unreachable("unexpected early data")),
47 }
48 }
49}
50
51pub(crate) enum ServerNext<T: Transport> {
53 NeedsInput(Connection<ServerSide, T>),
54 ChooseConfig(Accepted<T>),
55 VerifyClientIdentity(VerifyPeerIdentity<ServerSide, T>),
56 Complete(Connection<ServerSide, T>),
57}
58
59impl<T: Transport> TryFrom<Connection<ServerSide, T>> for ServerNext<T> {
60 type Error = Error;
61
62 fn try_from(mut conn: Connection<ServerSide, T>) -> Result<Self, Error> {
63 const MISUSED: Error = Error::Unreachable("forgot to restore state");
64
65 Ok(match mem::replace(&mut conn.state, Err(MISUSED))? {
66 ServerState::ChooseConfig(choose_config) => Self::ChooseConfig(Accepted {
67 conn,
68 choose_config,
69 }),
70
71 ServerState::VerifyClientIdentity(verify_identity) => {
72 Self::VerifyClientIdentity(VerifyPeerIdentity {
73 conn,
74 verify_identity,
75 })
76 }
77
78 state if state.is_traffic() => {
79 conn.state = Ok(state);
80 Self::Complete(conn)
81 }
82
83 state => {
84 conn.state = Ok(state);
85 Self::NeedsInput(conn)
86 }
87 })
88 }
89}
90
91pub(crate) enum ClientNext<T: Transport> {
93 NeedsInput(Connection<ClientSide, T>),
94 VerifyServerIdentity(VerifyPeerIdentity<ClientSide, T>),
95 Complete(Connection<ClientSide, T>),
96}
97
98impl<T: Transport> TryFrom<Connection<ClientSide, T>> for ClientNext<T> {
99 type Error = Error;
100
101 fn try_from(mut conn: Connection<ClientSide, T>) -> Result<Self, Error> {
102 const MISUSED: Error = Error::Unreachable("forgot to restore state");
103
104 Ok(match mem::replace(&mut conn.state, Err(MISUSED))? {
105 ClientState::VerifyServerIdentity(verify_identity) => {
106 Self::VerifyServerIdentity(VerifyPeerIdentity {
107 conn,
108 verify_identity,
109 })
110 }
111
112 state if state.is_traffic() => {
113 conn.state = Ok(state);
114 Self::Complete(conn)
115 }
116
117 state => {
118 conn.state = Ok(state);
119 Self::NeedsInput(conn)
120 }
121 })
122 }
123}
124
125pub struct Accepted<T: Transport> {
130 pub(crate) conn: Connection<ServerSide, T>,
132 choose_config: Box<ChooseConfig>,
133}
134
135impl<T: Transport> Accepted<T> {
136 pub fn client_hello(&self) -> ClientHello<'_> {
138 let ch = self.choose_config.client_hello();
139 trace!("Accepted::client_hello(): {ch:#?}");
140 ch
141 }
142
143 pub(crate) fn partial_choose_config(
144 self,
145 config: Arc<ServerConfig>,
146 exts: ServerExtensionsInput,
147 tls: &mut Vec<u8>,
148 ) -> Result<Connection<ServerSide, T>, Error> {
149 let Self {
150 mut conn,
151 choose_config,
152 } = self;
153
154 let result = conn.accepted(choose_config, exts, config, tls);
155
156 let send_path = &mut conn.common.send;
157
158 if let Err(err) = &result {
159 maybe_send_fatal_alert(send_path, err, tls)?;
160 }
161
162 result?;
163 Ok(conn)
164 }
165}
166
167impl Accepted<Tcp> {
168 pub fn choose_config(
175 self,
176 config: Arc<ServerConfig>,
177 tls: &mut Vec<u8>,
178 ) -> Result<ServerHandshake, Error> {
179 Ok(ServerHandshake::NeedsInput(NeedsInput(
180 self.partial_choose_config(config, ServerExtensionsInput::default(), tls)?,
181 )))
182 }
183}
184
185impl<T: Transport> fmt::Debug for Accepted<T> {
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 f.debug_struct("Accepted")
188 .finish_non_exhaustive()
189 }
190}
191
192pub struct VerifyPeerIdentity<Side: SideData, T: Transport> {
225 conn: Connection<Side, T>,
227 verify_identity: Box<dyn VerifySidePeerIdentity<Side>>,
228}
229
230impl<Side: SideData, T: Transport> VerifyPeerIdentity<Side, T> {
231 pub fn presented_identity(&self) -> Result<Side::PeerIdentity<'_>, Error> {
233 self.verify_identity
234 .presented_identity()
235 }
236}
237
238impl<Side: SideData> VerifyPeerIdentity<Side, Tcp> {
239 pub fn with_config(self, tls: &mut Vec<u8>) -> Result<Side::Handshake, Error> {
241 let result = self
242 .verify_identity
243 .verify_with_config();
244 self.continue_with(result, tls)
245 }
246
247 pub fn continue_with(
256 self,
257 verification_result: Result<VerifiedIdentity<'static>, Error>,
258 tls: &mut Vec<u8>,
259 ) -> Result<Side::Handshake, Error> {
260 self.partial_continue_with(verification_result, tls)?
261 .into_handshake()
262 }
263}
264
265impl<Side: SideData> VerifyPeerIdentity<Side, Quic> {
266 pub fn with_config(self, output: &mut Vec<QuicEvent>) -> Result<Side::QuicHandshake, Error> {
268 let result = self
269 .verify_identity
270 .verify_with_config();
271 self.continue_with(result, output)
272 }
273
274 pub fn continue_with(
282 self,
283 verification_result: Result<VerifiedIdentity<'static>, Error>,
284 output: &mut Vec<QuicEvent>,
285 ) -> Result<Side::QuicHandshake, Error> {
286 Side::QuicHandshake::from_conn(
287 self.partial_continue_with(verification_result, &mut Vec::new())?,
288 output,
289 )
290 }
291}
292
293impl<Side: SideData, T: Transport> VerifyPeerIdentity<Side, T> {
294 fn partial_continue_with(
295 self,
296 verification_result: Result<VerifiedIdentity<'static>, Error>,
297 tls: &mut Vec<u8>,
298 ) -> Result<Connection<Side, T>, Error> {
299 let Self {
300 mut conn,
301 verify_identity,
302 } = self;
303
304 let result = verification_result.and_then(|verified| {
305 verify_identity.continue_with(
306 verified,
307 &mut SideCommonOutput {
308 side: &mut conn.side,
309 quic: T::quic(&mut conn.transport),
310 common: &mut conn.common,
311 tls,
312 },
313 )
314 });
315
316 if let Err(err) = &result {
317 maybe_send_fatal_alert(&mut conn.common.send, err, tls)?;
318 }
319
320 conn.state = result;
321 Ok(conn)
322 }
323}
324
325impl<Side: SideData, T: Transport> fmt::Debug for VerifyPeerIdentity<Side, T> {
326 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327 f.debug_struct("VerifyPeerIdentity")
328 .finish_non_exhaustive()
329 }
330}
331
332#[expect(private_bounds)]
334pub trait Transport: Sized + sealed::Transport {}
335
336pub(crate) mod sealed {
337 use super::QuicOutput;
338 use crate::Protocol;
339
340 pub(crate) trait Transport {
341 fn protocol(&self) -> Protocol;
342
343 fn quic(&mut self) -> Option<&mut dyn QuicOutput>;
345 }
346}
347
348#[expect(clippy::exhaustive_structs)]
350pub struct Tcp;
351
352impl Transport for Tcp {}
353
354impl sealed::Transport for Tcp {
355 fn protocol(&self) -> Protocol {
356 Protocol::Tcp
357 }
358
359 fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
360 None
361 }
362}