s2n_quic_rustls/
server.rs1use crate::{certificate, cipher_suite::default_crypto_provider, session::Session, Error};
5use rustls::{crypto::aws_lc_rs, ConfigBuilder, ServerConfig, WantsVerifier};
6use s2n_codec::EncoderValue;
7use s2n_quic_core::{application::ServerName, crypto::tls};
8use std::sync::Arc;
9
10fn default_config_builder() -> Result<ConfigBuilder<ServerConfig, WantsVerifier>, rustls::Error> {
14 let tls13_cipher_suite_crypto_provider = default_crypto_provider()?;
15 ServerConfig::builder_with_provider(tls13_cipher_suite_crypto_provider.into())
16 .with_protocol_versions(crate::PROTOCOL_VERSIONS)
17}
18
19#[derive(Clone)]
20pub struct Server {
21 config: Arc<ServerConfig>,
22}
23
24impl Server {
25 #[deprecated = "client and server builders should be used instead"]
33 pub fn new(config: ServerConfig) -> Self {
34 Self {
35 config: Arc::new(config),
36 }
37 }
38
39 pub fn builder() -> Builder {
40 Builder::new()
41 }
42}
43
44impl Default for Server {
45 fn default() -> Self {
46 Self::builder()
47 .build()
48 .expect("could not create default server")
49 }
50}
51
52impl From<ServerConfig> for Server {
54 fn from(config: ServerConfig) -> Self {
55 Self::from(Arc::new(config))
56 }
57}
58
59impl From<Arc<ServerConfig>> for Server {
61 fn from(config: Arc<ServerConfig>) -> Self {
62 Self { config }
63 }
64}
65
66impl tls::Endpoint for Server {
67 type Session = Session;
68
69 fn new_server_session<Params: EncoderValue>(
70 &mut self,
71 transport_parameters: &Params,
72 _connection_info: tls::ConnectionInfo,
73 ) -> Self::Session {
74 let transport_parameters = transport_parameters.encode_to_vec();
77
78 let session = rustls::quic::ServerConnection::new(
79 self.config.clone(),
80 crate::QUIC_VERSION,
81 transport_parameters,
82 )
83 .expect("could not create rustls server session");
84
85 Session::new(session.into(), None)
86 }
87
88 fn new_client_session<Params: EncoderValue>(
89 &mut self,
90 _transport_parameters: &Params,
91 _sni: ServerName,
92 ) -> Self::Session {
93 panic!("cannot create a client session from a server config");
94 }
95
96 fn max_tag_length(&self) -> usize {
97 s2n_quic_crypto::MAX_TAG_LEN
98 }
99}
100
101pub struct Builder {
102 cert_resolver: Option<Arc<dyn rustls::server::ResolvesServerCert>>,
103 application_protocols: Vec<Vec<u8>>,
104 key_log: Option<Arc<dyn rustls::KeyLog>>,
105 prefer_server_cipher_suite_order: bool,
106}
107
108impl Default for Builder {
109 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl Builder {
115 pub fn new() -> Self {
116 Self {
117 cert_resolver: None,
118 application_protocols: vec![b"h3".to_vec()],
119 key_log: None,
120 prefer_server_cipher_suite_order: true,
121 }
122 }
123
124 pub fn with_certificate<C: certificate::IntoCertificate, PK: certificate::IntoPrivateKey>(
125 mut self,
126 certificate: C,
127 private_key: PK,
128 ) -> Result<Self, Error> {
129 let certificate = certificate.into_certificate()?;
130 let private_key = private_key.into_private_key()?;
131 let resolver = AlwaysResolvesChain::new(certificate, private_key)?;
132 let resolver = Arc::new(resolver);
133 self.cert_resolver = Some(resolver);
134 Ok(self)
135 }
136
137 #[deprecated = "client and server builders should be used instead"]
138 pub fn with_cert_resolver(
139 mut self,
140 cert_resolver: Arc<dyn rustls::server::ResolvesServerCert>,
141 ) -> Result<Self, Error> {
142 self.cert_resolver = Some(cert_resolver);
143 Ok(self)
144 }
145
146 pub fn with_application_protocols<P: Iterator<Item = I>, I: AsRef<[u8]>>(
147 mut self,
148 protocols: P,
149 ) -> Result<Self, Error> {
150 self.application_protocols = protocols.map(|p| p.as_ref().to_vec()).collect();
151 Ok(self)
152 }
153
154 pub fn with_key_logging(mut self) -> Result<Self, Error> {
155 self.key_log = Some(Arc::new(rustls::KeyLogFile::new()));
156 Ok(self)
157 }
158
159 pub fn with_prefer_server_cipher_suite_order(mut self, enabled: bool) -> Result<Self, Error> {
162 self.prefer_server_cipher_suite_order = enabled;
163 Ok(self)
164 }
165
166 pub fn build(self) -> Result<Server, Error> {
167 let builder = default_config_builder()?.with_no_client_auth();
168
169 let mut config = if let Some(cert_resolver) = self.cert_resolver {
170 builder.with_cert_resolver(cert_resolver)
171 } else {
172 return Err(rustls::Error::General(
173 "Missing certificate or certificate resolver".to_string(),
174 )
175 .into());
176 };
177
178 config.ignore_client_order = self.prefer_server_cipher_suite_order;
179 config.max_fragment_size = None;
180 config.alpn_protocols = self.application_protocols;
181
182 if let Some(key_log) = self.key_log {
183 config.key_log = key_log;
184 }
185
186 #[allow(deprecated)]
187 Ok(Server::new(config))
188 }
189}
190
191#[derive(Debug)]
192struct AlwaysResolvesChain(Arc<rustls::sign::CertifiedKey>);
193
194impl AlwaysResolvesChain {
195 fn new(
196 chain: certificate::Certificate,
197 priv_key: certificate::PrivateKey,
198 ) -> Result<Self, rustls::Error> {
199 let key = aws_lc_rs::sign::any_supported_type(&priv_key.0)
200 .map_err(|_| rustls::Error::General("invalid private key".into()))?;
201 Ok(Self(Arc::new(rustls::sign::CertifiedKey::new(
202 chain.0, key,
203 ))))
204 }
205}
206
207impl rustls::server::ResolvesServerCert for AlwaysResolvesChain {
208 fn resolve(
209 &self,
210 _client_hello: rustls::server::ClientHello,
211 ) -> Option<Arc<rustls::sign::CertifiedKey>> {
212 Some(Arc::clone(&self.0))
213 }
214}