1use alloc::vec::Vec;
2
3use pki_types::{DnsName, UnixTime};
4
5use crate::crypto::cipher::Payload;
6use crate::crypto::{CipherSuite, Identity};
7use crate::enums::{ApplicationProtocol, ProtocolVersion};
8use crate::error::InvalidMessage;
9use crate::msgs::{Codec, MaybeEmpty, Reader, SessionId, SizedPayload};
10pub use crate::verify::NoClientAuth;
11#[cfg(feature = "webpki")]
12pub use crate::webpki::{
13 ClientVerifierBuilder, ParsedCertificate, VerifierBuilderError, WebPkiClientVerifier,
14};
15
16pub(crate) mod config;
17pub use config::{
18 ClientHello, InvalidSniPolicy, ServerConfig, ServerCredentialResolver, StoresServerSessions,
19 WantsServerCert,
20};
21
22mod connection;
23pub use connection::{
24 Accepted, AcceptedAlert, Acceptor, ReadEarlyData, ServerConnection, ServerSide,
25};
26
27pub(crate) mod handy;
28#[cfg(feature = "webpki")]
29pub use handy::ServerNameResolver;
30pub use handy::{NoServerSessionStorage, ServerSessionMemoryCache};
31
32mod hs;
33pub(crate) use hs::ServerHandler;
34
35mod tls12;
36pub(crate) use tls12::TLS12_HANDLER;
37use tls12::Tls12ServerSessionValue;
38
39mod tls13;
40pub(crate) use tls13::TLS13_HANDLER;
41use tls13::Tls13ServerSessionValue;
42
43pub mod danger {
45 pub use crate::verify::{
46 ClientIdentity, ClientVerifier, PeerVerified, SignatureVerificationInput,
47 };
48}
49
50#[cfg(test)]
51mod test;
52
53#[derive(Debug)]
54pub(crate) enum ServerSessionValue<'a> {
55 Tls12(Tls12ServerSessionValue<'a>),
56 Tls13(Tls13ServerSessionValue<'a>),
57}
58
59impl<'a> Codec<'a> for ServerSessionValue<'a> {
60 fn encode(&self, bytes: &mut Vec<u8>) {
61 match self {
62 Self::Tls12(value) => {
63 ProtocolVersion::TLSv1_2.encode(bytes);
64 value.encode(bytes);
65 }
66 Self::Tls13(value) => {
67 ProtocolVersion::TLSv1_3.encode(bytes);
68 value.encode(bytes);
69 }
70 }
71 }
72
73 fn read(r: &mut Reader<'a>) -> Result<Self, InvalidMessage> {
74 match ProtocolVersion::read(r)? {
75 ProtocolVersion::TLSv1_2 => Ok(Self::Tls12(Tls12ServerSessionValue::read(r)?)),
76 ProtocolVersion::TLSv1_3 => Ok(Self::Tls13(Tls13ServerSessionValue::read(r)?)),
77 _ => Err(InvalidMessage::UnknownProtocolVersion),
78 }
79 }
80}
81
82#[derive(Debug)]
83pub(crate) struct CommonServerSessionValue<'a> {
84 pub(crate) creation_time_sec: u64,
85 pub(crate) sni: Option<DnsName<'a>>,
86 pub(crate) cipher_suite: CipherSuite,
87 pub(crate) peer_identity: Option<Identity<'a>>,
88 pub(crate) alpn: Option<ApplicationProtocol<'a>>,
89 pub(crate) application_data: SizedPayload<'a, u16, MaybeEmpty>,
90}
91
92impl<'a> CommonServerSessionValue<'a> {
93 pub(crate) fn new(
94 sni: Option<&DnsName<'a>>,
95 cipher_suite: CipherSuite,
96 peer_identity: Option<Identity<'a>>,
97 alpn: Option<ApplicationProtocol<'a>>,
98 application_data: Vec<u8>,
99 creation_time: UnixTime,
100 ) -> Self {
101 Self {
102 creation_time_sec: creation_time.as_secs(),
103 sni: sni.map(|s| s.to_owned()),
104 cipher_suite,
105 peer_identity,
106 alpn,
107 application_data: SizedPayload::from(Payload::new(application_data)),
108 }
109 }
110
111 fn into_owned(self) -> CommonServerSessionValue<'static> {
112 CommonServerSessionValue {
113 creation_time_sec: self.creation_time_sec,
114 sni: self.sni.map(|s| s.to_owned()),
115 cipher_suite: self.cipher_suite,
116 peer_identity: self
117 .peer_identity
118 .map(|i| i.into_owned()),
119 alpn: self.alpn.map(|a| a.to_owned()),
120 application_data: self.application_data.into_owned(),
121 }
122 }
123
124 pub(crate) fn can_resume(&self, suite: CipherSuite, sni: Option<&DnsName<'_>>) -> bool {
125 self.cipher_suite == suite && self.sni.as_ref() == sni
136 }
137}
138
139impl Codec<'_> for CommonServerSessionValue<'_> {
140 fn encode(&self, bytes: &mut Vec<u8>) {
141 self.creation_time_sec.encode(bytes);
142 if let Some(sni) = &self.sni {
143 1u8.encode(bytes);
144 let sni_bytes: &str = sni.as_ref();
145 SizedPayload::<u8, MaybeEmpty>::from(Payload::Borrowed(sni_bytes.as_bytes()))
146 .encode(bytes);
147 } else {
148 0u8.encode(bytes);
149 }
150 self.cipher_suite.encode(bytes);
151 if let Some(identity) = &self.peer_identity {
152 1u8.encode(bytes);
153 identity.encode(bytes);
154 } else {
155 0u8.encode(bytes);
156 }
157 if let Some(alpn) = &self.alpn {
158 1u8.encode(bytes);
159 alpn.encode(bytes);
160 } else {
161 0u8.encode(bytes);
162 }
163 self.application_data.encode(bytes);
164 }
165
166 fn read(r: &mut Reader<'_>) -> Result<Self, InvalidMessage> {
167 let creation_time_sec = u64::read(r)?;
168 let sni = match u8::read(r)? {
169 1 => {
170 let dns_name = SizedPayload::<u8, MaybeEmpty>::read(r)?;
171 let dns_name = match DnsName::try_from(dns_name.bytes()) {
172 Ok(dns_name) => dns_name.to_owned(),
173 Err(_) => return Err(InvalidMessage::InvalidServerName),
174 };
175
176 Some(dns_name)
177 }
178 _ => None,
179 };
180
181 Ok(Self {
182 creation_time_sec,
183 sni,
184 cipher_suite: CipherSuite::read(r)?,
185 peer_identity: match u8::read(r)? {
186 1 => Some(Identity::read(r)?.into_owned()),
187 _ => None,
188 },
189 alpn: match u8::read(r)? {
190 1 => Some(ApplicationProtocol::read(r)?.to_owned()),
191 _ => None,
192 },
193 application_data: SizedPayload::read(r)?.into_owned(),
194 })
195 }
196}
197
198pub struct ServerSessionKey<'a> {
200 inner: &'a [u8],
201}
202
203impl<'a> ServerSessionKey<'a> {
204 pub(crate) fn new(inner: &'a [u8]) -> Self {
205 Self { inner }
206 }
207}
208
209impl<'a> From<&'a SessionId> for ServerSessionKey<'a> {
210 fn from(session_id: &'a SessionId) -> Self {
211 Self::new(session_id.as_ref())
212 }
213}
214
215impl AsRef<[u8]> for ServerSessionKey<'_> {
216 fn as_ref(&self) -> &[u8] {
217 self.inner
218 }
219}