rustls/conn.rs
1use alloc::boxed::Box;
2use core::fmt::Debug;
3use core::mem;
4use core::ops::{Deref, DerefMut, Range};
5#[cfg(feature = "std")]
6use std::io;
7
8use kernel::KernelConnection;
9
10use crate::common_state::{CommonState, Context, DEFAULT_BUFFER_LIMIT, IoState, State};
11use crate::enums::{AlertDescription, ContentType, ProtocolVersion};
12use crate::error::{Error, PeerMisbehaved};
13use crate::log::trace;
14use crate::msgs::deframer::DeframerIter;
15use crate::msgs::deframer::buffers::{BufferProgress, DeframerVecBuffer, Delocator, Locator};
16use crate::msgs::deframer::handshake::HandshakeDeframer;
17use crate::msgs::handshake::Random;
18use crate::msgs::message::{InboundPlainMessage, Message, MessagePayload};
19use crate::record_layer::Decrypted;
20use crate::suites::ExtractedSecrets;
21use crate::vecbuf::ChunkVecBuffer;
22
23// pub so that it can be re-exported from the crate root
24pub mod kernel;
25pub(crate) mod unbuffered;
26
27#[cfg(feature = "std")]
28mod connection {
29 use alloc::vec::Vec;
30 use core::fmt::Debug;
31 use core::ops::{Deref, DerefMut};
32 use std::io::{self, BufRead, Read};
33
34 use crate::ConnectionCommon;
35 use crate::common_state::{CommonState, IoState};
36 use crate::error::Error;
37 use crate::msgs::message::OutboundChunks;
38 use crate::suites::ExtractedSecrets;
39 use crate::vecbuf::ChunkVecBuffer;
40
41 /// A client or server connection.
42 #[derive(Debug)]
43 pub enum Connection {
44 /// A client connection
45 Client(crate::client::ClientConnection),
46 /// A server connection
47 Server(crate::server::ServerConnection),
48 }
49
50 impl Connection {
51 /// Read TLS content from `rd`.
52 ///
53 /// See [`ConnectionCommon::read_tls()`] for more information.
54 pub fn read_tls(&mut self, rd: &mut dyn Read) -> Result<usize, io::Error> {
55 match self {
56 Self::Client(conn) => conn.read_tls(rd),
57 Self::Server(conn) => conn.read_tls(rd),
58 }
59 }
60
61 /// Writes TLS messages to `wr`.
62 ///
63 /// See [`ConnectionCommon::write_tls()`] for more information.
64 pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
65 self.sendable_tls.write_to(wr)
66 }
67
68 /// Returns an object that allows reading plaintext.
69 pub fn reader(&mut self) -> Reader<'_> {
70 match self {
71 Self::Client(conn) => conn.reader(),
72 Self::Server(conn) => conn.reader(),
73 }
74 }
75
76 /// Returns an object that allows writing plaintext.
77 pub fn writer(&mut self) -> Writer<'_> {
78 match self {
79 Self::Client(conn) => Writer::new(&mut **conn),
80 Self::Server(conn) => Writer::new(&mut **conn),
81 }
82 }
83
84 /// Processes any new packets read by a previous call to [`Connection::read_tls`].
85 ///
86 /// See [`ConnectionCommon::process_new_packets()`] for more information.
87 pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
88 match self {
89 Self::Client(conn) => conn.process_new_packets(),
90 Self::Server(conn) => conn.process_new_packets(),
91 }
92 }
93
94 /// Derives key material from the agreed connection secrets.
95 ///
96 /// See [`ConnectionCommon::export_keying_material()`] for more information.
97 pub fn export_keying_material<T: AsMut<[u8]>>(
98 &self,
99 output: T,
100 label: &[u8],
101 context: Option<&[u8]>,
102 ) -> Result<T, Error> {
103 match self {
104 Self::Client(conn) => conn.export_keying_material(output, label, context),
105 Self::Server(conn) => conn.export_keying_material(output, label, context),
106 }
107 }
108
109 /// This function uses `io` to complete any outstanding IO for this connection.
110 ///
111 /// See [`ConnectionCommon::complete_io()`] for more information.
112 pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
113 where
114 Self: Sized,
115 T: Read + io::Write,
116 {
117 match self {
118 Self::Client(conn) => conn.complete_io(io),
119 Self::Server(conn) => conn.complete_io(io),
120 }
121 }
122
123 /// Extract secrets, so they can be used when configuring kTLS, for example.
124 /// Should be used with care as it exposes secret key material.
125 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
126 match self {
127 Self::Client(client) => client.dangerous_extract_secrets(),
128 Self::Server(server) => server.dangerous_extract_secrets(),
129 }
130 }
131
132 /// Sets a limit on the internal buffers
133 ///
134 /// See [`ConnectionCommon::set_buffer_limit()`] for more information.
135 pub fn set_buffer_limit(&mut self, limit: Option<usize>) {
136 match self {
137 Self::Client(client) => client.set_buffer_limit(limit),
138 Self::Server(server) => server.set_buffer_limit(limit),
139 }
140 }
141
142 /// Sends a TLS1.3 `key_update` message to refresh a connection's keys
143 ///
144 /// See [`ConnectionCommon::refresh_traffic_keys()`] for more information.
145 pub fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
146 match self {
147 Self::Client(client) => client.refresh_traffic_keys(),
148 Self::Server(server) => server.refresh_traffic_keys(),
149 }
150 }
151 }
152
153 impl Deref for Connection {
154 type Target = CommonState;
155
156 fn deref(&self) -> &Self::Target {
157 match self {
158 Self::Client(conn) => &conn.core.common_state,
159 Self::Server(conn) => &conn.core.common_state,
160 }
161 }
162 }
163
164 impl DerefMut for Connection {
165 fn deref_mut(&mut self) -> &mut Self::Target {
166 match self {
167 Self::Client(conn) => &mut conn.core.common_state,
168 Self::Server(conn) => &mut conn.core.common_state,
169 }
170 }
171 }
172
173 /// A structure that implements [`std::io::Read`] for reading plaintext.
174 pub struct Reader<'a> {
175 pub(super) received_plaintext: &'a mut ChunkVecBuffer,
176 pub(super) has_received_close_notify: bool,
177 pub(super) has_seen_eof: bool,
178 }
179
180 impl<'a> Reader<'a> {
181 /// Check the connection's state if no bytes are available for reading.
182 fn check_no_bytes_state(&self) -> io::Result<()> {
183 match (self.has_received_close_notify, self.has_seen_eof) {
184 // cleanly closed; don't care about TCP EOF: express this as Ok(0)
185 (true, _) => Ok(()),
186 // unclean closure
187 (false, true) => Err(io::Error::new(
188 io::ErrorKind::UnexpectedEof,
189 UNEXPECTED_EOF_MESSAGE,
190 )),
191 // connection still going, but needs more data: signal `WouldBlock` so that
192 // the caller knows this
193 (false, false) => Err(io::ErrorKind::WouldBlock.into()),
194 }
195 }
196
197 /// Obtain a chunk of plaintext data received from the peer over this TLS connection.
198 ///
199 /// This method consumes `self` so that it can return a slice whose lifetime is bounded by
200 /// the [`ConnectionCommon`] that created this `Reader`.
201 pub fn into_first_chunk(self) -> io::Result<&'a [u8]> {
202 match self.received_plaintext.chunk() {
203 Some(chunk) => Ok(chunk),
204 None => {
205 self.check_no_bytes_state()?;
206 Ok(&[])
207 }
208 }
209 }
210 }
211
212 impl Read for Reader<'_> {
213 /// Obtain plaintext data received from the peer over this TLS connection.
214 ///
215 /// If the peer closes the TLS session cleanly, this returns `Ok(0)` once all
216 /// the pending data has been read. No further data can be received on that
217 /// connection, so the underlying TCP connection should be half-closed too.
218 ///
219 /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
220 /// `close_notify` alert) this function returns a `std::io::Error` of type
221 /// `ErrorKind::UnexpectedEof` once any pending data has been read.
222 ///
223 /// Note that support for `close_notify` varies in peer TLS libraries: many do not
224 /// support it and uncleanly close the TCP connection (this might be
225 /// vulnerable to truncation attacks depending on the application protocol).
226 /// This means applications using rustls must both handle EOF
227 /// from this function, *and* unexpected EOF of the underlying TCP connection.
228 ///
229 /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
230 ///
231 /// You may learn the number of bytes available at any time by inspecting
232 /// the return of [`Connection::process_new_packets`].
233 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
234 let len = self.received_plaintext.read(buf)?;
235 if len > 0 || buf.is_empty() {
236 return Ok(len);
237 }
238
239 self.check_no_bytes_state()
240 .map(|()| len)
241 }
242
243 /// Obtain plaintext data received from the peer over this TLS connection.
244 ///
245 /// If the peer closes the TLS session, this returns `Ok(())` without filling
246 /// any more of the buffer once all the pending data has been read. No further
247 /// data can be received on that connection, so the underlying TCP connection
248 /// should be half-closed too.
249 ///
250 /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
251 /// `close_notify` alert) this function returns a `std::io::Error` of type
252 /// `ErrorKind::UnexpectedEof` once any pending data has been read.
253 ///
254 /// Note that support for `close_notify` varies in peer TLS libraries: many do not
255 /// support it and uncleanly close the TCP connection (this might be
256 /// vulnerable to truncation attacks depending on the application protocol).
257 /// This means applications using rustls must both handle EOF
258 /// from this function, *and* unexpected EOF of the underlying TCP connection.
259 ///
260 /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
261 ///
262 /// You may learn the number of bytes available at any time by inspecting
263 /// the return of [`Connection::process_new_packets`].
264 #[cfg(read_buf)]
265 fn read_buf(&mut self, mut cursor: core::io::BorrowedCursor<'_, u8>) -> io::Result<()> {
266 let before = cursor.written();
267 self.received_plaintext
268 .read_buf(cursor.reborrow())?;
269 let len = cursor.written() - before;
270 if len > 0 || cursor.capacity() == 0 {
271 return Ok(());
272 }
273
274 self.check_no_bytes_state()
275 }
276 }
277
278 impl BufRead for Reader<'_> {
279 /// Obtain a chunk of plaintext data received from the peer over this TLS connection.
280 /// This reads the same data as [`Reader::read()`], but returns a reference instead of
281 /// copying the data.
282 ///
283 /// The caller should call [`Reader::consume()`] afterward to advance the buffer.
284 ///
285 /// See [`Reader::into_first_chunk()`] for a version of this function that returns a
286 /// buffer with a longer lifetime.
287 fn fill_buf(&mut self) -> io::Result<&[u8]> {
288 Reader {
289 // reborrow
290 received_plaintext: self.received_plaintext,
291 ..*self
292 }
293 .into_first_chunk()
294 }
295
296 fn consume(&mut self, amt: usize) {
297 self.received_plaintext
298 .consume_first_chunk(amt)
299 }
300 }
301
302 const UNEXPECTED_EOF_MESSAGE: &str = "peer closed connection without sending TLS close_notify: \
303https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#unexpected-eof";
304
305 /// A structure that implements [`std::io::Write`] for writing plaintext.
306 pub struct Writer<'a> {
307 sink: &'a mut dyn PlaintextSink,
308 }
309
310 impl<'a> Writer<'a> {
311 /// Create a new Writer.
312 ///
313 /// This is not an external interface. Get one of these objects
314 /// from [`Connection::writer`].
315 pub(crate) fn new(sink: &'a mut dyn PlaintextSink) -> Self {
316 Writer { sink }
317 }
318 }
319
320 impl io::Write for Writer<'_> {
321 /// Send the plaintext `buf` to the peer, encrypting
322 /// and authenticating it. Once this function succeeds
323 /// you should call [`Connection::write_tls`] which will output the
324 /// corresponding TLS records.
325 ///
326 /// This function buffers plaintext sent before the
327 /// TLS handshake completes, and sends it as soon
328 /// as it can. See [`ConnectionCommon::set_buffer_limit`] to control
329 /// the size of this buffer.
330 ///
331 /// If the connection previously encountered a fatal error (for example, while
332 /// processing received data in [`Connection::process_new_packets`]), this returns
333 /// that error, even if `buf` is empty.
334 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
335 self.sink.write(buf)
336 }
337
338 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
339 self.sink.write_vectored(bufs)
340 }
341
342 /// This does not do any I/O, but returns the fatal error the connection previously
343 /// encountered, if any.
344 fn flush(&mut self) -> io::Result<()> {
345 self.sink.flush()
346 }
347 }
348
349 /// Internal trait implemented by the [`ServerConnection`]/[`ClientConnection`]
350 /// allowing them to be the subject of a [`Writer`].
351 ///
352 /// [`ServerConnection`]: crate::ServerConnection
353 /// [`ClientConnection`]: crate::ClientConnection
354 pub(crate) trait PlaintextSink {
355 fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
356 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize>;
357 fn flush(&mut self) -> io::Result<()>;
358 }
359
360 impl<T> ConnectionCommon<T> {
361 /// Return the fatal error this connection previously encountered, if any.
362 fn check_error(&self) -> io::Result<()> {
363 match &self.core.state {
364 Ok(_) => Ok(()),
365 Err(err) => Err(io::Error::new(io::ErrorKind::InvalidData, err.clone())),
366 }
367 }
368
369 /// Send or buffer as much of `payload` as possible.
370 ///
371 /// This updates the TLS 1.3 traffic keys as needed between records.
372 fn send_plaintext(&mut self, payload: OutboundChunks<'_>) -> usize {
373 let mut len = 0;
374 loop {
375 len += self
376 .core
377 .common_state
378 .buffer_plaintext(payload.split_at(len).1, &mut self.sendable_plaintext);
379 if !self.core.maybe_refresh_traffic_keys() || len == payload.len() {
380 return len;
381 }
382 }
383 }
384 }
385
386 impl<T> PlaintextSink for ConnectionCommon<T> {
387 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
388 self.check_error()?;
389 Ok(self.send_plaintext(buf.into()))
390 }
391
392 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
393 self.check_error()?;
394 let payload_owner: Vec<&[u8]>;
395 let payload = match bufs.len() {
396 0 => return Ok(0),
397 1 => OutboundChunks::Single(bufs[0].deref()),
398 _ => {
399 payload_owner = bufs
400 .iter()
401 .map(|io_slice| io_slice.deref())
402 .collect();
403
404 OutboundChunks::new(&payload_owner)
405 }
406 };
407 Ok(self.send_plaintext(payload))
408 }
409
410 fn flush(&mut self) -> io::Result<()> {
411 self.check_error()
412 }
413 }
414}
415
416#[cfg(feature = "std")]
417pub use connection::{Connection, Reader, Writer};
418
419#[derive(Debug)]
420pub(crate) struct ConnectionRandoms {
421 pub(crate) client: [u8; 32],
422 pub(crate) server: [u8; 32],
423}
424
425impl ConnectionRandoms {
426 pub(crate) fn new(client: Random, server: Random) -> Self {
427 Self {
428 client: client.0,
429 server: server.0,
430 }
431 }
432}
433
434/// Interface shared by client and server connections.
435pub struct ConnectionCommon<Data> {
436 pub(crate) core: ConnectionCore<Data>,
437 deframer_buffer: DeframerVecBuffer,
438 sendable_plaintext: ChunkVecBuffer,
439}
440
441impl<Data> ConnectionCommon<Data> {
442 /// Processes any new packets read by a previous call to
443 /// [`Connection::read_tls`].
444 ///
445 /// Errors from this function relate to TLS protocol errors, and
446 /// are fatal to the connection. Future calls after an error will do
447 /// no new work and will return the same error. After an error is
448 /// received from [`process_new_packets`], you should not call [`read_tls`]
449 /// any more (it will fill up buffers to no purpose). However, you
450 /// may call the other methods on the connection, including `write`,
451 /// `send_close_notify`, and `write_tls`. Most likely you will want to
452 /// call `write_tls` to send any alerts queued by the error and then
453 /// close the underlying connection.
454 ///
455 /// Success from this function comes with some sundry state data
456 /// about the connection.
457 ///
458 /// [`read_tls`]: Connection::read_tls
459 /// [`process_new_packets`]: Connection::process_new_packets
460 #[inline]
461 pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
462 self.core
463 .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)
464 }
465
466 /// Derives key material from the agreed connection secrets.
467 ///
468 /// This function fills in `output` with `output.len()` bytes of key
469 /// material derived from the master session secret using `label`
470 /// and `context` for diversification. Ownership of the buffer is taken
471 /// by the function and returned via the Ok result to ensure no key
472 /// material leaks if the function fails.
473 ///
474 /// See RFC5705 for more details on what this does and is for.
475 ///
476 /// For TLS1.3 connections, this function does not use the
477 /// "early" exporter at any point.
478 ///
479 /// This function fails if called prior to the handshake completing;
480 /// check with [`CommonState::is_handshaking`] first.
481 ///
482 /// This function fails if `output.len()` is zero.
483 #[inline]
484 pub fn export_keying_material<T: AsMut<[u8]>>(
485 &self,
486 output: T,
487 label: &[u8],
488 context: Option<&[u8]>,
489 ) -> Result<T, Error> {
490 self.core
491 .export_keying_material(output, label, context)
492 }
493
494 /// Extract secrets, so they can be used when configuring kTLS, for example.
495 /// Should be used with care as it exposes secret key material.
496 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
497 self.core.dangerous_extract_secrets()
498 }
499
500 /// Sets a limit on the internal buffers used to buffer
501 /// unsent plaintext (prior to completing the TLS handshake)
502 /// and unsent TLS records. This limit acts only on application
503 /// data written through [`Connection::writer`].
504 ///
505 /// By default the limit is 64KB. The limit can be set
506 /// at any time, even if the current buffer use is higher.
507 ///
508 /// [`None`] means no limit applies, and will mean that written
509 /// data is buffered without bound -- it is up to the application
510 /// to appropriately schedule its plaintext and TLS writes to bound
511 /// memory usage.
512 ///
513 /// For illustration: `Some(1)` means a limit of one byte applies:
514 /// [`Connection::writer`] will accept only one byte, encrypt it and
515 /// add a TLS header. Once this is sent via [`Connection::write_tls`],
516 /// another byte may be sent.
517 ///
518 /// # Internal write-direction buffering
519 /// rustls has two buffers whose size are bounded by this setting:
520 ///
521 /// ## Buffering of unsent plaintext data prior to handshake completion
522 ///
523 /// Calls to [`Connection::writer`] before or during the handshake
524 /// are buffered (up to the limit specified here). Once the
525 /// handshake completes this data is encrypted and the resulting
526 /// TLS records are added to the outgoing buffer.
527 ///
528 /// ## Buffering of outgoing TLS records
529 ///
530 /// This buffer is used to store TLS records that rustls needs to
531 /// send to the peer. It is used in these two circumstances:
532 ///
533 /// - by [`Connection::process_new_packets`] when a handshake or alert
534 /// TLS record needs to be sent.
535 /// - by [`Connection::writer`] post-handshake: the plaintext is
536 /// encrypted and the resulting TLS record is buffered.
537 ///
538 /// This buffer is emptied by [`Connection::write_tls`].
539 ///
540 /// [`Connection::writer`]: crate::Connection::writer
541 /// [`Connection::write_tls`]: crate::Connection::write_tls
542 /// [`Connection::process_new_packets`]: crate::Connection::process_new_packets
543 pub fn set_buffer_limit(&mut self, limit: Option<usize>) {
544 self.sendable_plaintext.set_limit(limit);
545 self.sendable_tls.set_limit(limit);
546 }
547
548 /// Sends a TLS1.3 `key_update` message to refresh a connection's keys.
549 ///
550 /// This call refreshes our encryption keys. Once the peer receives the message,
551 /// it refreshes _its_ encryption and decryption keys and sends a response.
552 /// Once we receive that response, we refresh our decryption keys to match.
553 /// At the end of this process, keys in both directions have been refreshed.
554 ///
555 /// Note that this process does not happen synchronously: this call just
556 /// arranges that the `key_update` message will be included in the next
557 /// `write_tls` output.
558 ///
559 /// This fails with `Error::HandshakeNotComplete` if called before the initial
560 /// handshake is complete, or if a version prior to TLS1.3 is negotiated.
561 ///
562 /// # Usage advice
563 /// Note that other implementations (including rustls) may enforce limits on
564 /// the number of `key_update` messages allowed on a given connection to prevent
565 /// denial of service. Therefore, this should be called sparingly.
566 ///
567 /// rustls implicitly and automatically refreshes traffic keys when needed
568 /// according to the selected cipher suite's cryptographic constraints. There
569 /// is therefore no need to call this manually to avoid cryptographic keys
570 /// "wearing out".
571 ///
572 /// The main reason to call this manually is to roll keys when it is known
573 /// a connection will be idle for a long period.
574 pub fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
575 self.core.refresh_traffic_keys()
576 }
577}
578
579#[cfg(feature = "std")]
580impl<Data> ConnectionCommon<Data> {
581 /// Returns an object that allows reading plaintext.
582 pub fn reader(&mut self) -> Reader<'_> {
583 let common = &mut self.core.common_state;
584 Reader {
585 received_plaintext: &mut common.received_plaintext,
586 // Are we done? i.e., have we processed all received messages, and received a
587 // close_notify to indicate that no new messages will arrive?
588 has_received_close_notify: common.has_received_close_notify,
589 has_seen_eof: common.has_seen_eof,
590 }
591 }
592
593 /// Returns an object that allows writing plaintext.
594 pub fn writer(&mut self) -> Writer<'_> {
595 Writer::new(self)
596 }
597
598 /// This function uses `io` to complete any outstanding IO for
599 /// this connection.
600 ///
601 /// This is a convenience function which solely uses other parts
602 /// of the public API.
603 ///
604 /// What this means depends on the connection state:
605 ///
606 /// - If the connection [`is_handshaking`], then IO is performed until
607 /// the handshake is complete.
608 /// - Otherwise, if [`wants_write`] is true, [`write_tls`] is invoked
609 /// until it is all written.
610 /// - Otherwise, if [`wants_read`] is true, [`read_tls`] is invoked
611 /// once.
612 ///
613 /// The return value is the number of bytes read from and written
614 /// to `io`, respectively. Once both `read()` and `write()` yield `WouldBlock`,
615 /// this function will propagate the error.
616 ///
617 /// Errors from TLS record handling (i.e., from [`process_new_packets`])
618 /// are wrapped in an `io::ErrorKind::InvalidData`-kind error.
619 ///
620 /// [`is_handshaking`]: CommonState::is_handshaking
621 /// [`wants_read`]: CommonState::wants_read
622 /// [`wants_write`]: CommonState::wants_write
623 /// [`write_tls`]: ConnectionCommon::write_tls
624 /// [`read_tls`]: ConnectionCommon::read_tls
625 /// [`process_new_packets`]: ConnectionCommon::process_new_packets
626 pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
627 where
628 Self: Sized,
629 T: io::Read + io::Write,
630 {
631 let mut eof = false;
632 let mut wrlen = 0;
633 let mut rdlen = 0;
634 loop {
635 let (mut blocked_write, mut blocked_read) = (None, None);
636 let until_handshaked = self.is_handshaking();
637
638 if !self.wants_write() && !self.wants_read() {
639 // We will make no further progress.
640 return Ok((rdlen, wrlen));
641 }
642
643 while self.wants_write() {
644 match self.write_tls(io) {
645 Ok(0) => {
646 io.flush()?;
647 return Ok((rdlen, wrlen)); // EOF.
648 }
649 Ok(n) => wrlen += n,
650 Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
651 blocked_write = Some(err);
652 break;
653 }
654 Err(err) => return Err(err),
655 }
656 }
657 if wrlen > 0 {
658 io.flush()?;
659 }
660
661 if !until_handshaked && wrlen > 0 {
662 return Ok((rdlen, wrlen));
663 }
664
665 // If we want to write, but are WouldBlocked by the underlying IO, *and*
666 // have no desire to read; that is everything.
667 if let (Some(_), false) = (&blocked_write, self.wants_read()) {
668 return match wrlen {
669 0 => Err(blocked_write.unwrap()),
670 _ => Ok((rdlen, wrlen)),
671 };
672 }
673
674 while !eof && self.wants_read() {
675 let read_size = match self.read_tls(io) {
676 Ok(0) => {
677 eof = true;
678 Some(0)
679 }
680 Ok(n) => {
681 rdlen += n;
682 Some(n)
683 }
684 Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
685 blocked_read = Some(err);
686 break;
687 }
688 Err(err) if err.kind() == io::ErrorKind::Interrupted => None, // nothing to do
689 Err(err) => return Err(err),
690 };
691 if read_size.is_some() {
692 break;
693 }
694 }
695
696 if let Err(e) = self.process_new_packets() {
697 // In case we have an alert to send describing this error, try a last-gasp
698 // write -- but don't predate the primary error.
699 let _ignored = self.write_tls(io);
700 let _ignored = io.flush();
701 return Err(io::Error::new(io::ErrorKind::InvalidData, e));
702 };
703
704 // If we want to read, but are WouldBlocked by the underlying IO, *and*
705 // have no desire to write; that is everything.
706 if let (Some(_), false) = (&blocked_read, self.wants_write()) {
707 return match rdlen {
708 0 => Err(blocked_read.unwrap()),
709 _ => Ok((rdlen, wrlen)),
710 };
711 }
712
713 // if we're doing IO until handshaked, and we believe we've finished handshaking,
714 // but process_new_packets() has queued TLS data to send, loop around again to write
715 // the queued messages.
716 if until_handshaked && !self.is_handshaking() && self.wants_write() {
717 continue;
718 }
719
720 let blocked = blocked_write.zip(blocked_read);
721 match (eof, until_handshaked, self.is_handshaking(), blocked) {
722 (_, true, false, _) => return Ok((rdlen, wrlen)),
723 (_, _, _, Some((e, _))) if rdlen == 0 && wrlen == 0 => return Err(e),
724 (_, false, _, _) => return Ok((rdlen, wrlen)),
725 (true, true, true, _) => return Err(io::Error::from(io::ErrorKind::UnexpectedEof)),
726 _ => {}
727 }
728 }
729 }
730
731 /// Extract the first handshake message.
732 ///
733 /// This is a shortcut to the `process_new_packets()` -> `process_msg()` ->
734 /// `process_handshake_messages()` path, specialized for the first handshake message.
735 pub(crate) fn first_handshake_message(&mut self) -> Result<Option<Message<'static>>, Error> {
736 let mut buffer_progress = self.core.hs_deframer.progress();
737
738 let res = self
739 .core
740 .deframe(
741 None,
742 self.deframer_buffer.filled_mut(),
743 &mut buffer_progress,
744 )
745 .map(|opt| opt.map(|pm| Message::try_from(pm).map(|m| m.into_owned())));
746
747 match res? {
748 Some(Ok(msg)) => {
749 self.deframer_buffer
750 .discard(buffer_progress.take_discard());
751 Ok(Some(msg))
752 }
753 Some(Err(err)) => Err(self.send_fatal_alert(AlertDescription::DecodeError, err)),
754 None => Ok(None),
755 }
756 }
757
758 pub(crate) fn replace_state(&mut self, new: Box<dyn State<Data>>) {
759 self.core.state = Ok(new);
760 }
761
762 /// Read TLS content from `rd` into the internal buffer.
763 ///
764 /// Due to the internal buffering, `rd` can supply TLS messages in arbitrary-sized chunks (like
765 /// a socket or pipe might).
766 ///
767 /// You should call [`process_new_packets()`] each time a call to this function succeeds in order
768 /// to empty the incoming TLS data buffer.
769 ///
770 /// This function returns `Ok(0)` when the underlying `rd` does so. This typically happens when
771 /// a socket is cleanly closed, or a file is at EOF. Errors may result from the IO done through
772 /// `rd`; additionally, errors of `ErrorKind::Other` are emitted to signal backpressure:
773 ///
774 /// * In order to empty the incoming TLS data buffer, you should call [`process_new_packets()`]
775 /// each time a call to this function succeeds.
776 /// * In order to empty the incoming plaintext data buffer, you should empty it through
777 /// the [`reader()`] after the call to [`process_new_packets()`].
778 ///
779 /// This function also returns `Ok(0)` once a `close_notify` alert has been successfully
780 /// received. No additional data is ever read in this state.
781 ///
782 /// [`process_new_packets()`]: ConnectionCommon::process_new_packets
783 /// [`reader()`]: ConnectionCommon::reader
784 pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
785 if self.received_plaintext.is_full() {
786 return Err(io::Error::new(
787 io::ErrorKind::Other,
788 "received plaintext buffer full",
789 ));
790 }
791
792 if self.has_received_close_notify {
793 return Ok(0);
794 }
795
796 let res = self
797 .deframer_buffer
798 .read(rd, self.core.hs_deframer.is_active());
799 if let Ok(0) = res {
800 self.has_seen_eof = true;
801 }
802 res
803 }
804
805 /// Writes TLS messages to `wr`.
806 ///
807 /// On success, this function returns `Ok(n)` where `n` is a number of bytes written to `wr`
808 /// (after encoding and encryption).
809 ///
810 /// After this function returns, the connection buffer may not yet be fully flushed. The
811 /// [`CommonState::wants_write`] function can be used to check if the output buffer is empty.
812 pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
813 self.sendable_tls.write_to(wr)
814 }
815}
816
817impl<'a, Data> From<&'a mut ConnectionCommon<Data>> for Context<'a, Data> {
818 fn from(conn: &'a mut ConnectionCommon<Data>) -> Self {
819 Self {
820 common: &mut conn.core.common_state,
821 data: &mut conn.core.data,
822 sendable_plaintext: Some(&mut conn.sendable_plaintext),
823 }
824 }
825}
826
827impl<T> Deref for ConnectionCommon<T> {
828 type Target = CommonState;
829
830 fn deref(&self) -> &Self::Target {
831 &self.core.common_state
832 }
833}
834
835impl<T> DerefMut for ConnectionCommon<T> {
836 fn deref_mut(&mut self) -> &mut Self::Target {
837 &mut self.core.common_state
838 }
839}
840
841impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
842 fn from(core: ConnectionCore<Data>) -> Self {
843 Self {
844 core,
845 deframer_buffer: DeframerVecBuffer::default(),
846 sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
847 }
848 }
849}
850
851/// Interface shared by unbuffered client and server connections.
852pub struct UnbufferedConnectionCommon<Data> {
853 pub(crate) core: ConnectionCore<Data>,
854 wants_write: bool,
855 emitted_peer_closed_state: bool,
856}
857
858impl<Data> From<ConnectionCore<Data>> for UnbufferedConnectionCommon<Data> {
859 fn from(core: ConnectionCore<Data>) -> Self {
860 Self {
861 core,
862 wants_write: false,
863 emitted_peer_closed_state: false,
864 }
865 }
866}
867
868impl<Data> UnbufferedConnectionCommon<Data> {
869 /// Extract secrets, so they can be used when configuring kTLS, for example.
870 /// Should be used with care as it exposes secret key material.
871 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
872 self.core.dangerous_extract_secrets()
873 }
874}
875
876impl<T> Deref for UnbufferedConnectionCommon<T> {
877 type Target = CommonState;
878
879 fn deref(&self) -> &Self::Target {
880 &self.core.common_state
881 }
882}
883
884pub(crate) struct ConnectionCore<Data> {
885 pub(crate) state: Result<Box<dyn State<Data>>, Error>,
886 pub(crate) data: Data,
887 pub(crate) common_state: CommonState,
888 pub(crate) hs_deframer: HandshakeDeframer,
889
890 /// We limit consecutive empty fragments to avoid a route for the peer to send
891 /// us significant but fruitless traffic.
892 seen_consecutive_empty_fragments: u8,
893}
894
895impl<Data> ConnectionCore<Data> {
896 pub(crate) fn new(state: Box<dyn State<Data>>, data: Data, common_state: CommonState) -> Self {
897 Self {
898 state: Ok(state),
899 data,
900 common_state,
901 hs_deframer: HandshakeDeframer::default(),
902 seen_consecutive_empty_fragments: 0,
903 }
904 }
905
906 pub(crate) fn process_new_packets(
907 &mut self,
908 deframer_buffer: &mut DeframerVecBuffer,
909 sendable_plaintext: &mut ChunkVecBuffer,
910 ) -> Result<IoState, Error> {
911 let mut state = match mem::replace(&mut self.state, Err(Error::HandshakeNotComplete)) {
912 Ok(state) => state,
913 Err(e) => {
914 self.state = Err(e.clone());
915 return Err(e);
916 }
917 };
918
919 let mut buffer_progress = self.hs_deframer.progress();
920
921 loop {
922 let res = self.deframe(
923 Some(&*state),
924 deframer_buffer.filled_mut(),
925 &mut buffer_progress,
926 );
927
928 let opt_msg = match res {
929 Ok(opt_msg) => opt_msg,
930 Err(e) => {
931 self.state = Err(e.clone());
932 deframer_buffer.discard(buffer_progress.take_discard());
933 return Err(e);
934 }
935 };
936
937 let Some(msg) = opt_msg else {
938 break;
939 };
940
941 match self.process_msg(msg, state, Some(sendable_plaintext)) {
942 Ok(new) => state = new,
943 Err(e) => {
944 self.state = Err(e.clone());
945 deframer_buffer.discard(buffer_progress.take_discard());
946 return Err(e);
947 }
948 }
949
950 if self
951 .common_state
952 .has_received_close_notify
953 {
954 // "Any data received after a closure alert has been received MUST be ignored."
955 // -- <https://datatracker.ietf.org/doc/html/rfc8446#section-6.1>
956 // This is data that has already been accepted in `read_tls`.
957 buffer_progress.add_discard(deframer_buffer.filled().len());
958 break;
959 }
960
961 deframer_buffer.discard(buffer_progress.take_discard());
962 }
963
964 deframer_buffer.discard(buffer_progress.take_discard());
965 self.state = Ok(state);
966 Ok(self.common_state.current_io_state())
967 }
968
969 /// Pull a message out of the deframer and send any messages that need to be sent as a result.
970 fn deframe<'b>(
971 &mut self,
972 state: Option<&dyn State<Data>>,
973 buffer: &'b mut [u8],
974 buffer_progress: &mut BufferProgress,
975 ) -> Result<Option<InboundPlainMessage<'b>>, Error> {
976 // before processing any more of `buffer`, return any extant messages from `hs_deframer`
977 if self.hs_deframer.has_message_ready() {
978 Ok(self.take_handshake_message(buffer, buffer_progress))
979 } else {
980 self.process_more_input(state, buffer, buffer_progress)
981 }
982 }
983
984 fn take_handshake_message<'b>(
985 &mut self,
986 buffer: &'b mut [u8],
987 buffer_progress: &mut BufferProgress,
988 ) -> Option<InboundPlainMessage<'b>> {
989 let message = self
990 .hs_deframer
991 .iter(buffer)
992 .next()
993 .map(|(message, discard)| {
994 buffer_progress.add_discard(discard);
995 message
996 });
997 self.common_state.aligned_handshake = self.hs_deframer.is_aligned();
998 message
999 }
1000
1001 fn process_more_input<'b>(
1002 &mut self,
1003 state: Option<&dyn State<Data>>,
1004 buffer: &'b mut [u8],
1005 buffer_progress: &mut BufferProgress,
1006 ) -> Result<Option<InboundPlainMessage<'b>>, Error> {
1007 let version_is_tls13 = matches!(
1008 self.common_state.negotiated_version,
1009 Some(ProtocolVersion::TLSv1_3)
1010 );
1011
1012 let locator = Locator::new(buffer);
1013
1014 loop {
1015 let mut iter = DeframerIter::new(&mut buffer[buffer_progress.processed()..]);
1016
1017 let (message, processed) = loop {
1018 let message = match iter.next().transpose() {
1019 Ok(Some(message)) => message,
1020 Ok(None) => return Ok(None),
1021 Err(err) => return Err(self.handle_deframe_error(err, state)),
1022 };
1023
1024 let allowed_plaintext = match message.typ {
1025 // CCS messages are always plaintext.
1026 ContentType::ChangeCipherSpec => true,
1027 // Alerts are allowed to be plaintext if-and-only-if:
1028 // * The negotiated protocol version is TLS 1.3. - In TLS 1.2 it is unambiguous when
1029 // keying changes based on the CCS message. Only TLS 1.3 requires these heuristics.
1030 // * We have not yet decrypted any messages from the peer - if we have we don't
1031 // expect any plaintext.
1032 // * The payload size is indicative of a plaintext alert message.
1033 ContentType::Alert
1034 if version_is_tls13
1035 && !self
1036 .common_state
1037 .record_layer
1038 .has_decrypted()
1039 && message.payload.len() <= 2 =>
1040 {
1041 true
1042 }
1043 // In other circumstances, we expect all messages to be encrypted.
1044 _ => false,
1045 };
1046
1047 if allowed_plaintext && !self.hs_deframer.is_active() {
1048 break (message.into_plain_message(), iter.bytes_consumed());
1049 }
1050
1051 let message = match self
1052 .common_state
1053 .record_layer
1054 .decrypt_incoming(message)
1055 {
1056 // failed decryption during trial decryption is not allowed to be
1057 // interleaved with partial handshake data.
1058 Ok(None) if !self.hs_deframer.is_aligned() => {
1059 return Err(
1060 PeerMisbehaved::RejectedEarlyDataInterleavedWithHandshakeMessage.into(),
1061 );
1062 }
1063
1064 // failed decryption during trial decryption.
1065 Ok(None) => continue,
1066
1067 Ok(Some(message)) => message,
1068
1069 Err(err) => return Err(self.handle_deframe_error(err, state)),
1070 };
1071
1072 let Decrypted {
1073 want_close_before_decrypt,
1074 plaintext,
1075 } = message;
1076
1077 if want_close_before_decrypt {
1078 self.common_state.send_close_notify();
1079 }
1080
1081 break (plaintext, iter.bytes_consumed());
1082 };
1083
1084 if !self.hs_deframer.is_aligned() && message.typ != ContentType::Handshake {
1085 // "Handshake messages MUST NOT be interleaved with other record
1086 // types. That is, if a handshake message is split over two or more
1087 // records, there MUST NOT be any other records between them."
1088 // https://www.rfc-editor.org/rfc/rfc8446#section-5.1
1089 return Err(PeerMisbehaved::MessageInterleavedWithHandshakeMessage.into());
1090 }
1091
1092 match message.payload.len() {
1093 0 => {
1094 if self.seen_consecutive_empty_fragments
1095 == ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX
1096 {
1097 return Err(PeerMisbehaved::TooManyEmptyFragments.into());
1098 }
1099 self.seen_consecutive_empty_fragments += 1;
1100 }
1101 _ => {
1102 self.seen_consecutive_empty_fragments = 0;
1103 }
1104 };
1105
1106 buffer_progress.add_processed(processed);
1107
1108 // do an end-run around the borrow checker, converting `message` (containing
1109 // a borrowed slice) to an unborrowed one (containing a `Range` into the
1110 // same buffer). the reborrow happens inside the branch that returns the
1111 // message.
1112 //
1113 // is fixed by -Zpolonius
1114 // https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md#problem-case-3-conditional-control-flow-across-functions
1115 let unborrowed = InboundUnborrowedMessage::unborrow(&locator, message);
1116
1117 if unborrowed.typ != ContentType::Handshake {
1118 let message = unborrowed.reborrow(&Delocator::new(buffer));
1119 buffer_progress.add_discard(processed);
1120 return Ok(Some(message));
1121 }
1122
1123 let message = unborrowed.reborrow(&Delocator::new(buffer));
1124 self.hs_deframer
1125 .input_message(message, &locator, buffer_progress.processed());
1126 self.hs_deframer.coalesce(buffer)?;
1127
1128 self.common_state.aligned_handshake = self.hs_deframer.is_aligned();
1129
1130 if self.hs_deframer.has_message_ready() {
1131 // trial decryption finishes with the first handshake message after it started.
1132 self.common_state
1133 .record_layer
1134 .finish_trial_decryption();
1135
1136 return Ok(self.take_handshake_message(buffer, buffer_progress));
1137 }
1138 }
1139 }
1140
1141 fn handle_deframe_error(&mut self, error: Error, state: Option<&dyn State<Data>>) -> Error {
1142 match error {
1143 error @ Error::InvalidMessage(_) => {
1144 if self.common_state.is_quic() {
1145 self.common_state.quic.alert = Some(AlertDescription::DecodeError);
1146 error
1147 } else {
1148 self.common_state
1149 .send_fatal_alert(AlertDescription::DecodeError, error)
1150 }
1151 }
1152 Error::PeerSentOversizedRecord => self
1153 .common_state
1154 .send_fatal_alert(AlertDescription::RecordOverflow, error),
1155 Error::DecryptError => {
1156 if let Some(state) = state {
1157 state.handle_decrypt_error();
1158 }
1159 self.common_state
1160 .send_fatal_alert(AlertDescription::BadRecordMac, error)
1161 }
1162 Error::PeerMisbehaved(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec) => self
1163 .common_state
1164 .send_fatal_alert(AlertDescription::UnexpectedMessage, error),
1165
1166 error => error,
1167 }
1168 }
1169
1170 fn process_msg(
1171 &mut self,
1172 msg: InboundPlainMessage<'_>,
1173 state: Box<dyn State<Data>>,
1174 sendable_plaintext: Option<&mut ChunkVecBuffer>,
1175 ) -> Result<Box<dyn State<Data>>, Error> {
1176 // Drop CCS messages during handshake in TLS1.3
1177 if msg.typ == ContentType::ChangeCipherSpec
1178 && !self
1179 .common_state
1180 .may_receive_application_data
1181 && self.common_state.is_tls13()
1182 {
1183 if !msg.is_valid_ccs() {
1184 // "An implementation which receives any other change_cipher_spec value or
1185 // which receives a protected change_cipher_spec record MUST abort the
1186 // handshake with an "unexpected_message" alert."
1187 return Err(self.common_state.send_fatal_alert(
1188 AlertDescription::UnexpectedMessage,
1189 PeerMisbehaved::IllegalMiddleboxChangeCipherSpec,
1190 ));
1191 }
1192
1193 self.common_state
1194 .received_tls13_change_cipher_spec()?;
1195 trace!("Dropping CCS");
1196 return Ok(state);
1197 }
1198
1199 // Now we can fully parse the message payload.
1200 let msg = match Message::try_from(msg) {
1201 Ok(msg) => msg,
1202 Err(err) => {
1203 return Err(self
1204 .common_state
1205 .send_fatal_alert(AlertDescription::from(err), err));
1206 }
1207 };
1208
1209 // For alerts, we have separate logic.
1210 if let MessagePayload::Alert(alert) = &msg.payload {
1211 self.common_state.process_alert(alert)?;
1212 return Ok(state);
1213 }
1214
1215 self.common_state
1216 .process_main_protocol(msg, state, &mut self.data, sendable_plaintext)
1217 }
1218
1219 pub(crate) fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
1220 Ok(self
1221 .dangerous_into_kernel_connection()?
1222 .0)
1223 }
1224
1225 pub(crate) fn dangerous_into_kernel_connection(
1226 self,
1227 ) -> Result<(ExtractedSecrets, KernelConnection<Data>), Error> {
1228 if !self
1229 .common_state
1230 .enable_secret_extraction
1231 {
1232 return Err(Error::General("Secret extraction is disabled".into()));
1233 }
1234
1235 if self.common_state.is_handshaking() {
1236 return Err(Error::HandshakeNotComplete);
1237 }
1238
1239 if !self
1240 .common_state
1241 .sendable_tls
1242 .is_empty()
1243 {
1244 return Err(Error::General(
1245 "cannot convert into an KernelConnection while there are still buffered TLS records to send"
1246 .into()
1247 ));
1248 }
1249
1250 let state = self.state?;
1251
1252 let record_layer = &self.common_state.record_layer;
1253 let secrets = state.extract_secrets()?;
1254 let secrets = ExtractedSecrets {
1255 tx: (record_layer.write_seq(), secrets.tx),
1256 rx: (record_layer.read_seq(), secrets.rx),
1257 };
1258
1259 let state = state.into_external_state()?;
1260 let external = KernelConnection::new(state, self.common_state)?;
1261
1262 Ok((secrets, external))
1263 }
1264
1265 pub(crate) fn export_keying_material<T: AsMut<[u8]>>(
1266 &self,
1267 mut output: T,
1268 label: &[u8],
1269 context: Option<&[u8]>,
1270 ) -> Result<T, Error> {
1271 if output.as_mut().is_empty() {
1272 return Err(Error::General(
1273 "export_keying_material with zero-length output".into(),
1274 ));
1275 }
1276
1277 match self.state.as_ref() {
1278 Ok(st) => st
1279 .export_keying_material(output.as_mut(), label, context)
1280 .map(|_| output),
1281 Err(e) => Err(e.clone()),
1282 }
1283 }
1284
1285 /// Trigger a `refresh_traffic_keys` if required by `CommonState`.
1286 ///
1287 /// Returns whether the traffic keys were updated.
1288 fn maybe_refresh_traffic_keys(&mut self) -> bool {
1289 mem::take(
1290 &mut self
1291 .common_state
1292 .refresh_traffic_keys_pending,
1293 ) && self.refresh_traffic_keys().is_ok()
1294 }
1295
1296 fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
1297 match &mut self.state {
1298 Ok(st) => st.send_key_update_request(&mut self.common_state),
1299 Err(e) => Err(e.clone()),
1300 }
1301 }
1302}
1303
1304/// Data specific to the peer's side (client or server).
1305pub trait SideData: Debug {}
1306
1307/// An InboundPlainMessage which does not borrow its payload, but
1308/// references a range that can later be borrowed.
1309struct InboundUnborrowedMessage {
1310 typ: ContentType,
1311 version: ProtocolVersion,
1312 bounds: Range<usize>,
1313}
1314
1315impl InboundUnborrowedMessage {
1316 fn unborrow(locator: &Locator, msg: InboundPlainMessage<'_>) -> Self {
1317 Self {
1318 typ: msg.typ,
1319 version: msg.version,
1320 bounds: locator.locate(msg.payload),
1321 }
1322 }
1323
1324 fn reborrow<'b>(self, delocator: &Delocator<'b>) -> InboundPlainMessage<'b> {
1325 InboundPlainMessage {
1326 typ: self.typ,
1327 version: self.version,
1328 payload: delocator.slice_from_range(&self.bounds),
1329 }
1330 }
1331}
1332
1333/// cf. BoringSSL's `kMaxEmptyRecords`
1334/// <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L124-L128>
1335const ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX: u8 = 32;