1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt::{self, Debug};
4use core::ops::{Deref, DerefMut};
5
6use kernel::KernelConnection;
7use pki_types::FipsStatus;
8
9use crate::common_state::{
10 CommonState, ConnectionOutput, ConnectionOutputs, Event, Output, OutputEvent,
11};
12use crate::crypto::cipher::{OutboundPlain, Payload};
13use crate::error::{ApiMisuse, Error};
14use crate::kernel::KernelState;
15use crate::msgs::{Delocator, Message, Random, ServerExtensionsInput};
16use crate::quic::QuicOutput;
17use crate::server::{ChooseConfig, ServerConfig, ServerSide};
18use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
19use crate::sync::Arc;
20use crate::tls13::key_schedule::KeyScheduleTrafficSend;
21
22pub mod kernel;
24
25mod receive;
26pub(crate) use receive::{Input, MessageIter, ReceivePath, TrafficTemperCounters};
27pub use receive::{SliceInput, TlsInputBuffer, VecInput};
28
29mod send;
30pub(crate) use send::{SendOutput, SendPath};
31
32pub(crate) mod split;
33use split::SplitConnection;
34
35pub trait Connection: Debug + Deref<Target = ConnectionOutputs> {
37 type Side: SideData;
39
40 fn write_tls(&mut self, plaintext: OutboundPlain<'_>, tls: &mut Vec<u8>) -> Result<(), Error>;
46
47 fn wants_read(&self) -> bool;
49
50 fn process_new_packets<'a, 'm>(
52 &'a mut self,
53 input: &'m mut dyn TlsInputBuffer,
54 tls: &'a mut Vec<u8>,
55 ) -> MessageHandler<'a, 'm, Self::Side>;
56
57 fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error>;
71
72 fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error>;
76
77 fn refresh_traffic_keys(&mut self, tls: &mut Vec<u8>) -> Result<(), Error>;
103
104 fn send_close_notify(&mut self, tls: &mut Vec<u8>);
110
111 fn is_handshaking(&self) -> bool;
115
116 fn fips(&self) -> FipsStatus;
124}
125
126pub(crate) struct ConnectionCommon<Side: SideData> {
137 pub(crate) state: Result<Side::State, Error>,
138 pub(crate) side: Side::Data,
139 pub(crate) common: CommonState,
140}
141
142impl<Side: SideData> ConnectionCommon<Side> {
143 pub(crate) fn new(state: Side::State, side: Side::Data, common: CommonState) -> Self {
144 Self {
145 state: Ok(state),
146 side,
147 common,
148 }
149 }
150
151 pub(crate) fn process_new_packets<'a, 'm>(
152 &'a mut self,
153 input: &'m mut dyn TlsInputBuffer,
154 tls: &'a mut Vec<u8>,
155 ) -> MessageHandler<'a, 'm, Side> {
156 MessageHandler::new(input, tls, self)
157 }
158
159 pub(crate) fn write_tls(
160 &mut self,
161 plaintext: OutboundPlain<'_>,
162 tls: &mut Vec<u8>,
163 ) -> Result<(), Error> {
164 if plaintext.is_empty() {
165 return Ok(());
166 } else if !self
167 .common
168 .send
169 .may_send_application_data
170 {
171 return Err(ApiMisuse::WriteTlsBeforeHandshakeComplete.into());
172 } else if self.common.send.has_sent_close_notify {
173 return Err(ApiMisuse::WriteTlsAfterSendPathClosed.into());
174 }
175
176 self.common
177 .send
178 .send_appdata_encrypt(plaintext, tls);
179
180 Ok(())
181 }
182
183 pub(crate) fn wants_read(&self) -> bool {
184 !self
187 .common
188 .recv
189 .has_received_close_notify
190 }
191
192 pub(crate) fn refresh_traffic_keys(&mut self, tls: &mut Vec<u8>) -> Result<(), Error> {
193 self.common
194 .send
195 .refresh_traffic_keys(tls)
196 }
197
198 pub(crate) fn split(self) -> Result<SplitConnection<Side>, Error> {
199 if self.is_handshaking() {
201 return Err(ApiMisuse::SplitDuringHandshake.into());
202 }
203
204 SplitConnection::try_from(self)
205 }
206
207 pub(crate) fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
210 Ok(self
211 .dangerous_into_kernel_connection()?
212 .0)
213 }
214
215 pub(crate) fn dangerous_into_kernel_connection(
216 mut self,
217 ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
218 if self.common.is_handshaking() {
219 return Err(Error::HandshakeNotComplete);
220 }
221 Self::from_parts_into_kernel_connection(
222 &mut self.common.send,
223 self.common.recv,
224 self.common.outputs,
225 self.state?,
226 )
227 }
228
229 pub(crate) fn from_parts_into_kernel_connection(
230 send: &mut SendPath,
231 recv: ReceivePath,
232 outputs: ConnectionOutputs,
233 state: Side::State,
234 ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
235 let read_seq = recv.decrypt_state.read_seq();
236 let write_seq = send.encrypt_state.write_seq();
237
238 let tls13_key_schedule = send.tls13_key_schedule.take();
239
240 let (secrets, state) = state.into_external_state(&tls13_key_schedule)?;
241 let secrets = ExtractedSecrets {
242 tx: (write_seq, secrets.tx),
243 rx: (read_seq, secrets.rx),
244 };
245 let external = KernelConnection::new(state, outputs, tls13_key_schedule)?;
246
247 Ok((secrets, external))
248 }
249
250 pub(crate) fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
251 match self.common.exporter.take() {
252 Some(inner) => Ok(KeyingMaterialExporter { inner }),
253 None if self.common.is_handshaking() => Err(Error::HandshakeNotComplete),
254 None => Err(ApiMisuse::ExporterAlreadyUsed.into()),
255 }
256 }
257}
258
259impl ConnectionCommon<ServerSide> {
260 pub(crate) fn accepted(
261 &mut self,
262 choose: Box<ChooseConfig>,
263 exts: ServerExtensionsInput,
264 quic: Option<&mut dyn QuicOutput>,
265 config: Arc<ServerConfig>,
266 tls: &mut Vec<u8>,
267 ) -> Result<(), Error> {
268 self.common
269 .send
270 .set_max_fragment_size(config.max_fragment_size)?;
271 self.common.fips = config.fips();
272
273 let mut output = SideCommonOutput {
274 side: &mut self.side,
275 quic,
276 common: &mut self.common,
277 tls,
278 };
279
280 self.state = Ok(choose.use_config(config, exts, &mut output)?);
281 Ok(())
282 }
283}
284
285impl<Side: SideData> Deref for ConnectionCommon<Side> {
286 type Target = CommonState;
287
288 fn deref(&self) -> &Self::Target {
289 &self.common
290 }
291}
292
293impl<Side: SideData> DerefMut for ConnectionCommon<Side> {
294 fn deref_mut(&mut self) -> &mut Self::Target {
295 &mut self.common
296 }
297}
298
299#[must_use]
307pub struct MessageHandler<'a, 'm, Side: SideData> {
308 iter: MessageIter<'a, 'm, Side, SendPath>,
309 done: bool,
310}
311
312impl<'a, 'm, Side: SideData> MessageHandler<'a, 'm, Side> {
313 pub(crate) fn new(
314 input: &'m mut dyn TlsInputBuffer,
315 tls: &'a mut Vec<u8>,
316 core: &'a mut ConnectionCommon<Side>,
317 ) -> Self {
318 Self {
319 iter: MessageIter::new(input, tls, None, core),
320 done: false,
321 }
322 }
323}
324
325impl<'a, 'm, Side: SideData> MessageHandler<'a, 'm, Side> {
326 pub fn handle_all(mut self, buf: &mut Vec<u8>) -> Result<IoState, Error> {
338 while let Some(result) = self.next_payload() {
339 buf.extend_from_slice(result?.bytes());
340 }
341
342 Ok(self.state())
343 }
344
345 pub fn next_payload(&mut self) -> Option<Result<Payload<'_>, Error>> {
350 if self.done {
351 return None;
352 }
353
354 let Some(result) = self.iter.next() else {
355 self.done = true;
356 return None;
357 };
358
359 let payload = match result {
360 Ok(payload) => payload,
361 Err(err) => {
362 self.done = true;
363 return Some(Err(err));
364 }
365 };
366
367 Some(Ok(
368 payload.reborrow(&Delocator::new(self.iter.input.slice_mut()))
369 ))
370 }
371
372 pub fn state(self) -> IoState {
374 IoState::new(self.iter.recv)
375 }
376}
377
378impl<'a, 'm, Side: SideData + private::Side> Drop for MessageHandler<'a, 'm, Side> {
379 fn drop(&mut self) {
380 let MessageIter { input, recv, .. } = &mut self.iter;
381 input.discard(recv.deframer.take_discard());
382 }
383}
384
385impl<S: SideData> Debug for MessageHandler<'_, '_, S> {
386 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
387 f.debug_struct("MessageHandler")
388 .field("done", &self.done)
389 .finish_non_exhaustive()
390 }
391}
392
393pub struct KeyingMaterialExporter {
395 pub(crate) inner: Box<dyn Exporter>,
396}
397
398impl KeyingMaterialExporter {
399 pub fn derive<T: AsMut<[u8]>>(
416 &self,
417 label: &[u8],
418 context: Option<&[u8]>,
419 mut output: T,
420 ) -> Result<T, Error> {
421 if output.as_mut().is_empty() {
422 return Err(ApiMisuse::ExporterOutputZeroLength.into());
423 }
424
425 self.inner
426 .derive(label, context, output.as_mut())
427 .map(|_| output)
428 }
429}
430
431impl Debug for KeyingMaterialExporter {
432 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
433 f.debug_struct("KeyingMaterialExporter")
434 .finish_non_exhaustive()
435 }
436}
437
438pub(crate) trait Exporter: Send + Sync {
449 fn derive(&self, label: &[u8], context: Option<&[u8]>, output: &mut [u8]) -> Result<(), Error>;
456}
457
458#[derive(Debug)]
459pub(crate) struct ConnectionRandoms {
460 pub(crate) client: [u8; 32],
461 pub(crate) server: [u8; 32],
462}
463
464impl ConnectionRandoms {
465 pub(crate) fn new(client: Random, server: Random) -> Self {
466 Self {
467 client: client.0,
468 server: server.0,
469 }
470 }
471}
472
473#[derive(Debug, Eq, PartialEq)]
476pub struct IoState {
477 peer_has_closed: bool,
478}
479
480impl IoState {
481 pub(crate) fn new(recv: &ReceivePath) -> Self {
482 Self {
483 peer_has_closed: recv.has_received_close_notify,
484 }
485 }
486
487 pub fn peer_has_closed(&self) -> bool {
495 self.peer_has_closed
496 }
497}
498
499pub(crate) struct SideCommonOutput<'a, 'q> {
500 pub(crate) side: &'a mut dyn SideOutput,
501 pub(crate) quic: Option<&'q mut dyn QuicOutput>,
502 pub(crate) common: &'a mut CommonState,
503 pub(crate) tls: &'a mut Vec<u8>,
504}
505
506impl<'q> Output<'_> for SideCommonOutput<'_, 'q> {
507 fn emit(&mut self, ev: Event<'_>) {
508 self.side.emit(ev);
509 }
510
511 fn output(&mut self, ev: OutputEvent<'_>) {
512 if let OutputEvent::ProtocolVersion(ver) = ev {
513 self.common.recv.negotiated_version = Some(ver);
514 self.common.send.negotiated_version(ver);
515 }
516 self.common.outputs.handle(ev);
517 }
518
519 fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) {
520 match self.quic() {
521 Some(quic) => quic.send_msg(m, must_encrypt),
522 None => self
523 .common
524 .send
525 .send_msg(m, must_encrypt, self.tls),
526 }
527 }
528
529 fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
530 match self.quic.as_mut() {
531 Some(q) => Some(&mut **q),
532 None => None,
533 }
534 }
535
536 fn start_traffic(&mut self) {
537 self.common
538 .recv
539 .may_receive_application_data = true;
540 self.common
541 .send
542 .start_outgoing_traffic();
543 }
544
545 fn receive(&mut self) -> &mut ReceivePath {
546 &mut self.common.recv
547 }
548
549 fn send(&mut self) -> &mut dyn SendOutput {
550 &mut self.common.send
551 }
552}
553
554#[expect(private_bounds)]
556pub trait SideData: private::Side {}
557
558pub(crate) mod private {
559 use super::*;
560
561 pub(crate) trait Side: Debug {
562 type Data: SideOutput;
564 type State: StateMachine;
566 }
567
568 pub(crate) trait SideOutput {
569 fn emit(&mut self, ev: Event<'_>);
570 }
571}
572
573use private::SideOutput;
574
575pub(crate) trait StateMachine: Sized {
576 fn handle<'m>(self, input: Input<'m>, output: &mut dyn Output<'m>) -> Result<Self, Error>;
577 fn wants_input(&self) -> bool;
578 fn is_traffic(&self) -> bool;
579 fn handle_decrypt_error(&mut self);
580 fn into_external_state(
581 self,
582 send_keys: &Option<Box<KeyScheduleTrafficSend>>,
583 ) -> Result<(PartiallyExtractedSecrets, Box<dyn KernelState + 'static>), Error>;
584}