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