use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt;
use pki_types::{DnsName, FipsStatus};
use super::config::ServerConfig;
use crate::common_state::{CommonState, Event, Side};
use crate::conn::private::SideOutput;
use crate::conn::split::SplitConnection;
use crate::conn::{
Accepted, Connection, NeedsInput, ServerNext, SideData, Tcp, Transport, VerifyPeerIdentity,
};
#[cfg(doc)]
use crate::crypto;
use crate::error::Error;
use crate::msgs::ServerExtensionsInput;
use crate::quic::ServerHandshake as QuicServerHandshake;
use crate::server::hs::{ExpectClientHello, ReadClientHello, ServerState};
use crate::sync::Arc;
use crate::verify::ClientIdentity;
impl Connection<ServerSide, Tcp> {
pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
Self::for_server(config, ServerExtensionsInput::default(), Tcp)
}
}
impl<T: Transport> Connection<ServerSide, T> {
pub(crate) fn for_server(
config: Arc<ServerConfig>,
extra_exts: ServerExtensionsInput,
transport: T,
) -> Result<Self, Error> {
let mut common = CommonState::new(Side::Server, config.fips());
common
.send
.set_max_fragment_size(config.max_fragment_size)?;
let protocol = transport.protocol();
Ok(Self {
state: Ok(Box::new(ExpectClientHello::new(
config,
extra_exts,
Vec::new(),
protocol,
))
.into()),
side: ServerSide::default(),
transport,
common,
})
}
pub(crate) fn for_acceptor(transport: T) -> Self {
Self {
state: Ok(ReadClientHello::new(transport.protocol()).into()),
side: ServerSide::default(),
transport,
common: CommonState::new(Side::Server, FipsStatus::Unvalidated),
}
}
}
#[non_exhaustive]
#[derive(Debug)]
pub enum ServerHandshake {
NeedsInput(NeedsInput<ServerSide>),
Accepted(Accepted<Tcp>),
VerifyClientIdentity(VerifyPeerIdentity<ServerSide, Tcp>),
Complete(SplitConnection<ServerSide>),
}
impl ServerHandshake {
pub fn start() -> NeedsInput<ServerSide> {
NeedsInput::new(Connection::for_acceptor(Tcp))
}
}
impl TryFrom<Connection<ServerSide, Tcp>> for ServerHandshake {
type Error = Error;
fn try_from(conn: Connection<ServerSide, Tcp>) -> Result<Self, Error> {
Ok(match ServerNext::try_from(conn)? {
ServerNext::NeedsInput(conn) => Self::NeedsInput(NeedsInput(conn)),
ServerNext::ChooseConfig(accepted) => Self::Accepted(accepted),
ServerNext::VerifyClientIdentity(verify) => Self::VerifyClientIdentity(verify),
ServerNext::Complete(conn) => Self::Complete(SplitConnection::try_from(conn)?),
})
}
}
#[derive(Default)]
pub struct ServerSide {
sni: Option<DnsName<'static>>,
received_resumption_data: Option<Vec<u8>>,
}
impl ServerSide {
pub fn received_resumption_data(&self) -> Option<&[u8]> {
self.received_resumption_data.as_deref()
}
pub fn server_name(&self) -> Option<&DnsName<'static>> {
self.sni.as_ref()
}
}
impl SideData for ServerSide {
type Handshake = ServerHandshake;
type QuicHandshake = QuicServerHandshake;
type PeerIdentity<'a> = ClientIdentity<'static, 'a>;
}
impl SideOutput for ServerSide {
fn emit(&mut self, ev: Event) {
match ev {
Event::ReceivedServerName(sni) => self.sni = sni,
Event::ResumptionData(data) => self.received_resumption_data = Some(data),
_ => unreachable!(),
}
}
}
impl crate::conn::private::Side for ServerSide {
type State = ServerState;
}
impl fmt::Debug for ServerSide {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ServerSide")
.field("sni", &self.sni)
.finish_non_exhaustive()
}
}