1#[cfg(feature = "std")]
2use alloc::borrow::Cow;
3use alloc::boxed::Box;
4use alloc::vec::Vec;
5use core::fmt;
6use core::fmt::{Debug, Formatter};
7use core::ops::{Deref, DerefMut};
8#[cfg(feature = "std")]
9use std::io;
10
11use pki_types::DnsName;
12
13#[cfg(feature = "std")]
14use super::config::ClientHello;
15use super::config::ServerConfig;
16use super::hs;
17#[cfg(feature = "std")]
18use super::hs::ClientHelloInput;
19#[cfg(feature = "std")]
20use crate::common_state::State;
21use crate::common_state::{CommonState, Side};
22#[cfg(feature = "std")]
23use crate::conn::ConnectionCommon;
24use crate::conn::{ConnectionCore, UnbufferedConnectionCommon};
25#[cfg(doc)]
26use crate::crypto;
27#[cfg(feature = "std")]
28use crate::crypto::SignatureScheme;
29use crate::crypto::cipher::Payload;
30use crate::error::Error;
31use crate::kernel::KernelConnection;
32#[cfg(feature = "std")]
33use crate::log::trace;
34#[cfg(feature = "std")]
35use crate::msgs::deframer::Locator;
36#[cfg(feature = "std")]
37use crate::msgs::handshake::ClientHelloPayload;
38use crate::msgs::handshake::ServerExtensionsInput;
39#[cfg(feature = "std")]
40use crate::msgs::handshake::ServerNamePayload;
41#[cfg(feature = "std")]
42use crate::msgs::message::Message;
43use crate::suites::ExtractedSecrets;
44use crate::sync::Arc;
45use crate::vecbuf::ChunkVecBuffer;
46
47#[cfg(feature = "std")]
48mod buffered {
49 use alloc::boxed::Box;
50 use core::fmt;
51 use core::fmt::{Debug, Formatter};
52 use core::ops::{Deref, DerefMut};
53 use std::io;
54
55 use pki_types::DnsName;
56
57 use super::{Accepted, Accepting, ServerConfig, ServerConnectionData, ServerExtensionsInput};
58 use crate::KeyingMaterialExporter;
59 use crate::common_state::{CommonState, Side};
60 use crate::conn::{ConnectionCommon, ConnectionCore};
61 use crate::error::{ApiMisuse, Error};
62 use crate::msgs::deframer::Locator;
63 use crate::server::hs::{ClientHelloInput, ServerContext};
64 use crate::suites::ExtractedSecrets;
65 use crate::sync::Arc;
66 use crate::vecbuf::ChunkVecBuffer;
67
68 pub struct ServerConnection {
73 pub(super) inner: ConnectionCommon<ServerConnectionData>,
74 }
75
76 impl ServerConnection {
77 pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
80 Ok(Self {
81 inner: ConnectionCommon::from(ConnectionCore::for_server(
82 config,
83 ServerExtensionsInput::default(),
84 )?),
85 })
86 }
87
88 pub fn server_name(&self) -> Option<&DnsName<'_>> {
104 self.inner.core.side.sni.as_ref()
105 }
106
107 pub fn received_resumption_data(&self) -> Option<&[u8]> {
113 self.inner
114 .core
115 .side
116 .received_resumption_data
117 .as_ref()
118 .map(|x| &x[..])
119 }
120
121 pub fn set_resumption_data(&mut self, data: &[u8]) {
130 assert!(data.len() < 2usize.pow(15));
131 self.inner.core.side.resumption_data = data.into();
132 }
133
134 pub fn reject_early_data(&mut self) {
140 self.inner.core.reject_early_data()
141 }
142
143 pub fn early_data(&mut self) -> Option<ReadEarlyData<'_>> {
154 if self
155 .inner
156 .core
157 .side
158 .early_data
159 .was_accepted()
160 {
161 Some(ReadEarlyData::new(&mut self.inner))
162 } else {
163 None
164 }
165 }
166
167 pub fn fips(&self) -> bool {
173 self.inner.core.common_state.fips
174 }
175
176 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
179 self.inner.dangerous_extract_secrets()
180 }
181 }
182
183 impl Debug for ServerConnection {
184 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
185 f.debug_struct("ServerConnection")
186 .finish()
187 }
188 }
189
190 impl Deref for ServerConnection {
191 type Target = ConnectionCommon<ServerConnectionData>;
192
193 fn deref(&self) -> &Self::Target {
194 &self.inner
195 }
196 }
197
198 impl DerefMut for ServerConnection {
199 fn deref_mut(&mut self) -> &mut Self::Target {
200 &mut self.inner
201 }
202 }
203
204 impl From<ServerConnection> for crate::Connection {
205 fn from(conn: ServerConnection) -> Self {
206 Self::Server(conn)
207 }
208 }
209
210 pub struct Acceptor {
257 inner: Option<ConnectionCommon<ServerConnectionData>>,
258 }
259
260 impl Default for Acceptor {
261 fn default() -> Self {
263 Self {
264 inner: Some(
265 ConnectionCore::new(
266 Box::new(Accepting),
267 ServerConnectionData::default(),
268 CommonState::new(Side::Server),
269 )
270 .into(),
271 ),
272 }
273 }
274 }
275
276 impl Acceptor {
277 pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
284 match &mut self.inner {
285 Some(conn) => conn.read_tls(rd),
286 None => Err(io::Error::other(
287 "acceptor cannot read after successful acceptance",
288 )),
289 }
290 }
291
292 pub fn accept(&mut self) -> Result<Option<Accepted>, (Error, AcceptedAlert)> {
304 let Some(mut connection) = self.inner.take() else {
305 return Err((
306 ApiMisuse::AcceptorPolledAfterCompletion.into(),
307 AcceptedAlert::empty(),
308 ));
309 };
310
311 let message = match connection.first_handshake_message() {
312 Ok(Some(msg)) => msg,
313 Ok(None) => {
314 self.inner = Some(connection);
315 return Ok(None);
316 }
317 Err(err) => return Err(AcceptedAlert::from_error(err, connection)),
318 };
319
320 let mut cx = ServerContext {
321 common: &mut connection.core.common_state,
322 data: &mut connection.core.side,
323 plaintext_locator: &Locator::new(&[]),
325 received_plaintext: &mut None,
326 sendable_plaintext: Some(&mut connection.sendable_plaintext),
327 };
328
329 let sig_schemes = match ClientHelloInput::from_message(&message, false, &mut cx) {
330 Ok(ClientHelloInput { sig_schemes, .. }) => sig_schemes,
331 Err(err) => {
332 return Err(AcceptedAlert::from_error(err, connection));
333 }
334 };
335 debug_assert!(cx.received_plaintext.is_none(), "read plaintext");
336
337 Ok(Some(Accepted {
338 connection,
339 message,
340 sig_schemes,
341 }))
342 }
343 }
344
345 pub struct AcceptedAlert(ChunkVecBuffer);
350
351 impl AcceptedAlert {
352 pub(super) fn from_error(
353 error: Error,
354 mut conn: ConnectionCommon<ServerConnectionData>,
355 ) -> (Error, Self) {
356 conn.core
357 .common_state
358 .maybe_send_fatal_alert(&error);
359 (error, Self(conn.core.common_state.sendable_tls))
360 }
361
362 pub(super) fn empty() -> Self {
363 Self(ChunkVecBuffer::new(None))
364 }
365
366 pub fn write(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
371 self.0.write_to(wr)
372 }
373
374 pub fn write_all(&mut self, wr: &mut dyn io::Write) -> Result<(), io::Error> {
378 while self.write(wr)? != 0 {}
379 Ok(())
380 }
381 }
382
383 impl Debug for AcceptedAlert {
384 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
385 f.debug_struct("AcceptedAlert").finish()
386 }
387 }
388
389 pub struct ReadEarlyData<'a> {
395 common: &'a mut ConnectionCommon<ServerConnectionData>,
396 }
397
398 impl<'a> ReadEarlyData<'a> {
399 fn new(common: &'a mut ConnectionCommon<ServerConnectionData>) -> Self {
400 ReadEarlyData { common }
401 }
402
403 pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
423 self.common.core.early_exporter()
424 }
425 }
426
427 impl io::Read for ReadEarlyData<'_> {
428 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
429 self.common
430 .core
431 .side
432 .early_data
433 .read(buf)
434 }
435 }
436}
437#[cfg(feature = "std")]
438pub use buffered::{AcceptedAlert, Acceptor, ReadEarlyData, ServerConnection};
439
440pub struct UnbufferedServerConnection {
444 inner: UnbufferedConnectionCommon<ServerConnectionData>,
445}
446
447impl UnbufferedServerConnection {
448 pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
450 Ok(Self {
451 inner: UnbufferedConnectionCommon::from(ConnectionCore::for_server(
452 config,
453 ServerExtensionsInput::default(),
454 )?),
455 })
456 }
457
458 #[deprecated = "dangerous_extract_secrets() does not support session tickets or \
461 key updates, use dangerous_into_kernel_connection() instead"]
462 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
463 self.inner.dangerous_extract_secrets()
464 }
465
466 pub fn dangerous_into_kernel_connection(
476 self,
477 ) -> Result<(ExtractedSecrets, KernelConnection<ServerConnectionData>), Error> {
478 self.inner
479 .core
480 .dangerous_into_kernel_connection()
481 }
482}
483
484impl Deref for UnbufferedServerConnection {
485 type Target = UnbufferedConnectionCommon<ServerConnectionData>;
486
487 fn deref(&self) -> &Self::Target {
488 &self.inner
489 }
490}
491
492impl DerefMut for UnbufferedServerConnection {
493 fn deref_mut(&mut self) -> &mut Self::Target {
494 &mut self.inner
495 }
496}
497
498impl UnbufferedConnectionCommon<ServerConnectionData> {
499 pub(crate) fn pop_early_data(&mut self) -> Option<Vec<u8>> {
500 self.core.side.early_data.pop()
501 }
502
503 pub(crate) fn peek_early_data(&self) -> Option<&[u8]> {
504 self.core.side.early_data.peek()
505 }
506}
507
508#[cfg(feature = "std")]
512pub struct Accepted {
513 connection: ConnectionCommon<ServerConnectionData>,
514 message: Message<'static>,
515 sig_schemes: Vec<SignatureScheme>,
516}
517
518#[cfg(feature = "std")]
519impl Accepted {
520 pub fn client_hello(&self) -> ClientHello<'_> {
522 let payload = Self::client_hello_payload(&self.message);
523 let server_name = payload
524 .server_name
525 .as_ref()
526 .and_then(ServerNamePayload::to_dns_name_normalized)
527 .map(Cow::Owned);
528 let ch = ClientHello {
529 server_name,
530 signature_schemes: &self.sig_schemes,
531 alpn: payload.protocols.as_ref(),
532 server_cert_types: payload
533 .server_certificate_types
534 .as_deref(),
535 client_cert_types: payload
536 .client_certificate_types
537 .as_deref(),
538 cipher_suites: &payload.cipher_suites,
539 certificate_authorities: payload
540 .certificate_authority_names
541 .as_deref(),
542 named_groups: payload.named_groups.as_deref(),
543 };
544
545 trace!("Accepted::client_hello(): {ch:#?}");
546 ch
547 }
548
549 pub fn into_connection(
555 mut self,
556 config: Arc<ServerConfig>,
557 ) -> Result<ServerConnection, (Error, AcceptedAlert)> {
558 if let Err(err) = self
559 .connection
560 .set_max_fragment_size(config.max_fragment_size)
561 {
562 return Err((err, AcceptedAlert::empty()));
565 }
566
567 self.connection.enable_secret_extraction = config.enable_secret_extraction;
568
569 let state = hs::ExpectClientHello::new(config, ServerExtensionsInput::default());
570 let proof = match self
571 .connection
572 .core
573 .common_state
574 .check_aligned_handshake()
575 {
576 Ok(proof) => proof,
577 Err(err) => return Err(AcceptedAlert::from_error(err, self.connection)),
578 };
579 let mut cx = hs::ServerContext {
580 common: &mut self.connection.core.common_state,
581 data: &mut self.connection.core.side,
582 plaintext_locator: &Locator::new(&[]),
584 received_plaintext: &mut None,
585 sendable_plaintext: Some(&mut self.connection.sendable_plaintext),
586 };
587
588 let input = ClientHelloInput {
589 client_hello: Self::client_hello_payload(&self.message),
590 message: &self.message,
591 sig_schemes: self.sig_schemes,
592 proof,
593 };
594
595 let new = match state.with_input(input, &mut cx) {
596 Ok(new) => new,
597 Err(err) => return Err(AcceptedAlert::from_error(err, self.connection)),
598 };
599 debug_assert!(cx.received_plaintext.is_none(), "read plaintext");
600
601 self.connection.replace_state(new);
602 Ok(ServerConnection {
603 inner: self.connection,
604 })
605 }
606
607 fn client_hello_payload<'a>(message: &'a Message<'_>) -> &'a ClientHelloPayload {
608 match &message.payload {
609 crate::msgs::message::MessagePayload::Handshake { parsed, .. } => match &parsed.0 {
610 crate::msgs::handshake::HandshakePayload::ClientHello(ch) => ch,
611 _ => unreachable!(),
612 },
613 _ => unreachable!(),
614 }
615 }
616}
617
618#[cfg(feature = "std")]
619impl Debug for Accepted {
620 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
621 f.debug_struct("Accepted").finish()
622 }
623}
624
625#[cfg(feature = "std")]
626struct Accepting;
627
628#[cfg(feature = "std")]
629impl State<ServerConnectionData> for Accepting {
630 #[cfg_attr(coverage_nightly, coverage(off))]
631 fn handle<'m>(
632 self: Box<Self>,
633 _cx: &mut hs::ServerContext<'_>,
634 _m: Message<'m>,
635 ) -> Result<Box<dyn State<ServerConnectionData>>, Error> {
636 Err(Error::Unreachable("unreachable state"))
637 }
638}
639
640#[derive(Default)]
641pub(super) enum EarlyDataState {
642 #[default]
643 New,
644 Accepted {
645 received: ChunkVecBuffer,
646 left: usize,
647 },
648 Rejected,
649}
650
651impl EarlyDataState {
652 pub(super) fn reject(&mut self) {
653 *self = Self::Rejected;
654 }
655
656 pub(super) fn accept(&mut self, max_size: usize) {
657 *self = Self::Accepted {
658 received: ChunkVecBuffer::new(Some(max_size)),
659 left: max_size,
660 };
661 }
662
663 #[cfg(feature = "std")]
664 fn was_accepted(&self) -> bool {
665 matches!(self, Self::Accepted { .. })
666 }
667
668 pub(super) fn was_rejected(&self) -> bool {
669 matches!(self, Self::Rejected)
670 }
671
672 fn peek(&self) -> Option<&[u8]> {
673 match self {
674 Self::Accepted { received, .. } => received.peek(),
675 _ => None,
676 }
677 }
678
679 fn pop(&mut self) -> Option<Vec<u8>> {
680 match self {
681 Self::Accepted { received, .. } => received.pop(),
682 _ => None,
683 }
684 }
685
686 #[cfg(feature = "std")]
687 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
688 match self {
689 Self::Accepted { received, .. } => received.read(buf),
690 _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)),
691 }
692 }
693
694 pub(super) fn take_received_plaintext(&mut self, bytes: Payload<'_>) -> bool {
695 let available = bytes.bytes().len();
696 let Self::Accepted { received, left } = self else {
697 return false;
698 };
699
700 if received.apply_limit(available) != available || available > *left {
701 return false;
702 }
703
704 received.append(bytes.into_vec());
705 *left -= available;
706 true
707 }
708}
709
710impl Debug for EarlyDataState {
711 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
712 match self {
713 Self::New => write!(f, "EarlyDataState::New"),
714 Self::Accepted { received, left } => write!(
715 f,
716 "EarlyDataState::Accepted {{ received: {}, left: {} }}",
717 received.len(),
718 left
719 ),
720 Self::Rejected => write!(f, "EarlyDataState::Rejected"),
721 }
722 }
723}
724
725impl ConnectionCore<ServerConnectionData> {
726 pub(crate) fn for_server(
727 config: Arc<ServerConfig>,
728 extra_exts: ServerExtensionsInput<'static>,
729 ) -> Result<Self, Error> {
730 let mut common = CommonState::new(Side::Server);
731 common.set_max_fragment_size(config.max_fragment_size)?;
732 common.enable_secret_extraction = config.enable_secret_extraction;
733 common.fips = config.fips();
734 Ok(Self::new(
735 Box::new(hs::ExpectClientHello::new(config, extra_exts)),
736 ServerConnectionData::default(),
737 common,
738 ))
739 }
740
741 #[cfg(feature = "std")]
742 pub(crate) fn reject_early_data(&mut self) {
743 assert!(
744 self.common_state.is_handshaking(),
745 "cannot retroactively reject early data"
746 );
747 self.side.early_data.reject();
748 }
749}
750
751#[derive(Default, Debug)]
753pub struct ServerConnectionData {
754 pub(crate) sni: Option<DnsName<'static>>,
755 pub(crate) received_resumption_data: Option<Vec<u8>>,
756 pub(crate) resumption_data: Vec<u8>,
757 pub(super) early_data: EarlyDataState,
758}
759
760impl crate::conn::SideData for ServerConnectionData {}
761
762#[cfg(feature = "std")]
763#[cfg(test)]
764mod tests {
765 use std::format;
766
767 use super::*;
768
769 #[test]
771 fn test_read_in_new_state() {
772 assert_eq!(
773 format!("{:?}", EarlyDataState::default().read(&mut [0u8; 5])),
774 "Err(Kind(BrokenPipe))"
775 );
776 }
777}