clia_rustls_mod/conn.rs
1use alloc::boxed::Box;
2use core::fmt::Debug;
3use core::mem;
4use core::ops::{Deref, DerefMut};
5#[cfg(feature = "std")]
6use std::io;
7
8use crate::common_state::{CommonState, Context, IoState, State, DEFAULT_BUFFER_LIMIT};
9use crate::enums::{AlertDescription, ContentType};
10use crate::error::{Error, PeerMisbehaved};
11#[cfg(feature = "logging")]
12use crate::log::trace;
13use crate::msgs::deframer::{Deframed, DeframerSliceBuffer, DeframerVecBuffer, MessageDeframer};
14use crate::msgs::handshake::Random;
15use crate::msgs::message::{InboundPlainMessage, Message, MessagePayload};
16use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
17use crate::vecbuf::ChunkVecBuffer;
18
19pub(crate) mod unbuffered;
20
21#[cfg(feature = "std")]
22mod connection {
23 use alloc::vec::Vec;
24 use core::fmt::Debug;
25 use core::ops::{Deref, DerefMut};
26 use std::io;
27
28 use crate::common_state::{CommonState, IoState};
29 use crate::error::Error;
30 use crate::msgs::message::OutboundChunks;
31 use crate::suites::ExtractedSecrets;
32 use crate::vecbuf::ChunkVecBuffer;
33 use crate::ConnectionCommon;
34
35 /// A client or server connection.
36 #[derive(Debug)]
37 pub enum Connection {
38 /// A client connection
39 Client(crate::client::ClientConnection),
40 /// A server connection
41 Server(crate::server::ServerConnection),
42 }
43
44 impl Connection {
45 /// Read TLS content from `rd`.
46 ///
47 /// See [`ConnectionCommon::read_tls()`] for more information.
48 pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
49 match self {
50 Self::Client(conn) => conn.read_tls(rd),
51 Self::Server(conn) => conn.read_tls(rd),
52 }
53 }
54
55 /// Writes TLS messages to `wr`.
56 ///
57 /// See [`ConnectionCommon::write_tls()`] for more information.
58 pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
59 self.sendable_tls.write_to(wr)
60 }
61
62 /// Returns an object that allows reading plaintext.
63 pub fn reader(&mut self) -> Reader {
64 match self {
65 Self::Client(conn) => conn.reader(),
66 Self::Server(conn) => conn.reader(),
67 }
68 }
69
70 /// Returns an object that allows writing plaintext.
71 pub fn writer(&mut self) -> Writer {
72 match self {
73 Self::Client(conn) => Writer::new(&mut **conn),
74 Self::Server(conn) => Writer::new(&mut **conn),
75 }
76 }
77
78 /// Processes any new packets read by a previous call to [`Connection::read_tls`].
79 ///
80 /// See [`ConnectionCommon::process_new_packets()`] for more information.
81 pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
82 match self {
83 Self::Client(conn) => conn.process_new_packets(),
84 Self::Server(conn) => conn.process_new_packets(),
85 }
86 }
87
88 /// Derives key material from the agreed connection secrets.
89 ///
90 /// See [`ConnectionCommon::export_keying_material()`] for more information.
91 pub fn export_keying_material<T: AsMut<[u8]>>(
92 &self,
93 output: T,
94 label: &[u8],
95 context: Option<&[u8]>,
96 ) -> Result<T, Error> {
97 match self {
98 Self::Client(conn) => conn.export_keying_material(output, label, context),
99 Self::Server(conn) => conn.export_keying_material(output, label, context),
100 }
101 }
102
103 /// This function uses `io` to complete any outstanding IO for this connection.
104 ///
105 /// See [`ConnectionCommon::complete_io()`] for more information.
106 pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
107 where
108 Self: Sized,
109 T: io::Read + io::Write,
110 {
111 match self {
112 Self::Client(conn) => conn.complete_io(io),
113 Self::Server(conn) => conn.complete_io(io),
114 }
115 }
116
117 /// Extract secrets, so they can be used when configuring kTLS, for example.
118 /// Should be used with care as it exposes secret key material.
119 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
120 match self {
121 Self::Client(client) => client.dangerous_extract_secrets(),
122 Self::Server(server) => server.dangerous_extract_secrets(),
123 }
124 }
125
126 /// Sets a limit on the internal buffers
127 ///
128 /// See [`ConnectionCommon::set_buffer_limit()`] for more information.
129 pub fn set_buffer_limit(&mut self, limit: Option<usize>) {
130 match self {
131 Self::Client(client) => client.set_buffer_limit(limit),
132 Self::Server(server) => server.set_buffer_limit(limit),
133 }
134 }
135 }
136
137 impl Deref for Connection {
138 type Target = CommonState;
139
140 fn deref(&self) -> &Self::Target {
141 match self {
142 Self::Client(conn) => &conn.core.common_state,
143 Self::Server(conn) => &conn.core.common_state,
144 }
145 }
146 }
147
148 impl DerefMut for Connection {
149 fn deref_mut(&mut self) -> &mut Self::Target {
150 match self {
151 Self::Client(conn) => &mut conn.core.common_state,
152 Self::Server(conn) => &mut conn.core.common_state,
153 }
154 }
155 }
156
157 /// A structure that implements [`std::io::Read`] for reading plaintext.
158 pub struct Reader<'a> {
159 pub(super) received_plaintext: &'a mut ChunkVecBuffer,
160 pub(super) peer_cleanly_closed: bool,
161 pub(super) has_seen_eof: bool,
162 }
163
164 impl<'a> io::Read for Reader<'a> {
165 /// Obtain plaintext data received from the peer over this TLS connection.
166 ///
167 /// If the peer closes the TLS session cleanly, this returns `Ok(0)` once all
168 /// the pending data has been read. No further data can be received on that
169 /// connection, so the underlying TCP connection should be half-closed too.
170 ///
171 /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
172 /// `close_notify` alert) this function returns a `std::io::Error` of type
173 /// `ErrorKind::UnexpectedEof` once any pending data has been read.
174 ///
175 /// Note that support for `close_notify` varies in peer TLS libraries: many do not
176 /// support it and uncleanly close the TCP connection (this might be
177 /// vulnerable to truncation attacks depending on the application protocol).
178 /// This means applications using rustls must both handle EOF
179 /// from this function, *and* unexpected EOF of the underlying TCP connection.
180 ///
181 /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
182 ///
183 /// You may learn the number of bytes available at any time by inspecting
184 /// the return of [`Connection::process_new_packets`].
185 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
186 let len = self.received_plaintext.read(buf)?;
187
188 if len == 0 && !buf.is_empty() {
189 // No bytes available:
190 match (self.peer_cleanly_closed, self.has_seen_eof) {
191 // cleanly closed; don't care about TCP EOF: express this as Ok(0)
192 (true, _) => {}
193 // unclean closure
194 (false, true) => {
195 return Err(io::Error::new(
196 io::ErrorKind::UnexpectedEof,
197 UNEXPECTED_EOF_MESSAGE,
198 ))
199 }
200 // connection still going, but needs more data: signal `WouldBlock` so that
201 // the caller knows this
202 (false, false) => return Err(io::ErrorKind::WouldBlock.into()),
203 }
204 }
205
206 Ok(len)
207 }
208
209 /// Obtain plaintext data received from the peer over this TLS connection.
210 ///
211 /// If the peer closes the TLS session, this returns `Ok(())` without filling
212 /// any more of the buffer once all the pending data has been read. No further
213 /// data can be received on that connection, so the underlying TCP connection
214 /// should be half-closed too.
215 ///
216 /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
217 /// `close_notify` alert) this function returns a `std::io::Error` of type
218 /// `ErrorKind::UnexpectedEof` once any pending data has been read.
219 ///
220 /// Note that support for `close_notify` varies in peer TLS libraries: many do not
221 /// support it and uncleanly close the TCP connection (this might be
222 /// vulnerable to truncation attacks depending on the application protocol).
223 /// This means applications using rustls must both handle EOF
224 /// from this function, *and* unexpected EOF of the underlying TCP connection.
225 ///
226 /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
227 ///
228 /// You may learn the number of bytes available at any time by inspecting
229 /// the return of [`Connection::process_new_packets`].
230 #[cfg(read_buf)]
231 fn read_buf(&mut self, mut cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> {
232 let before = cursor.written();
233 self.received_plaintext
234 .read_buf(cursor.reborrow())?;
235 let len = cursor.written() - before;
236
237 if len == 0 && cursor.capacity() > 0 {
238 // No bytes available:
239 match (self.peer_cleanly_closed, self.has_seen_eof) {
240 // cleanly closed; don't care about TCP EOF: express this as Ok(0)
241 (true, _) => {}
242 // unclean closure
243 (false, true) => {
244 return Err(io::Error::new(
245 io::ErrorKind::UnexpectedEof,
246 UNEXPECTED_EOF_MESSAGE,
247 ));
248 }
249 // connection still going, but need more data: signal `WouldBlock` so that
250 // the caller knows this
251 (false, false) => return Err(io::ErrorKind::WouldBlock.into()),
252 }
253 }
254
255 Ok(())
256 }
257 }
258
259 const UNEXPECTED_EOF_MESSAGE: &str =
260 "peer closed connection without sending TLS close_notify: \
261https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#unexpected-eof";
262
263 /// A structure that implements [`std::io::Write`] for writing plaintext.
264 pub struct Writer<'a> {
265 sink: &'a mut dyn PlaintextSink,
266 }
267
268 impl<'a> Writer<'a> {
269 /// Create a new Writer.
270 ///
271 /// This is not an external interface. Get one of these objects
272 /// from [`Connection::writer`].
273 pub(crate) fn new(sink: &'a mut dyn PlaintextSink) -> Self {
274 Writer { sink }
275 }
276 }
277
278 impl<'a> io::Write for Writer<'a> {
279 /// Send the plaintext `buf` to the peer, encrypting
280 /// and authenticating it. Once this function succeeds
281 /// you should call [`Connection::write_tls`] which will output the
282 /// corresponding TLS records.
283 ///
284 /// This function buffers plaintext sent before the
285 /// TLS handshake completes, and sends it as soon
286 /// as it can. See [`ConnectionCommon::set_buffer_limit`] to control
287 /// the size of this buffer.
288 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
289 self.sink.write(buf)
290 }
291
292 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
293 self.sink.write_vectored(bufs)
294 }
295
296 fn flush(&mut self) -> io::Result<()> {
297 self.sink.flush()
298 }
299 }
300
301 /// Internal trait implemented by the [`ServerConnection`]/[`ClientConnection`]
302 /// allowing them to be the subject of a [`Writer`].
303 ///
304 /// [`ServerConnection`]: crate::ServerConnection
305 /// [`ClientConnection`]: crate::ClientConnection
306 pub(crate) trait PlaintextSink {
307 fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
308 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize>;
309 fn flush(&mut self) -> io::Result<()>;
310 }
311
312 impl<T> PlaintextSink for ConnectionCommon<T> {
313 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
314 Ok(self
315 .core
316 .common_state
317 .buffer_plaintext(buf.into(), &mut self.sendable_plaintext))
318 }
319
320 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
321 let payload_owner: Vec<&[u8]>;
322 let payload = match bufs.len() {
323 0 => return Ok(0),
324 1 => OutboundChunks::Single(bufs[0].deref()),
325 _ => {
326 payload_owner = bufs
327 .iter()
328 .map(|io_slice| io_slice.deref())
329 .collect();
330
331 OutboundChunks::new(&payload_owner)
332 }
333 };
334 Ok(self
335 .core
336 .common_state
337 .buffer_plaintext(payload, &mut self.sendable_plaintext))
338 }
339
340 fn flush(&mut self) -> io::Result<()> {
341 Ok(())
342 }
343 }
344}
345
346#[cfg(feature = "std")]
347pub use connection::{Connection, Reader, Writer};
348
349#[derive(Debug)]
350pub(crate) struct ConnectionRandoms {
351 pub(crate) client: [u8; 32],
352 pub(crate) server: [u8; 32],
353}
354
355/// How many ChangeCipherSpec messages we accept and drop in TLS1.3 handshakes.
356/// The spec says 1, but implementations (namely the boringssl test suite) get
357/// this wrong. BoringSSL itself accepts up to 32.
358static TLS13_MAX_DROPPED_CCS: u8 = 2u8;
359
360impl ConnectionRandoms {
361 pub(crate) fn new(client: Random, server: Random) -> Self {
362 Self {
363 client: client.0,
364 server: server.0,
365 }
366 }
367}
368
369/// Interface shared by client and server connections.
370pub struct ConnectionCommon<Data> {
371 pub(crate) core: ConnectionCore<Data>,
372 deframer_buffer: DeframerVecBuffer,
373 sendable_plaintext: ChunkVecBuffer,
374}
375
376impl<Data> ConnectionCommon<Data> {
377 /// Processes any new packets read by a previous call to
378 /// [`Connection::read_tls`].
379 ///
380 /// Errors from this function relate to TLS protocol errors, and
381 /// are fatal to the connection. Future calls after an error will do
382 /// no new work and will return the same error. After an error is
383 /// received from [`process_new_packets`], you should not call [`read_tls`]
384 /// any more (it will fill up buffers to no purpose). However, you
385 /// may call the other methods on the connection, including `write`,
386 /// `send_close_notify`, and `write_tls`. Most likely you will want to
387 /// call `write_tls` to send any alerts queued by the error and then
388 /// close the underlying connection.
389 ///
390 /// Success from this function comes with some sundry state data
391 /// about the connection.
392 ///
393 /// [`read_tls`]: Connection::read_tls
394 /// [`process_new_packets`]: Connection::process_new_packets
395 #[inline]
396 pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
397 self.core
398 .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)
399 }
400
401 /// Derives key material from the agreed connection secrets.
402 ///
403 /// This function fills in `output` with `output.len()` bytes of key
404 /// material derived from the master session secret using `label`
405 /// and `context` for diversification. Ownership of the buffer is taken
406 /// by the function and returned via the Ok result to ensure no key
407 /// material leaks if the function fails.
408 ///
409 /// See RFC5705 for more details on what this does and is for.
410 ///
411 /// For TLS1.3 connections, this function does not use the
412 /// "early" exporter at any point.
413 ///
414 /// This function fails if called prior to the handshake completing;
415 /// check with [`CommonState::is_handshaking`] first.
416 ///
417 /// This function fails if `output.len()` is zero.
418 #[inline]
419 pub fn export_keying_material<T: AsMut<[u8]>>(
420 &self,
421 output: T,
422 label: &[u8],
423 context: Option<&[u8]>,
424 ) -> Result<T, Error> {
425 self.core
426 .export_keying_material(output, label, context)
427 }
428
429 /// Extract secrets, so they can be used when configuring kTLS, for example.
430 /// Should be used with care as it exposes secret key material.
431 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
432 if !self.enable_secret_extraction {
433 return Err(Error::General("Secret extraction is disabled".into()));
434 }
435
436 let st = self.core.state?;
437
438 let record_layer = self.core.common_state.record_layer;
439 let PartiallyExtractedSecrets { tx, rx } = st.extract_secrets()?;
440 Ok(ExtractedSecrets {
441 tx: (record_layer.write_seq(), tx),
442 rx: (record_layer.read_seq(), rx),
443 })
444 }
445
446 /// Sets a limit on the internal buffers used to buffer
447 /// unsent plaintext (prior to completing the TLS handshake)
448 /// and unsent TLS records. This limit acts only on application
449 /// data written through [`Connection::writer`].
450 ///
451 /// By default the limit is 64KB. The limit can be set
452 /// at any time, even if the current buffer use is higher.
453 ///
454 /// [`None`] means no limit applies, and will mean that written
455 /// data is buffered without bound -- it is up to the application
456 /// to appropriately schedule its plaintext and TLS writes to bound
457 /// memory usage.
458 ///
459 /// For illustration: `Some(1)` means a limit of one byte applies:
460 /// [`Connection::writer`] will accept only one byte, encrypt it and
461 /// add a TLS header. Once this is sent via [`Connection::write_tls`],
462 /// another byte may be sent.
463 ///
464 /// # Internal write-direction buffering
465 /// rustls has two buffers whose size are bounded by this setting:
466 ///
467 /// ## Buffering of unsent plaintext data prior to handshake completion
468 ///
469 /// Calls to [`Connection::writer`] before or during the handshake
470 /// are buffered (up to the limit specified here). Once the
471 /// handshake completes this data is encrypted and the resulting
472 /// TLS records are added to the outgoing buffer.
473 ///
474 /// ## Buffering of outgoing TLS records
475 ///
476 /// This buffer is used to store TLS records that rustls needs to
477 /// send to the peer. It is used in these two circumstances:
478 ///
479 /// - by [`Connection::process_new_packets`] when a handshake or alert
480 /// TLS record needs to be sent.
481 /// - by [`Connection::writer`] post-handshake: the plaintext is
482 /// encrypted and the resulting TLS record is buffered.
483 ///
484 /// This buffer is emptied by [`Connection::write_tls`].
485 ///
486 /// [`Connection::writer`]: crate::Connection::writer
487 /// [`Connection::write_tls`]: crate::Connection::write_tls
488 /// [`Connection::process_new_packets`]: crate::Connection::process_new_packets
489 pub fn set_buffer_limit(&mut self, limit: Option<usize>) {
490 self.sendable_plaintext.set_limit(limit);
491 self.sendable_tls.set_limit(limit);
492 }
493}
494
495#[cfg(feature = "std")]
496impl<Data> ConnectionCommon<Data> {
497 /// Returns an object that allows reading plaintext.
498 pub fn reader(&mut self) -> Reader {
499 let common = &mut self.core.common_state;
500 Reader {
501 received_plaintext: &mut common.received_plaintext,
502 // Are we done? i.e., have we processed all received messages, and received a
503 // close_notify to indicate that no new messages will arrive?
504 peer_cleanly_closed: common.has_received_close_notify
505 && !self.deframer_buffer.has_pending(),
506 has_seen_eof: common.has_seen_eof,
507 }
508 }
509
510 /// Returns an object that allows writing plaintext.
511 pub fn writer(&mut self) -> Writer {
512 Writer::new(self)
513 }
514
515 /// This function uses `io` to complete any outstanding IO for
516 /// this connection.
517 ///
518 /// This is a convenience function which solely uses other parts
519 /// of the public API.
520 ///
521 /// What this means depends on the connection state:
522 ///
523 /// - If the connection [`is_handshaking`], then IO is performed until
524 /// the handshake is complete.
525 /// - Otherwise, if [`wants_write`] is true, [`write_tls`] is invoked
526 /// until it is all written.
527 /// - Otherwise, if [`wants_read`] is true, [`read_tls`] is invoked
528 /// once.
529 ///
530 /// The return value is the number of bytes read from and written
531 /// to `io`, respectively.
532 ///
533 /// This function will block if `io` blocks.
534 ///
535 /// Errors from TLS record handling (i.e., from [`process_new_packets`])
536 /// are wrapped in an `io::ErrorKind::InvalidData`-kind error.
537 ///
538 /// [`is_handshaking`]: CommonState::is_handshaking
539 /// [`wants_read`]: CommonState::wants_read
540 /// [`wants_write`]: CommonState::wants_write
541 /// [`write_tls`]: ConnectionCommon::write_tls
542 /// [`read_tls`]: ConnectionCommon::read_tls
543 /// [`process_new_packets`]: ConnectionCommon::process_new_packets
544 pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
545 where
546 Self: Sized,
547 T: io::Read + io::Write,
548 {
549 let mut eof = false;
550 let mut wrlen = 0;
551 let mut rdlen = 0;
552
553 loop {
554 let until_handshaked = self.is_handshaking();
555
556 while self.wants_write() {
557 wrlen += self.write_tls(io)?;
558 }
559 io.flush()?;
560
561 if !until_handshaked && wrlen > 0 {
562 return Ok((rdlen, wrlen));
563 }
564
565 while !eof && self.wants_read() {
566 let read_size = match self.read_tls(io) {
567 Ok(0) => {
568 eof = true;
569 Some(0)
570 }
571 Ok(n) => {
572 rdlen += n;
573 Some(n)
574 }
575 Err(ref err) if err.kind() == io::ErrorKind::Interrupted => None, // nothing to do
576 Err(err) => return Err(err),
577 };
578 if read_size.is_some() {
579 break;
580 }
581 }
582
583 match self.process_new_packets() {
584 Ok(_) => {}
585 Err(e) => {
586 // In case we have an alert to send describing this error,
587 // try a last-gasp write -- but don't predate the primary
588 // error.
589 let _ignored = self.write_tls(io);
590 let _ignored = io.flush();
591
592 return Err(io::Error::new(io::ErrorKind::InvalidData, e));
593 }
594 };
595
596 // if we're doing IO until handshaked, and we believe we've finished handshaking,
597 // but process_new_packets() has queued TLS data to send, loop around again to write
598 // the queued messages.
599 if until_handshaked && !self.is_handshaking() && self.wants_write() {
600 continue;
601 }
602
603 match (eof, until_handshaked, self.is_handshaking()) {
604 (_, true, false) => return Ok((rdlen, wrlen)),
605 (_, false, _) => return Ok((rdlen, wrlen)),
606 (true, true, true) => return Err(io::Error::from(io::ErrorKind::UnexpectedEof)),
607 (..) => {}
608 }
609 }
610 }
611
612 /// Extract the first handshake message.
613 ///
614 /// This is a shortcut to the `process_new_packets()` -> `process_msg()` ->
615 /// `process_handshake_messages()` path, specialized for the first handshake message.
616 pub(crate) fn first_handshake_message(&mut self) -> Result<Option<Message<'static>>, Error> {
617 let mut deframer_buffer = self.deframer_buffer.borrow();
618 let res = self
619 .core
620 .deframe(None, &mut deframer_buffer)
621 .map(|opt| opt.map(|pm| Message::try_from(pm).map(|m| m.into_owned())));
622 let discard = deframer_buffer.pending_discard();
623 self.deframer_buffer.discard(discard);
624
625 match res? {
626 Some(Ok(msg)) => Ok(Some(msg)),
627 Some(Err(err)) => Err(self.send_fatal_alert(AlertDescription::DecodeError, err)),
628 None => Ok(None),
629 }
630 }
631
632 pub(crate) fn replace_state(&mut self, new: Box<dyn State<Data>>) {
633 self.core.state = Ok(new);
634 }
635
636 /// Read TLS content from `rd` into the internal buffer.
637 ///
638 /// Due to the internal buffering, `rd` can supply TLS messages in arbitrary-sized chunks (like
639 /// a socket or pipe might).
640 ///
641 /// You should call [`process_new_packets()`] each time a call to this function succeeds in order
642 /// to empty the incoming TLS data buffer.
643 ///
644 /// This function returns `Ok(0)` when the underlying `rd` does so. This typically happens when
645 /// a socket is cleanly closed, or a file is at EOF. Errors may result from the IO done through
646 /// `rd`; additionally, errors of `ErrorKind::Other` are emitted to signal backpressure:
647 ///
648 /// * In order to empty the incoming TLS data buffer, you should call [`process_new_packets()`]
649 /// each time a call to this function succeeds.
650 /// * In order to empty the incoming plaintext data buffer, you should empty it through
651 /// the [`reader()`] after the call to [`process_new_packets()`].
652 ///
653 /// [`process_new_packets()`]: ConnectionCommon::process_new_packets
654 /// [`reader()`]: ConnectionCommon::reader
655 pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
656 if self.received_plaintext.is_full() {
657 return Err(io::Error::new(
658 io::ErrorKind::Other,
659 "received plaintext buffer full",
660 ));
661 }
662
663 let res = self
664 .core
665 .message_deframer
666 .read(rd, &mut self.deframer_buffer);
667 if let Ok(0) = res {
668 self.has_seen_eof = true;
669 }
670 res
671 }
672
673 /// Writes TLS messages to `wr`.
674 ///
675 /// On success, this function returns `Ok(n)` where `n` is a number of bytes written to `wr`
676 /// (after encoding and encryption).
677 ///
678 /// After this function returns, the connection buffer may not yet be fully flushed. The
679 /// [`CommonState::wants_write`] function can be used to check if the output buffer is empty.
680 pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
681 self.sendable_tls.write_to(wr)
682 }
683}
684
685impl<'a, Data> From<&'a mut ConnectionCommon<Data>> for Context<'a, Data> {
686 fn from(conn: &'a mut ConnectionCommon<Data>) -> Self {
687 Self {
688 common: &mut conn.core.common_state,
689 data: &mut conn.core.data,
690 sendable_plaintext: Some(&mut conn.sendable_plaintext),
691 }
692 }
693}
694
695impl<T> Deref for ConnectionCommon<T> {
696 type Target = CommonState;
697
698 fn deref(&self) -> &Self::Target {
699 &self.core.common_state
700 }
701}
702
703impl<T> DerefMut for ConnectionCommon<T> {
704 fn deref_mut(&mut self) -> &mut Self::Target {
705 &mut self.core.common_state
706 }
707}
708
709impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
710 fn from(core: ConnectionCore<Data>) -> Self {
711 Self {
712 core,
713 deframer_buffer: DeframerVecBuffer::default(),
714 sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
715 }
716 }
717}
718
719/// Interface shared by unbuffered client and server connections.
720pub struct UnbufferedConnectionCommon<Data> {
721 pub(crate) core: ConnectionCore<Data>,
722 wants_write: bool,
723}
724
725impl<Data> From<ConnectionCore<Data>> for UnbufferedConnectionCommon<Data> {
726 fn from(core: ConnectionCore<Data>) -> Self {
727 Self {
728 core,
729 wants_write: false,
730 }
731 }
732}
733
734pub(crate) struct ConnectionCore<Data> {
735 pub(crate) state: Result<Box<dyn State<Data>>, Error>,
736 pub(crate) data: Data,
737 pub(crate) common_state: CommonState,
738 pub(crate) message_deframer: MessageDeframer,
739}
740
741impl<Data> ConnectionCore<Data> {
742 pub(crate) fn new(state: Box<dyn State<Data>>, data: Data, common_state: CommonState) -> Self {
743 Self {
744 state: Ok(state),
745 data,
746 common_state,
747 message_deframer: MessageDeframer::default(),
748 }
749 }
750
751 pub(crate) fn process_new_packets(
752 &mut self,
753 deframer_buffer: &mut DeframerVecBuffer,
754 sendable_plaintext: &mut ChunkVecBuffer,
755 ) -> Result<IoState, Error> {
756 let mut state = match mem::replace(&mut self.state, Err(Error::HandshakeNotComplete)) {
757 Ok(state) => state,
758 Err(e) => {
759 self.state = Err(e.clone());
760 return Err(e);
761 }
762 };
763
764 let mut discard = 0;
765 loop {
766 let mut borrowed_buffer = deframer_buffer.borrow();
767 borrowed_buffer.queue_discard(discard);
768
769 let res = self.deframe(Some(&*state), &mut borrowed_buffer);
770 discard = borrowed_buffer.pending_discard();
771
772 let opt_msg = match res {
773 Ok(opt_msg) => opt_msg,
774 Err(e) => {
775 self.state = Err(e.clone());
776 deframer_buffer.discard(discard);
777 return Err(e);
778 }
779 };
780
781 let msg = match opt_msg {
782 Some(msg) => msg,
783 None => break,
784 };
785
786 match self.process_msg(msg, state, Some(sendable_plaintext)) {
787 Ok(new) => state = new,
788 Err(e) => {
789 self.state = Err(e.clone());
790 deframer_buffer.discard(discard);
791 return Err(e);
792 }
793 }
794 }
795
796 deframer_buffer.discard(discard);
797 self.state = Ok(state);
798 Ok(self.common_state.current_io_state())
799 }
800
801 /// Pull a message out of the deframer and send any messages that need to be sent as a result.
802 fn deframe<'b>(
803 &mut self,
804 state: Option<&dyn State<Data>>,
805 deframer_buffer: &mut DeframerSliceBuffer<'b>,
806 ) -> Result<Option<InboundPlainMessage<'b>>, Error> {
807 match self.message_deframer.pop(
808 &mut self.common_state.record_layer,
809 self.common_state.negotiated_version,
810 deframer_buffer,
811 ) {
812 Ok(Some(Deframed {
813 want_close_before_decrypt,
814 aligned,
815 trial_decryption_finished,
816 message,
817 })) => {
818 if want_close_before_decrypt {
819 self.common_state.send_close_notify();
820 }
821
822 if trial_decryption_finished {
823 self.common_state
824 .record_layer
825 .finish_trial_decryption();
826 }
827
828 self.common_state.aligned_handshake = aligned;
829 Ok(Some(message))
830 }
831 Ok(None) => Ok(None),
832 Err(err @ Error::InvalidMessage(_)) => {
833 if self.common_state.is_quic() {
834 self.common_state.quic.alert = Some(AlertDescription::DecodeError);
835 }
836
837 Err(if !self.common_state.is_quic() {
838 self.common_state
839 .send_fatal_alert(AlertDescription::DecodeError, err)
840 } else {
841 err
842 })
843 }
844 Err(err @ Error::PeerSentOversizedRecord) => Err(self
845 .common_state
846 .send_fatal_alert(AlertDescription::RecordOverflow, err)),
847 Err(err @ Error::DecryptError) => {
848 if let Some(state) = state {
849 state.handle_decrypt_error();
850 }
851 Err(self
852 .common_state
853 .send_fatal_alert(AlertDescription::BadRecordMac, err))
854 }
855 Err(e) => Err(e),
856 }
857 }
858
859 fn process_msg(
860 &mut self,
861 msg: InboundPlainMessage,
862 state: Box<dyn State<Data>>,
863 sendable_plaintext: Option<&mut ChunkVecBuffer>,
864 ) -> Result<Box<dyn State<Data>>, Error> {
865 // Drop CCS messages during handshake in TLS1.3
866 if msg.typ == ContentType::ChangeCipherSpec
867 && !self
868 .common_state
869 .may_receive_application_data
870 && self.common_state.is_tls13()
871 {
872 if !msg.is_valid_ccs()
873 || self.common_state.received_middlebox_ccs > TLS13_MAX_DROPPED_CCS
874 {
875 // "An implementation which receives any other change_cipher_spec value or
876 // which receives a protected change_cipher_spec record MUST abort the
877 // handshake with an "unexpected_message" alert."
878 return Err(self.common_state.send_fatal_alert(
879 AlertDescription::UnexpectedMessage,
880 PeerMisbehaved::IllegalMiddleboxChangeCipherSpec,
881 ));
882 } else {
883 self.common_state.received_middlebox_ccs += 1;
884 trace!("Dropping CCS");
885 return Ok(state);
886 }
887 }
888
889 // Now we can fully parse the message payload.
890 let msg = match Message::try_from(msg) {
891 Ok(msg) => msg,
892 Err(err) => {
893 return Err(self
894 .common_state
895 .send_fatal_alert(AlertDescription::DecodeError, err));
896 }
897 };
898
899 // For alerts, we have separate logic.
900 if let MessagePayload::Alert(alert) = &msg.payload {
901 self.common_state.process_alert(alert)?;
902 return Ok(state);
903 }
904
905 self.common_state
906 .process_main_protocol(msg, state, &mut self.data, sendable_plaintext)
907 }
908
909 pub(crate) fn export_keying_material<T: AsMut<[u8]>>(
910 &self,
911 mut output: T,
912 label: &[u8],
913 context: Option<&[u8]>,
914 ) -> Result<T, Error> {
915 if output.as_mut().is_empty() {
916 return Err(Error::General(
917 "export_keying_material with zero-length output".into(),
918 ));
919 }
920
921 match self.state.as_ref() {
922 Ok(st) => st
923 .export_keying_material(output.as_mut(), label, context)
924 .map(|_| output),
925 Err(e) => Err(e.clone()),
926 }
927 }
928}
929
930/// Data specific to the peer's side (client or server).
931pub trait SideData: Debug {}