Coverage Report

Created: 2026-10-28 06:24

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