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