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 ServerNext<T: Transport> {
31 NeedsInput(Connection<ServerSide, T>),
32 ChooseConfig(Accepted<T>),
33 VerifyClientIdentity(VerifyPeerIdentity<ServerSide, T>),
34 Complete(Connection<ServerSide, T>),
35}
36
37impl<T: Transport> TryFrom<Connection<ServerSide, T>> for ServerNext<T> {
38 type Error = Error;
39
40 fn try_from(mut conn: Connection<ServerSide, T>) -> Result<Self, Error> {
41 const MISUSED: Error = Error::Unreachable("forgot to restore state");
42
43 Ok(match mem::replace(&mut conn.state, Err(MISUSED))? {
44 ServerState::ChooseConfig(choose_config) => Self::ChooseConfig(Accepted {
45 conn,
46 choose_config,
47 }),
48
49 ServerState::VerifyClientIdentity(verify_identity) => {
50 Self::VerifyClientIdentity(VerifyPeerIdentity {
51 conn,
52 verify_identity,
53 })
54 }
55
56 state if state.is_traffic() => {
57 conn.state = Ok(state);
58 Self::Complete(conn)
59 }
60
61 state => {
62 conn.state = Ok(state);
63 Self::NeedsInput(conn)
64 }
65 })
66 }
67}
68
69pub(crate) enum ClientNext<T: Transport> {
71 NeedsInput(Connection<ClientSide, T>),
72 VerifyServerIdentity(VerifyPeerIdentity<ClientSide, T>),
73 Complete(Connection<ClientSide, T>),
74}
75
76impl<T: Transport> TryFrom<Connection<ClientSide, T>> for ClientNext<T> {
77 type Error = Error;
78
79 fn try_from(mut conn: Connection<ClientSide, T>) -> Result<Self, Error> {
80 const MISUSED: Error = Error::Unreachable("forgot to restore state");
81
82 Ok(match mem::replace(&mut conn.state, Err(MISUSED))? {
83 ClientState::VerifyServerIdentity(verify_identity) => {
84 Self::VerifyServerIdentity(VerifyPeerIdentity {
85 conn,
86 verify_identity,
87 })
88 }
89
90 state if state.is_traffic() => {
91 conn.state = Ok(state);
92 Self::Complete(conn)
93 }
94
95 state => {
96 conn.state = Ok(state);
97 Self::NeedsInput(conn)
98 }
99 })
100 }
101}
102
103pub struct Accepted<T: Transport> {
108 pub(crate) conn: Connection<ServerSide, T>,
110 choose_config: Box<ChooseConfig>,
111}
112
113impl<T: Transport> Accepted<T> {
114 pub fn client_hello(&self) -> ClientHello<'_> {
116 let ch = self.choose_config.client_hello();
117 trace!("Accepted::client_hello(): {ch:#?}");
118 ch
119 }
120
121 pub(crate) fn partial_choose_config(
122 self,
123 config: Arc<ServerConfig>,
124 exts: ServerExtensionsInput,
125 tls: &mut Vec<u8>,
126 ) -> Result<Connection<ServerSide, T>, Error> {
127 let Self {
128 mut conn,
129 choose_config,
130 } = self;
131
132 let result = conn.accepted(choose_config, exts, config, tls);
133
134 let send_path = &mut conn.common.send;
135
136 if let Err(err) = &result {
137 maybe_send_fatal_alert(send_path, err, tls)?;
138 }
139
140 result?;
141 Ok(conn)
142 }
143}
144
145impl Accepted<Tcp> {
146 pub fn choose_config(
153 self,
154 config: Arc<ServerConfig>,
155 tls: &mut Vec<u8>,
156 ) -> Result<ServerHandshake, Error> {
157 Ok(ServerHandshake::NeedsInput(NeedsInput(
158 self.partial_choose_config(config, ServerExtensionsInput::default(), tls)?,
159 )))
160 }
161}
162
163impl<T: Transport> fmt::Debug for Accepted<T> {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 f.debug_struct("Accepted")
166 .finish_non_exhaustive()
167 }
168}
169
170pub struct VerifyPeerIdentity<Side: SideData, T: Transport> {
199 conn: Connection<Side, T>,
201 verify_identity: Box<dyn VerifySidePeerIdentity<Side>>,
202}
203
204impl<Side: SideData, T: Transport> VerifyPeerIdentity<Side, T> {
205 pub fn presented_identity(&self) -> Result<Side::PeerIdentity<'_>, Error> {
207 self.verify_identity
208 .presented_identity()
209 }
210}
211
212impl<Side: SideData> VerifyPeerIdentity<Side, Tcp> {
213 pub fn with_config(self, tls: &mut Vec<u8>) -> Result<Side::Handshake, Error> {
215 let result = self
216 .verify_identity
217 .verify_with_config();
218 self.continue_with(result, tls)
219 }
220
221 pub fn continue_with(
228 self,
229 verification_result: Result<VerifiedIdentity<'static>, Error>,
230 tls: &mut Vec<u8>,
231 ) -> Result<Side::Handshake, Error> {
232 self.partial_continue_with(verification_result, tls)?
233 .into_handshake()
234 }
235}
236
237impl<Side: SideData> VerifyPeerIdentity<Side, Quic> {
238 pub fn with_config(self, output: &mut Vec<QuicEvent>) -> Result<Side::QuicHandshake, Error> {
240 let result = self
241 .verify_identity
242 .verify_with_config();
243 self.continue_with(result, output)
244 }
245
246 pub fn continue_with(
252 self,
253 verification_result: Result<VerifiedIdentity<'static>, Error>,
254 output: &mut Vec<QuicEvent>,
255 ) -> Result<Side::QuicHandshake, Error> {
256 Side::QuicHandshake::from_conn(
257 self.partial_continue_with(verification_result, &mut Vec::new())?,
258 output,
259 )
260 }
261}
262
263impl<Side: SideData, T: Transport> VerifyPeerIdentity<Side, T> {
264 fn partial_continue_with(
265 self,
266 verification_result: Result<VerifiedIdentity<'static>, Error>,
267 tls: &mut Vec<u8>,
268 ) -> Result<Connection<Side, T>, Error> {
269 let Self {
270 mut conn,
271 verify_identity,
272 } = self;
273
274 let result = verification_result.and_then(|verified| {
275 verify_identity.continue_with(
276 verified,
277 &mut SideCommonOutput {
278 side: &mut conn.side,
279 quic: T::quic(&mut conn.transport),
280 common: &mut conn.common,
281 tls,
282 },
283 )
284 });
285
286 if let Err(err) = &result {
287 maybe_send_fatal_alert(&mut conn.common.send, err, tls)?;
288 }
289
290 conn.state = result;
291 Ok(conn)
292 }
293}
294
295impl<Side: SideData, T: Transport> fmt::Debug for VerifyPeerIdentity<Side, T> {
296 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
297 f.debug_struct("VerifyPeerIdentity")
298 .finish_non_exhaustive()
299 }
300}
301
302#[expect(private_bounds)]
304pub trait Transport: Sized + sealed::Transport {}
305
306pub(crate) mod sealed {
307 use super::QuicOutput;
308 use crate::Protocol;
309
310 pub(crate) trait Transport {
311 fn protocol(&self) -> Protocol;
312
313 fn quic(&mut self) -> Option<&mut dyn QuicOutput>;
315 }
316}
317
318#[expect(clippy::exhaustive_structs)]
320pub struct Tcp;
321
322impl Transport for Tcp {}
323
324impl sealed::Transport for Tcp {
325 fn protocol(&self) -> Protocol {
326 Protocol::Tcp
327 }
328
329 fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
330 None
331 }
332}