base_endpoint/tls/rustls/
rustls_connection.rs1use super::tls_error;
5use crate::tls::{TlsSession, TlsStream};
6use ::rustls::{Connection, pki_types::CertificateDer};
7use base_scheduler::{
8 Cancellation, OperationError, OperationResult, SocketClose, SocketStreamReader,
9 SocketStreamReading, SocketStreamWriter, SocketStreamWriting,
10};
11use std::io::{self, BufRead, Read, Write};
12
13const BUFFER_SIZE: usize = 16 * 1024;
14
15mod duplex;
16pub use duplex::{EncryptedSocketStreamReader, EncryptedSocketStreamWriter};
17
18#[derive(Debug)]
22pub struct RustlsConnection<C> {
23 socket: C,
24 state: Connection,
25 incoming: Vec<u8>,
26 incoming_start: usize,
27 incoming_end: usize,
28 outgoing: Vec<u8>,
29 outgoing_start: usize,
30 write_closed: bool,
31}
32
33impl<C> RustlsConnection<C> {
34 pub(super) fn new(socket: C, mut state: Connection) -> Self {
35 state.set_buffer_limit(Some(BUFFER_SIZE));
36 Self {
37 socket,
38 state,
39 incoming: vec![0; BUFFER_SIZE],
40 incoming_start: 0,
41 incoming_end: 0,
42 outgoing: Vec::with_capacity(BUFFER_SIZE),
43 outgoing_start: 0,
44 write_closed: false,
45 }
46 }
47
48 pub fn socket(&self) -> &C {
50 &self.socket
51 }
52
53 pub fn peer_certificates(&self) -> Option<&[CertificateDer<'static>]> {
55 self.state.peer_certificates()
56 }
57
58 pub(super) async fn handshake<S>(
59 &mut self,
60 scheduler: &S,
61 cancellation: &Cancellation,
62 ) -> OperationResult<()>
63 where
64 S: SocketStreamReading<Socket = C> + SocketStreamWriting + ?Sized,
65 C: 'static,
66 {
67 let mut reader = scheduler.socket_stream_reader(&self.socket)?;
68 let mut writer = match scheduler.socket_stream_writer(&self.socket) {
69 Ok(writer) => writer,
70 Err(error) => {
71 let _ = reader.close().await;
72 return Err(error.into());
73 }
74 };
75 let result: OperationResult<()> = async {
76 loop {
77 self.send(&mut writer, cancellation).await?;
78 if !self.state.is_handshaking() {
79 return Ok(());
80 }
81 if self.receive(&mut reader, cancellation).await? == 0 {
82 return Err(io::Error::new(
83 io::ErrorKind::UnexpectedEof,
84 "peer closed during TLS handshake",
85 )
86 .into());
87 }
88 }
89 }
90 .await;
91 self.send_alert_on_error(&result, &mut writer, cancellation)
92 .await;
93 let read_closed = reader.close().await;
94 let write_closed = writer.close().await;
95 result?;
96 read_closed?;
97 write_closed?;
98 Ok(())
99 }
100
101 pub async fn read<S>(
103 &mut self,
104 scheduler: &S,
105 buffer: &mut [u8],
106 cancellation: &Cancellation,
107 ) -> OperationResult<usize>
108 where
109 S: SocketStreamReading<Socket = C> + SocketStreamWriting + ?Sized,
110 C: 'static,
111 {
112 cancellation.check()?;
113 if buffer.is_empty() {
114 return Ok(0);
115 }
116 let mut reader = scheduler.socket_stream_reader(&self.socket)?;
117 let mut writer = match scheduler.socket_stream_writer(&self.socket) {
118 Ok(writer) => writer,
119 Err(error) => {
120 let _ = reader.close().await;
121 return Err(error.into());
122 }
123 };
124 let result: OperationResult<()> = async {
125 loop {
126 self.send(&mut writer, cancellation).await?;
127 match self.state.reader().fill_buf() {
129 Err(error) if error.kind() == io::ErrorKind::WouldBlock => {
130 self.receive(&mut reader, cancellation).await?;
131 }
132 Ok(_) => return Ok(()),
133 Err(error) => return Err(error.into()),
134 }
135 }
136 }
137 .await;
138 self.send_alert_on_error(&result, &mut writer, cancellation)
139 .await;
140 let read_closed = reader.close().await;
141 let write_closed = writer.close().await;
142 result?;
143 read_closed?;
144 write_closed?;
145 self.state.reader().read(buffer).map_err(Into::into)
146 }
147
148 pub async fn write<S>(
150 &mut self,
151 scheduler: &S,
152 buffer: &[u8],
153 cancellation: &Cancellation,
154 ) -> OperationResult<usize>
155 where
156 S: SocketStreamWriting<Socket = C> + ?Sized,
157 C: 'static,
158 {
159 cancellation.check()?;
160 if self.write_closed {
161 return Err(
162 io::Error::new(io::ErrorKind::BrokenPipe, "TLS output is shut down").into(),
163 );
164 }
165 self.flush(scheduler, cancellation).await?;
166 cancellation.check()?;
167 self.state.writer().write(buffer).map_err(Into::into)
168 }
169
170 pub async fn flush<S>(
172 &mut self,
173 scheduler: &S,
174 cancellation: &Cancellation,
175 ) -> OperationResult<()>
176 where
177 S: SocketStreamWriting<Socket = C> + ?Sized,
178 C: 'static,
179 {
180 cancellation.check()?;
181 let mut writer = scheduler.socket_stream_writer(&self.socket)?;
182 let result = self.send(&mut writer, cancellation).await;
183 let closed = writer.close().await;
184 result?;
185 closed?;
186 Ok(())
187 }
188
189 pub async fn shutdown<S>(
191 &mut self,
192 scheduler: &S,
193 cancellation: &Cancellation,
194 ) -> OperationResult<()>
195 where
196 S: SocketStreamWriting<Socket = C> + ?Sized,
197 C: 'static,
198 {
199 cancellation.check()?;
200 if !self.write_closed {
201 self.state.send_close_notify();
202 self.write_closed = true;
203 }
204 self.flush(scheduler, cancellation).await
205 }
206
207 pub async fn close<S>(
209 mut self,
210 scheduler: &S,
211 cancellation: &Cancellation,
212 ) -> OperationResult<()>
213 where
214 S: SocketStreamWriting<Socket = C> + SocketClose + ?Sized,
215 C: 'static,
216 {
217 let result = self.shutdown(scheduler, cancellation).await;
218 let closed = scheduler.socket_close(self.socket).await;
219 result?;
220 closed?;
221 Ok(())
222 }
223
224 pub async fn abort<S>(self, scheduler: &S) -> io::Result<()>
226 where
227 S: SocketClose<Socket = C> + ?Sized,
228 {
229 scheduler.socket_close(self.socket).await
230 }
231
232 async fn send<W: SocketStreamWriter>(
233 &mut self,
234 writer: &mut W,
235 cancellation: &Cancellation,
236 ) -> OperationResult<()> {
237 loop {
238 if self.outgoing_start == self.outgoing.len() {
239 self.outgoing.clear();
240 self.outgoing_start = 0;
241 if !self.state.wants_write() {
242 break;
243 }
244 self.outgoing.resize(BUFFER_SIZE, 0);
245 let count = self
247 .state
248 .write_tls(&mut io::Cursor::new(self.outgoing.as_mut_slice()))
249 .expect("writing TLS records to memory cannot fail");
250 self.outgoing.truncate(count);
251 }
252 let count = writer
253 .write(&self.outgoing[self.outgoing_start..], cancellation)
254 .await?;
255 if count == 0 {
256 return Err(io::Error::new(
257 io::ErrorKind::WriteZero,
258 "TLS transport made no write progress",
259 )
260 .into());
261 }
262 self.outgoing_start += count;
263 }
264 writer.flush(cancellation).await
265 }
266
267 async fn send_alert_on_error<W: SocketStreamWriter>(
269 &mut self,
270 result: &OperationResult<()>,
271 writer: &mut W,
272 cancellation: &Cancellation,
273 ) {
274 if matches!(result, Err(OperationError::Io(error)) if error.get_ref().is_some_and(|source| source.is::<::rustls::Error>()))
275 {
276 let _ = self.send(writer, cancellation).await;
277 }
278 }
279
280 async fn receive<R: SocketStreamReader>(
281 &mut self,
282 reader: &mut R,
283 cancellation: &Cancellation,
284 ) -> OperationResult<usize> {
285 if self.incoming_start == self.incoming_end {
286 self.incoming_start = 0;
287 self.incoming_end = reader.read_into(&mut self.incoming, cancellation).await?;
288 }
289 let mut input = &self.incoming[self.incoming_start..self.incoming_end];
290 let count = self.state.read_tls(&mut input)?;
291 self.incoming_start += count;
292 self.state.process_new_packets().map_err(tls_error)?;
293 Ok(count)
294 }
295}
296
297impl<C: Send> TlsSession for RustlsConnection<C> {
298 fn negotiated_protocol(&self) -> Option<&[u8]> {
299 self.state.alpn_protocol()
300 }
301}
302
303impl<S> TlsStream<S> for RustlsConnection<S::Socket>
304where
305 S: SocketStreamReading + SocketStreamWriting + SocketClose + ?Sized,
306 S::Socket: 'static,
307{
308 async fn read(
309 &mut self,
310 scheduler: &S,
311 buffer: &mut [u8],
312 cancellation: &Cancellation,
313 ) -> OperationResult<usize> {
314 Self::read(self, scheduler, buffer, cancellation).await
315 }
316
317 async fn write(
318 &mut self,
319 scheduler: &S,
320 buffer: &[u8],
321 cancellation: &Cancellation,
322 ) -> OperationResult<usize> {
323 Self::write(self, scheduler, buffer, cancellation).await
324 }
325
326 async fn flush(&mut self, scheduler: &S, cancellation: &Cancellation) -> OperationResult<()> {
327 Self::flush(self, scheduler, cancellation).await
328 }
329
330 async fn shutdown(
331 &mut self,
332 scheduler: &S,
333 cancellation: &Cancellation,
334 ) -> OperationResult<()> {
335 Self::shutdown(self, scheduler, cancellation).await
336 }
337
338 async fn close(self, scheduler: &S, cancellation: &Cancellation) -> OperationResult<()> {
339 Self::close(self, scheduler, cancellation).await
340 }
341
342 async fn abort(self, scheduler: &S) -> io::Result<()> {
343 Self::abort(self, scheduler).await
344 }
345}
346
347#[cfg(test)]
348mod tests;