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