Skip to main content

simoom_tls/tls/
conn.rs

1//! TLS 1.3 over records, sans-io: feed received bytes with [`Connection::read_tls`] and
2//! [`Connection::process_new_packets`], take bytes to send with [`Connection::tls_output`] /
3//! [`Connection::consume_tls_output`], and exchange plaintext with
4//! [`Connection::write_plaintext`] and [`Connection::read_plaintext`].
5//!
6//! Records are decrypted in place in the receive buffer and plaintext is sealed in place in the
7//! send buffer, so the steady state allocates nothing. Buffers are bounded: `read_tls` stops
8//! accepting bytes while two records are pending, and decryption pauses while 64 KiB of
9//! plaintext waits to be read.
10
11#[cfg(feature = "client")]
12use super::client::ClientHs;
13#[cfg(feature = "client")]
14use super::config::ClientConfig;
15use super::config::ServerConfig;
16use super::engine::{Engine, Event, HsReader};
17use super::keyschedule::{derive_secret, expand_label_vec, next_traffic_secret, traffic_key_iv};
18use super::record::{RecordCipher, MAX_CIPHERTEXT, MAX_PLAINTEXT};
19use super::server::ServerHs;
20use super::{alert, codec, content, hs, CipherSuite, Error, Level, NamedGroup, Result};
21use std::ops::{Deref, DerefMut};
22use std::sync::Arc;
23
24const MAX_RX: usize = 2 * (5 + MAX_CIPHERTEXT);
25const MAX_PLAIN_BUFFERED: usize = 64 * 1024;
26const MAX_PENDING_APP: usize = 1 << 20;
27/// Records sent under one key before an automatic KeyUpdate (well below the AES-GCM limit of
28/// 2^24.5 full-size records, RFC 8446 section 5.5).
29const KEY_UPDATE_AFTER: u64 = 1 << 23;
30/// Consecutive received records that deliver nothing to the application (empty application
31/// data, user_canceled warnings, KeyUpdates) before the peer is treated as hostile. Each one
32/// costs a decryption, and a KeyUpdate with update_requested also a reply, so a flood of them
33/// is a cheap way to burn CPU and grow output (the many-empty-records and alert-flood DoS
34/// class). OpenSSL uses the same bound for empty records.
35const MAX_IDLE_RECORDS: u32 = 32;
36
37/// What [`Connection::process_new_packets`] left for the caller.
38#[derive(Clone, Copy, Debug, PartialEq, Eq)]
39pub struct IoState {
40    pub tls_bytes_to_write: usize,
41    pub plaintext_bytes_to_read: usize,
42    pub peer_has_closed: bool,
43}
44
45/// One direction's traffic secret and record state, for kernel TLS.
46#[derive(Clone, Debug)]
47pub struct DirectionalSecret {
48    pub secret: Vec<u8>,
49    pub key: Vec<u8>,
50    pub iv: [u8; 12],
51    /// The sequence number of the next record.
52    pub seq: u64,
53}
54
55/// The state handed to kernel TLS (or another record layer) by
56/// [`Connection::export_traffic_secrets`].
57#[derive(Clone, Debug)]
58pub struct ExportedSecrets {
59    pub suite: CipherSuite,
60    pub tx: DirectionalSecret,
61    pub rx: DirectionalSecret,
62    /// Received bytes not yet processed (they continue the rx record stream).
63    pub unprocessed_input: Vec<u8>,
64    /// Decrypted plaintext the application has not read.
65    pub plaintext: Vec<u8>,
66}
67
68/// The state shared by [`ServerConnection`] and [`ClientConnection`].
69pub struct Connection {
70    engine: Engine,
71    hs: HsReader,
72    rx: Vec<u8>,
73    rx_pos: usize,
74    plain: Vec<u8>,
75    plain_pos: usize,
76    tx: Vec<u8>,
77    tx_pos: usize,
78    read: Option<RecordCipher>,
79    write: Option<RecordCipher>,
80    read_level: Level,
81    write_level: Level,
82    /// (client, server) traffic secrets per level.
83    secrets: [Option<(Vec<u8>, Vec<u8>)>; 3],
84    pending_hs: Vec<u8>,
85    pending_level: Level,
86    pending_app: Vec<u8>,
87    read_secret: Vec<u8>,
88    write_secret: Vec<u8>,
89    error: Option<Error>,
90    peer_closed: bool,
91    sent_close: bool,
92    ccs_seen: u8,
93    sent_first: bool,
94    /// Rejected 0-RTT bytes skipped so far (server); usize::MAX once skipping has ended.
95    early_skipped: usize,
96    /// Consecutive received records that delivered nothing ([`MAX_IDLE_RECORDS`]).
97    idle_records: u32,
98}
99
100impl std::fmt::Debug for Connection {
101    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102        f.debug_struct("Connection")
103            .field("client", &self.engine.is_client())
104            .field("handshaking", &self.is_handshaking())
105            .field("suite", &self.negotiated_cipher_suite())
106            .finish()
107    }
108}
109
110fn idx(l: Level) -> usize {
111    l as usize
112}
113
114impl Connection {
115    fn new(engine: Engine) -> Connection {
116        let mut c = Connection {
117            engine,
118            hs: HsReader::new(),
119            rx: Vec::new(),
120            rx_pos: 0,
121            plain: Vec::new(),
122            plain_pos: 0,
123            tx: Vec::new(),
124            tx_pos: 0,
125            read: None,
126            write: None,
127            read_level: Level::Initial,
128            write_level: Level::Initial,
129            secrets: [None, None, None],
130            pending_hs: Vec::new(),
131            pending_level: Level::Initial,
132            pending_app: Vec::new(),
133            read_secret: Vec::new(),
134            write_secret: Vec::new(),
135            error: None,
136            peer_closed: false,
137            sent_close: false,
138            ccs_seen: 0,
139            sent_first: false,
140            early_skipped: 0,
141            idle_records: 0,
142        };
143        if let Err(e) = c.drain_events() {
144            c.error = Some(e);
145        }
146        c
147    }
148
149    fn suite(&self) -> CipherSuite {
150        self.engine.shared().suite.expect("cipher suite negotiated")
151    }
152
153    fn local(&self, level: Level) -> Option<&Vec<u8>> {
154        let (c, s) = self.secrets[idx(level)].as_ref()?;
155        Some(if self.engine.is_client() { c } else { s })
156    }
157
158    fn remote(&self, level: Level) -> Option<&Vec<u8>> {
159        let (c, s) = self.secrets[idx(level)].as_ref()?;
160        Some(if self.engine.is_client() { s } else { c })
161    }
162
163    // ---------------------------------------------------------------- input
164
165    /// Buffers received TLS bytes and returns how many were taken (fewer than offered, possibly
166    /// zero, while earlier input waits to be processed or read).
167    pub fn read_tls(&mut self, data: &[u8]) -> usize {
168        if self.rx_pos > 0 {
169            self.rx.drain(..self.rx_pos);
170            self.rx_pos = 0;
171        }
172        let n = MAX_RX.saturating_sub(self.rx.len()).min(data.len());
173        self.rx.extend_from_slice(&data[..n]);
174        n
175    }
176
177    /// Processes buffered records. After an error every call returns the same error; the
178    /// alert for it (if any) is already queued in the TLS output.
179    pub fn process_new_packets(&mut self) -> Result<IoState> {
180        if let Some(e) = &self.error {
181            return Err(e.clone());
182        }
183        if let Err(e) = self.process() {
184            self.fail(e.clone());
185            return Err(e);
186        }
187        Ok(self.io_state())
188    }
189
190    fn io_state(&self) -> IoState {
191        IoState {
192            tls_bytes_to_write: self.tx.len() - self.tx_pos,
193            plaintext_bytes_to_read: self.plain.len() - self.plain_pos,
194            peer_has_closed: self.peer_closed,
195        }
196    }
197
198    fn fail(&mut self, e: Error) {
199        if self.error.is_none() {
200            if let Some(a) = e.alert_to_send() {
201                self.pending_hs.clear();
202                let _ = self.send_record(content::ALERT, &[2, a]);
203            }
204            self.error = Some(e);
205        }
206    }
207
208    fn process(&mut self) -> Result<()> {
209        loop {
210            if self.peer_closed || self.plain.len() - self.plain_pos >= MAX_PLAIN_BUFFERED {
211                break;
212            }
213            let avail = self.rx.len() - self.rx_pos;
214            if avail < 5 {
215                break;
216            }
217            let p = self.rx_pos;
218            let header: [u8; 5] = self.rx[p..p + 5].try_into().unwrap();
219            let typ = header[0];
220            let len = u16::from_be_bytes([header[3], header[4]]) as usize;
221            if !(content::CHANGE_CIPHER_SPEC..=content::APPLICATION_DATA).contains(&typ) || header[1] != 3 {
222                return Err(Error::proto(alert::UNEXPECTED_MESSAGE, "not a TLS record"));
223            }
224            if len > MAX_CIPHERTEXT {
225                return Err(Error::proto(alert::RECORD_OVERFLOW, "record too large"));
226            }
227            if avail < 5 + len {
228                break;
229            }
230            self.rx_pos += 5 + len;
231            let body = p + 5..p + 5 + len;
232            if typ == content::CHANGE_CIPHER_SPEC {
233                // TLS 1.2: the peer switches to its new keys
234                #[cfg(feature = "tls12")]
235                if self.rx[body.clone()] == [1] {
236                    if let Some(rc) = self.engine.shared_mut().pending_read12.take() {
237                        if !self.hs.is_empty() {
238                            return Err(Error::unexpected("ChangeCipherSpec inside a handshake message"));
239                        }
240                        self.read = Some(rc);
241                        self.read_level = Level::OneRtt;
242                        self.engine.shared_mut().expect_level = Level::OneRtt;
243                        continue;
244                    }
245                }
246                // TLS 1.3 middlebox compatibility: tolerated, unprotected, only during the handshake
247                if self.rx[body] != [1] || self.engine.shared().done || self.ccs_seen >= 2 || self.engine.shared().is_tls12() {
248                    return Err(Error::unexpected("ChangeCipherSpec"));
249                }
250                self.ccs_seen += 1;
251                continue;
252            }
253            let (inner, range) = match self.read.as_mut() {
254                Some(rc) => {
255                    if typ == content::ALERT && len == 2 {
256                        let d = self.rx[p + 6];
257                        return Err(if d == alert::CLOSE_NOTIFY { Error::unexpected("unprotected close_notify") } else { Error::PeerAlert(d) });
258                    }
259                    if !rc.is_tls12() && typ != content::APPLICATION_DATA {
260                        return Err(Error::unexpected("unprotected record after the key change"));
261                    }
262                    match rc.open_any(&header, &mut self.rx[body.clone()]) {
263                        Ok((t, off, n)) => {
264                            self.early_skipped = usize::MAX;
265                            let start = body.start + off;
266                            (t, start..start + n)
267                        }
268                        // rejected 0-RTT data under the client's early key: skip it
269                        Err(_) if self.skip_early(len) => continue,
270                        Err(e) => return Err(e),
271                    }
272                }
273                None => {
274                    if len > MAX_PLAINTEXT {
275                        return Err(Error::proto(alert::RECORD_OVERFLOW, "plaintext record too large"));
276                    }
277                    if typ == content::APPLICATION_DATA {
278                        if self.skip_early(len) {
279                            continue;
280                        }
281                        return Err(Error::unexpected("application data before the handshake keys"));
282                    }
283                    (typ, body)
284                }
285            };
286            match inner {
287                content::APPLICATION_DATA => {
288                    if self.read_level != Level::OneRtt || !self.engine.shared().done && !self.engine.is_client() {
289                        return Err(Error::unexpected("application data during the handshake"));
290                    }
291                    if range.is_empty() {
292                        self.idle_record()?;
293                        continue;
294                    }
295                    self.idle_records = 0;
296                    if self.plain_pos == self.plain.len() {
297                        self.plain.clear();
298                        self.plain_pos = 0;
299                    }
300                    self.plain.extend_from_slice(&self.rx[range]);
301                }
302                content::HANDSHAKE => {
303                    if range.is_empty() {
304                        return Err(Error::unexpected("empty handshake record"));
305                    }
306                    let data = self.rx[range].to_vec();
307                    self.handshake_data(&data)?;
308                }
309                content::ALERT => {
310                    if range.len() != 2 {
311                        return Err(Error::proto(alert::DECODE_ERROR, "malformed alert"));
312                    }
313                    let d = self.rx[range.start + 1];
314                    match d {
315                        alert::CLOSE_NOTIFY => self.peer_closed = true,
316                        alert::USER_CANCELED => self.idle_record()?,
317                        // TLS 1.2: a warning that the peer will not renegotiate (we never ask)
318                        alert::NO_RENEGOTIATION if self.engine.shared().is_tls12() && self.rx[range.start] == 1 => self.idle_record()?,
319                        _ => return Err(Error::PeerAlert(d)),
320                    }
321                }
322                _ => return Err(Error::unexpected("record content type")),
323            }
324        }
325        if self.rx_pos == self.rx.len() {
326            self.rx.clear();
327            self.rx_pos = 0;
328        }
329        Ok(())
330    }
331
332    /// Counts a received record that delivered nothing; too many in a row is fatal.
333    fn idle_record(&mut self) -> Result<()> {
334        self.idle_records += 1;
335        if self.idle_records > MAX_IDLE_RECORDS {
336            return Err(Error::unexpected("too many consecutive empty records, warnings or KeyUpdates"));
337        }
338        Ok(())
339    }
340
341    /// Whether a record of `len` bytes is rejected early data to skip (server, 0-RTT offered,
342    /// before the first record that decrypts with the client's handshake key, at most 64 KiB).
343    fn skip_early(&mut self, len: usize) -> bool {
344        const BUDGET: usize = 64 * 1024;
345        let sh = self.engine.shared();
346        if self.engine.is_client() || !sh.early_data_offered || self.read_level == Level::OneRtt || self.early_skipped > BUDGET - len.min(BUDGET) {
347            return false;
348        }
349        self.early_skipped += len;
350        true
351    }
352
353    fn handshake_data(&mut self, data: &[u8]) -> Result<()> {
354        self.hs.push(self.read_level, data)?;
355        let max = self.engine.shared().max_message;
356        while let Some((level, msg)) = self.hs.next(max)? {
357            #[cfg(feature = "tls12")]
358            if self.engine.shared().done && self.engine.shared().is_tls12() {
359                // renegotiation is refused (RFC 5746 allows a no_renegotiation warning)
360                self.idle_record()?;
361                let client = self.engine.is_client();
362                if (client && msg[0] == hs::HELLO_REQUEST && msg.len() == 4) || (!client && msg[0] == hs::CLIENT_HELLO) {
363                    if !self.sent_close {
364                        self.send_record(content::ALERT, &[1, alert::NO_RENEGOTIATION])?;
365                    }
366                    continue;
367                }
368                return Err(Error::unexpected("handshake message after the TLS 1.2 handshake"));
369            }
370            if self.engine.shared().done && msg[0] == hs::KEY_UPDATE {
371                self.idle_record()?;
372                self.key_update_received(&msg)?;
373                continue;
374            }
375            self.idle_records = 0;
376            self.engine.handle(level, &msg)?;
377            self.drain_events()?;
378            let want = self.engine.shared().expect_level;
379            if want != self.read_level {
380                if !self.hs.is_empty() {
381                    return Err(Error::unexpected("handshake data across a key change"));
382                }
383                let secret = self.remote(want).ok_or_else(|| Error::proto(alert::INTERNAL_ERROR, "missing read secret"))?.clone();
384                self.read = Some(RecordCipher::new(self.suite(), &secret));
385                self.read_level = want;
386                if want == Level::OneRtt {
387                    self.read_secret = secret;
388                }
389            }
390        }
391        Ok(())
392    }
393
394    fn key_update_received(&mut self, msg: &[u8]) -> Result<()> {
395        if msg.len() != 5 || msg[4] > 1 {
396            return Err(Error::proto(alert::DECODE_ERROR, "malformed KeyUpdate"));
397        }
398        if !self.hs.is_empty() {
399            return Err(Error::unexpected("KeyUpdate not at a record boundary"));
400        }
401        let suite = self.suite();
402        self.read_secret = next_traffic_secret(suite.hash(), &self.read_secret);
403        self.read = Some(RecordCipher::new(suite, &self.read_secret));
404        if msg[4] == 1 && !self.sent_close {
405            self.send_key_update(false)?;
406        }
407        Ok(())
408    }
409
410    // ---------------------------------------------------------------- output
411
412    fn drain_events(&mut self) -> Result<()> {
413        while let Some(ev) = self.engine.shared_mut().events.pop_front() {
414            match ev {
415                Event::Msg(level, m) => {
416                    if level != self.pending_level {
417                        self.flush_hs()?;
418                    }
419                    self.pending_level = level;
420                    self.pending_hs.extend_from_slice(&m);
421                }
422                Event::Ccs => {
423                    self.flush_hs()?;
424                    self.tx.extend_from_slice(&[content::CHANGE_CIPHER_SPEC, 3, 3, 0, 1, 1]);
425                }
426                #[cfg(feature = "tls12")]
427                Event::ChangeCipher12(rc) => {
428                    self.flush_hs()?;
429                    self.tx.extend_from_slice(&[content::CHANGE_CIPHER_SPEC, 3, 3, 0, 1, 1]);
430                    self.write = Some(rc);
431                    self.write_level = Level::OneRtt;
432                }
433                Event::Secrets { level, client, server } => {
434                    self.flush_hs()?;
435                    self.secrets[idx(level)] = Some((client, server));
436                    // After its Finished the server writes under its application traffic key
437                    // (RFC 8446 sections 4.4.4 and 7.1): the client reads with that key from
438                    // then on, so an alert for a rejected client certificate or Finished must
439                    // use it, or the client sees bad_record_mac instead of the alert.
440                    if level == Level::OneRtt && !self.engine.is_client() {
441                        self.switch_write(Level::OneRtt)?;
442                    }
443                }
444            }
445        }
446        self.flush_hs()?;
447        if self.engine.shared().done {
448            self.switch_write(Level::OneRtt)?;
449            if !self.pending_app.is_empty() {
450                let data = std::mem::take(&mut self.pending_app);
451                self.write_plaintext(&data)?;
452            }
453        }
454        Ok(())
455    }
456
457    fn switch_write(&mut self, level: Level) -> Result<()> {
458        if level == self.write_level {
459            return Ok(());
460        }
461        let secret = self.local(level).ok_or_else(|| Error::proto(alert::INTERNAL_ERROR, "missing write secret"))?.clone();
462        self.write = Some(RecordCipher::new(self.suite(), &secret));
463        self.write_level = level;
464        if level == Level::OneRtt {
465            self.write_secret = secret;
466        }
467        Ok(())
468    }
469
470    fn flush_hs(&mut self) -> Result<()> {
471        if self.pending_hs.is_empty() {
472            return Ok(());
473        }
474        if self.pending_level != Level::Initial || self.write.is_some() {
475            self.switch_write(self.pending_level)?;
476        }
477        let data = std::mem::take(&mut self.pending_hs);
478        for chunk in data.chunks(MAX_PLAINTEXT) {
479            self.send_record(content::HANDSHAKE, chunk)?;
480        }
481        Ok(())
482    }
483
484    fn send_record(&mut self, typ: u8, payload: &[u8]) -> Result<()> {
485        match self.write.as_mut() {
486            Some(w) => w.seal_record(typ, payload, &mut self.tx),
487            None => {
488                let v = if self.sent_first { 3 } else { 1 };
489                self.sent_first = true;
490                self.tx.extend_from_slice(&[typ, 3, v]);
491                codec::put_u16(&mut self.tx, payload.len() as u16);
492                self.tx.extend_from_slice(payload);
493                Ok(())
494            }
495        }
496    }
497
498    /// True if TLS bytes are waiting to be sent.
499    pub fn wants_write(&self) -> bool {
500        self.tx_pos < self.tx.len()
501    }
502
503    /// The TLS bytes waiting to be sent.
504    pub fn tls_output(&self) -> &[u8] {
505        &self.tx[self.tx_pos..]
506    }
507
508    /// Marks `n` bytes of [`tls_output`](Self::tls_output) as sent.
509    pub fn consume_tls_output(&mut self, n: usize) {
510        self.tx_pos = (self.tx_pos + n).min(self.tx.len());
511        if self.tx_pos == self.tx.len() {
512            self.tx.clear();
513            self.tx_pos = 0;
514        }
515    }
516
517    /// Moves all pending TLS output to `out`.
518    pub fn write_tls_into(&mut self, out: &mut Vec<u8>) -> usize {
519        let n = self.tx.len() - self.tx_pos;
520        out.extend_from_slice(&self.tx[self.tx_pos..]);
521        self.tx.clear();
522        self.tx_pos = 0;
523        n
524    }
525
526    // ---------------------------------------------------------------- plaintext
527
528    /// Encrypts application data. Before the handshake completes the data is buffered (up to
529    /// 1 MiB) and sent right after it.
530    pub fn write_plaintext(&mut self, data: &[u8]) -> Result<usize> {
531        if let Some(e) = &self.error {
532            return Err(e.clone());
533        }
534        if self.sent_close {
535            return Err(Error::Closed);
536        }
537        if !self.engine.shared().done {
538            if self.pending_app.len() + data.len() > MAX_PENDING_APP {
539                return Err(Error::Config("too much data written before the handshake completed".into()));
540            }
541            self.pending_app.extend_from_slice(data);
542            return Ok(data.len());
543        }
544        let tls12 = self.engine.shared().is_tls12();
545        for chunk in data.chunks(MAX_PLAINTEXT) {
546            if self.write.as_ref().is_some_and(|w| w.seq >= KEY_UPDATE_AFTER) {
547                if tls12 {
548                    // TLS 1.2 has no KeyUpdate (and renegotiation is refused): stop well below
549                    // the AES-GCM limit; the application reconnects
550                    if self.write.as_ref().is_some_and(|w| w.seq >= 2 * KEY_UPDATE_AFTER) {
551                        return Err(Error::Config("TLS 1.2 record limit reached; reconnect".into()));
552                    }
553                } else {
554                    self.send_key_update(false)?;
555                }
556            }
557            self.send_record(content::APPLICATION_DATA, chunk)?;
558        }
559        Ok(data.len())
560    }
561
562    /// Copies decrypted application data into `buf`.
563    pub fn read_plaintext(&mut self, buf: &mut [u8]) -> usize {
564        let n = buf.len().min(self.plain.len() - self.plain_pos);
565        buf[..n].copy_from_slice(&self.plain[self.plain_pos..self.plain_pos + n]);
566        self.consume_plaintext(n);
567        n
568    }
569
570    /// The decrypted application data not yet consumed.
571    pub fn plaintext(&self) -> &[u8] {
572        &self.plain[self.plain_pos..]
573    }
574
575    pub fn consume_plaintext(&mut self, n: usize) {
576        self.plain_pos = (self.plain_pos + n).min(self.plain.len());
577        if self.plain_pos == self.plain.len() {
578            self.plain.clear();
579            self.plain_pos = 0;
580        }
581    }
582
583    /// Frees the capacity of empty buffers (call on idle keep-alive connections). Returns the
584    /// bytes still held by buffers with pending data.
585    pub fn release_buffers(&mut self) -> usize {
586        for (buf, pos) in [(&mut self.rx, &mut self.rx_pos), (&mut self.plain, &mut self.plain_pos), (&mut self.tx, &mut self.tx_pos)] {
587            if *pos == buf.len() {
588                *buf = Vec::new();
589                *pos = 0;
590            }
591        }
592        if self.pending_app.is_empty() {
593            self.pending_app = Vec::new();
594        }
595        self.rx.capacity() + self.plain.capacity() + self.tx.capacity() + self.pending_app.capacity()
596    }
597
598    // ---------------------------------------------------------------- control
599
600    /// Queues close_notify. Further writes fail with [`Error::Closed`].
601    pub fn send_close_notify(&mut self) {
602        if self.sent_close || self.error.is_some() {
603            return;
604        }
605        self.sent_close = true;
606        let _ = self.send_record(content::ALERT, &[1, alert::CLOSE_NOTIFY]);
607    }
608
609    /// Sends a KeyUpdate and switches to the next write key; `request_peer` asks the peer to
610    /// update its keys too.
611    pub fn send_key_update(&mut self, request_peer: bool) -> Result<()> {
612        if !self.engine.shared().done || self.write_level != Level::OneRtt {
613            return Err(Error::Config("KeyUpdate requires a completed handshake".into()));
614        }
615        if self.engine.shared().is_tls12() {
616            return Err(Error::Config("KeyUpdate is TLS 1.3 only".into()));
617        }
618        self.send_record(content::HANDSHAKE, &codec::handshake_msg(hs::KEY_UPDATE, &[request_peer as u8]))?;
619        let suite = self.suite();
620        self.write_secret = next_traffic_secret(suite.hash(), &self.write_secret);
621        self.write = Some(RecordCipher::new(suite, &self.write_secret));
622        Ok(())
623    }
624
625    // ---------------------------------------------------------------- state
626
627    pub fn is_handshaking(&self) -> bool {
628        !self.engine.shared().done
629    }
630    pub fn alpn_protocol(&self) -> Option<&[u8]> {
631        self.engine.shared().alpn.as_deref()
632    }
633    /// The TLS 1.3 cipher suite (None for TLS 1.2: see `negotiated_tls12_suite` and
634    /// [`Connection::cipher_suite_name`]).
635    pub fn negotiated_cipher_suite(&self) -> Option<CipherSuite> {
636        self.engine.shared().suite.filter(|_| !self.is_handshaking())
637    }
638    /// The TLS 1.2 cipher suite, when TLS 1.2 was negotiated.
639    #[cfg(feature = "tls12")]
640    pub fn negotiated_tls12_suite(&self) -> Option<super::tls12::Tls12Suite> {
641        self.engine.shared().tls12.filter(|_| !self.is_handshaking())
642    }
643    /// The IANA name of the negotiated cipher suite, for either version.
644    pub fn cipher_suite_name(&self) -> Option<&'static str> {
645        #[cfg(feature = "tls12")]
646        if let Some(s) = self.negotiated_tls12_suite() {
647            return Some(s.name());
648        }
649        self.negotiated_cipher_suite().map(|s| s.name())
650    }
651    /// The negotiated protocol version (None during the handshake).
652    pub fn protocol_version(&self) -> Option<super::ProtocolVersion> {
653        if self.is_handshaking() {
654            return None;
655        }
656        Some(if self.engine.shared().is_tls12() { super::ProtocolVersion::Tls12 } else { super::ProtocolVersion::Tls13 })
657    }
658    /// Client: the OCSP response the server stapled, if any (feature `revocation`; it was
659    /// validated when the client's revocation policy asked for stapling).
660    #[cfg(feature = "revocation")]
661    pub fn ocsp_response(&self) -> Option<&[u8]> {
662        self.engine.shared().ocsp_response.as_deref()
663    }
664    pub fn negotiated_group(&self) -> Option<NamedGroup> {
665        self.engine.shared().group
666    }
667    /// Server: the SNI name sent by the client. Client: the name, if the server acknowledged it.
668    pub fn server_name(&self) -> Option<&str> {
669        self.engine.shared().sni.as_deref()
670    }
671    /// The peer's certificate chain, leaf first (restored from the ticket on resumption).
672    pub fn peer_certificates(&self) -> &[Vec<u8>] {
673        &self.engine.shared().peer_certs
674    }
675    pub fn is_resumed(&self) -> bool {
676        self.engine.shared().resumed
677    }
678    pub fn peer_has_closed(&self) -> bool {
679        self.peer_closed
680    }
681    /// The error that ended the connection, if any.
682    pub fn error(&self) -> Option<&Error> {
683        self.error.as_ref()
684    }
685
686    /// RFC 8446 section 7.5 keying material exporter.
687    /// With TLS 1.2 this is RFC 5705, where an empty `context` means no context.
688    pub fn export_keying_material(&self, label: &[u8], context: &[u8], len: usize) -> Result<Vec<u8>> {
689        #[cfg(feature = "tls12")]
690        if let Some(e) = &self.engine.shared().exporter12 {
691            if self.is_handshaking() {
692                return Err(Error::Config("handshake not complete".into()));
693            }
694            return Ok(super::tls12::export(e.hash, &e.master, &e.randoms, label, (!context.is_empty()).then_some(context), len));
695        }
696        let em = self.engine.shared().exporter_master.as_ref().ok_or_else(|| Error::Config("handshake not complete".into()))?;
697        let h = self.suite().hash();
698        let secret = derive_secret(h, em, label, &h.hash(&[]));
699        Ok(expand_label_vec(h, &secret, b"exporter", &h.hash(context), len))
700    }
701
702    /// Hands the record state to another record layer, such as kernel TLS (Linux `SOL_TLS`).
703    /// Pending TLS output must have been sent first. KeyUpdates after the export are the new
704    /// owner's job.
705    pub fn export_traffic_secrets(self) -> Result<ExportedSecrets> {
706        if self.is_handshaking() || self.error.is_some() || self.wants_write() || !self.hs.is_empty() {
707            return Err(Error::Config("export needs an established connection with no pending output".into()));
708        }
709        if self.engine.shared().is_tls12() {
710            return Err(Error::Config("traffic secret export is TLS 1.3 only".into()));
711        }
712        let suite = self.suite();
713        let dir = |secret: &Vec<u8>, c: &Option<RecordCipher>| {
714            let (key, iv) = traffic_key_iv(suite, secret);
715            DirectionalSecret { secret: secret.clone(), key, iv, seq: c.as_ref().map_or(0, |c| c.seq) }
716        };
717        Ok(ExportedSecrets {
718            suite,
719            tx: dir(&self.write_secret, &self.write),
720            rx: dir(&self.read_secret, &self.read),
721            unprocessed_input: self.rx[self.rx_pos..].to_vec(),
722            plaintext: self.plain[self.plain_pos..].to_vec(),
723        })
724    }
725}
726
727/// A TLS 1.3 server connection.
728#[derive(Debug)]
729pub struct ServerConnection(Connection);
730
731impl ServerConnection {
732    pub fn new(cfg: Arc<ServerConfig>) -> ServerConnection {
733        ServerConnection(Connection::new(Engine::Server(Box::new(ServerHs::new(cfg, None)))))
734    }
735
736    /// The underlying connection (for example to call [`Connection::export_traffic_secrets`]).
737    pub fn into_inner(self) -> Connection {
738        self.0
739    }
740}
741
742impl Deref for ServerConnection {
743    type Target = Connection;
744    fn deref(&self) -> &Connection {
745        &self.0
746    }
747}
748
749impl DerefMut for ServerConnection {
750    fn deref_mut(&mut self) -> &mut Connection {
751        &mut self.0
752    }
753}
754
755/// A TLS 1.3 client connection. The ClientHello is queued at construction.
756#[cfg(feature = "client")]
757#[derive(Debug)]
758pub struct ClientConnection(Connection);
759
760#[cfg(feature = "client")]
761impl ClientConnection {
762    /// `server_name` is verified against the certificate and sent as SNI (unless it is an IP
763    /// address).
764    pub fn new(cfg: Arc<ClientConfig>, server_name: &str) -> Result<ClientConnection> {
765        Ok(ClientConnection(Connection::new(Engine::Client(Box::new(ClientHs::new(cfg, server_name, None)?)))))
766    }
767
768    /// The underlying connection (for example to call [`Connection::export_traffic_secrets`]).
769    pub fn into_inner(self) -> Connection {
770        self.0
771    }
772}
773
774#[cfg(feature = "client")]
775impl Deref for ClientConnection {
776    type Target = Connection;
777    fn deref(&self) -> &Connection {
778        &self.0
779    }
780}
781
782#[cfg(feature = "client")]
783impl DerefMut for ClientConnection {
784    fn deref_mut(&mut self) -> &mut Connection {
785        &mut self.0
786    }
787}
788
789#[cfg(all(test, feature = "client"))]
790mod tests {
791    use super::*;
792    use crate::certgen::{self, CertParams};
793    use crate::keys::{EcCurve, PrivateKey};
794    use crate::tls::client::TEST_OFFER_EARLY_DATA;
795    use crate::tls::config::CertifiedKey;
796    use crate::x509::RootStore;
797
798    fn move_bytes(from: &mut Connection, to: &mut Connection, inject: &[u8]) -> Result<()> {
799        let mut data = from.tls_output().to_vec();
800        from.consume_tls_output(data.len());
801        // early data records ride right behind the client's flight
802        data.extend_from_slice(inject);
803        to.read_tls(&data);
804        to.process_new_packets().map(|_| ())
805    }
806
807    #[test]
808    fn rejected_early_data_is_skipped() {
809        let ss = certgen::issue(&CertParams::server(&["localhost"]), PrivateKey::generate_ec(EcCurve::P256), None);
810        let scfg = Arc::new(ServerConfig::new(CertifiedKey::new(vec![ss.cert_der.clone()], ss.key.clone()).unwrap()));
811        let mut roots = RootStore::empty();
812        roots.add_der(&ss.cert_der).unwrap();
813        let ccfg = Arc::new(ClientConfig::new(roots));
814        let fake_early = [23u8, 3, 3, 0, 40].iter().copied().chain(std::iter::repeat_n(0x5a, 40)).collect::<Vec<u8>>();
815        for offer in [true, false] {
816            TEST_OFFER_EARLY_DATA.with(|f| f.set(offer));
817            let mut c = ClientConnection::new(ccfg.clone(), "localhost").unwrap();
818            TEST_OFFER_EARLY_DATA.with(|f| f.set(false));
819            let mut s = ServerConnection::new(scfg.clone());
820            let r = move_bytes(&mut c, &mut s, &fake_early);
821            if !offer {
822                // without 0-RTT the server already reads with the handshake key: fatal
823                assert_eq!(r.unwrap_err().alert(), Some(alert::BAD_RECORD_MAC));
824                continue;
825            }
826            r.unwrap();
827            move_bytes(&mut s, &mut c, &[]).unwrap();
828            // more 0-RTT records (now undecryptable under the handshake key) before Finished
829            let mut early2 = fake_early.clone();
830            early2.extend_from_slice(&fake_early);
831            let mut flight = c.tls_output().to_vec();
832            c.consume_tls_output(flight.len());
833            flight.splice(0..0, early2);
834            s.read_tls(&flight);
835            s.process_new_packets().unwrap();
836            assert!(!s.is_handshaking());
837            // after the handshake key worked, garbage is fatal again
838            s.read_tls(&fake_early);
839            assert_eq!(s.process_new_packets().unwrap_err().alert(), Some(alert::BAD_RECORD_MAC));
840        }
841    }
842
843    fn handshaken() -> (ClientConnection, ServerConnection) {
844        let ss = certgen::issue(&CertParams::server(&["localhost"]), PrivateKey::generate_ec(EcCurve::P256), None);
845        let scfg = Arc::new(ServerConfig::new(CertifiedKey::new(vec![ss.cert_der.clone()], ss.key.clone()).unwrap()));
846        let mut roots = RootStore::empty();
847        roots.add_der(&ss.cert_der).unwrap();
848        let mut c = ClientConnection::new(Arc::new(ClientConfig::new(roots)), "localhost").unwrap();
849        let mut s = ServerConnection::new(scfg);
850        for _ in 0..10 {
851            move_bytes(&mut c, &mut s, &[]).unwrap();
852            move_bytes(&mut s, &mut c, &[]).unwrap();
853        }
854        assert!(!c.is_handshaking() && !s.is_handshaking());
855        (c, s)
856    }
857
858    /// Seals one record with the client's current write key, as a misbehaving peer would.
859    fn forge(c: &mut ClientConnection, typ: u8, payload: &[u8]) -> Vec<u8> {
860        let mut out = Vec::new();
861        c.0.write.as_mut().unwrap().seal_record(typ, payload, &mut out).unwrap();
862        out
863    }
864
865    fn feed(s: &mut ServerConnection, data: &[u8]) -> Result<IoState> {
866        let mut off = 0;
867        loop {
868            off += s.read_tls(&data[off..]);
869            let r = s.process_new_packets();
870            if r.is_err() || off == data.len() {
871                return r;
872            }
873        }
874    }
875
876    #[test]
877    fn empty_record_flood_is_bounded() {
878        let (mut c, mut s) = handshaken();
879        // up to the bound is tolerated, and real data resets the count
880        let mut burst = Vec::new();
881        for _ in 0..MAX_IDLE_RECORDS {
882            burst.extend(forge(&mut c, content::APPLICATION_DATA, &[]));
883        }
884        burst.extend(forge(&mut c, content::APPLICATION_DATA, b"x"));
885        for _ in 0..MAX_IDLE_RECORDS {
886            burst.extend(forge(&mut c, content::APPLICATION_DATA, &[]));
887        }
888        feed(&mut s, &burst).unwrap();
889        assert_eq!(s.plaintext(), b"x");
890        // one more in a row is fatal
891        let more = forge(&mut c, content::APPLICATION_DATA, &[]);
892        assert_eq!(feed(&mut s, &more).unwrap_err().alert(), Some(alert::UNEXPECTED_MESSAGE));
893    }
894
895    #[test]
896    fn warning_alert_flood_is_bounded() {
897        let (mut c, mut s) = handshaken();
898        let mut flood = Vec::new();
899        for _ in 0..1000 {
900            flood.extend(forge(&mut c, content::ALERT, &[1, alert::USER_CANCELED]));
901        }
902        assert_eq!(feed(&mut s, &flood).unwrap_err().alert(), Some(alert::UNEXPECTED_MESSAGE));
903        // any other alert, warning level or not, is fatal in TLS 1.3 (RFC 8446 section 6)
904        let (mut c, mut s) = handshaken();
905        let a = forge(&mut c, content::ALERT, &[1, alert::UNSUPPORTED_CERTIFICATE]);
906        assert_eq!(feed(&mut s, &a).unwrap_err(), Error::PeerAlert(alert::UNSUPPORTED_CERTIFICATE));
907    }
908
909    #[test]
910    fn key_update_flood_is_bounded() {
911        let (mut c, mut s) = handshaken();
912        // each KeyUpdate with update_requested would make the server answer with its own
913        let mut flood = Vec::new();
914        for _ in 0..200 {
915            flood.extend(forge(&mut c, content::HANDSHAKE, &[hs::KEY_UPDATE, 0, 0, 1, 1]));
916            let next = next_traffic_secret(c.suite().hash(), &c.0.write_secret);
917            c.0.write_secret = next.clone();
918            c.0.write = Some(RecordCipher::new(c.suite(), &next));
919        }
920        assert_eq!(feed(&mut s, &flood).unwrap_err().alert(), Some(alert::UNEXPECTED_MESSAGE));
921        // the replies stayed bounded by the limit
922        assert!(s.tls_output().len() < (MAX_IDLE_RECORDS as usize + 2) * 64, "{} bytes queued", s.tls_output().len());
923    }
924
925    #[test]
926    fn renegotiation_is_unexpected_message() {
927        let (mut c, mut s) = handshaken();
928        // a ClientHello (or any handshake message but KeyUpdate) after the handshake
929        let ch = forge(&mut c, content::HANDSHAKE, &[hs::CLIENT_HELLO, 0, 0, 4, 3, 3, 0, 0]);
930        assert_eq!(feed(&mut s, &ch).unwrap_err().alert(), Some(alert::UNEXPECTED_MESSAGE));
931        // the client reads the alert under the server's application key
932        move_bytes(&mut s, &mut c, &[]).unwrap_err();
933        assert_eq!(c.error(), Some(&Error::PeerAlert(alert::UNEXPECTED_MESSAGE)));
934    }
935
936    #[cfg(feature = "tls12")]
937    fn handshaken12() -> (ClientConnection, ServerConnection) {
938        let ss = certgen::issue(&CertParams::server(&["localhost"]), PrivateKey::generate_ec(EcCurve::P256), None);
939        let mut scfg = ServerConfig::new(CertifiedKey::new(vec![ss.cert_der.clone()], ss.key.clone()).unwrap());
940        scfg.max_version = super::super::ProtocolVersion::Tls12;
941        let mut roots = RootStore::empty();
942        roots.add_der(&ss.cert_der).unwrap();
943        let mut c = ClientConnection::new(Arc::new(ClientConfig::new(roots)), "localhost").unwrap();
944        let mut s = ServerConnection::new(Arc::new(scfg));
945        for _ in 0..10 {
946            move_bytes(&mut c, &mut s, &[]).unwrap();
947            move_bytes(&mut s, &mut c, &[]).unwrap();
948        }
949        assert!(!c.is_handshaking() && !s.is_handshaking());
950        assert_eq!(c.protocol_version(), Some(super::super::ProtocolVersion::Tls12));
951        (c, s)
952    }
953
954    #[cfg(feature = "tls12")]
955    #[test]
956    fn tls12_renegotiation_is_refused_with_a_warning() {
957        let (mut c, mut s) = handshaken12();
958        // a ClientHello after the handshake: the server warns no_renegotiation and carries on
959        let ch = forge(&mut c, content::HANDSHAKE, &[hs::CLIENT_HELLO, 0, 0, 4, 3, 3, 0, 0]);
960        feed(&mut s, &ch).unwrap();
961        move_bytes(&mut s, &mut c, &[]).unwrap();
962        assert!(c.error().is_none());
963        let data = forge(&mut c, content::APPLICATION_DATA, b"still here");
964        feed(&mut s, &data).unwrap();
965        assert_eq!(s.plaintext(), b"still here");
966        // a flood of them hits the idle-record bound
967        let mut flood = Vec::new();
968        for _ in 0..100 {
969            flood.extend(forge(&mut c, content::HANDSHAKE, &[hs::CLIENT_HELLO, 0, 0, 4, 3, 3, 0, 0]));
970        }
971        assert_eq!(feed(&mut s, &flood).unwrap_err().alert(), Some(alert::UNEXPECTED_MESSAGE));
972        // a HelloRequest to the client gets the same answer; any other message is fatal
973        let (mut c, mut s) = handshaken12();
974        let mut hr = Vec::new();
975        s.0.write.as_mut().unwrap().seal_record(content::HANDSHAKE, &[hs::HELLO_REQUEST, 0, 0, 0], &mut hr).unwrap();
976        c.read_tls(&hr);
977        c.process_new_packets().unwrap();
978        assert!(c.wants_write());
979        let mut fin = Vec::new();
980        s.0.write.as_mut().unwrap().seal_record(content::HANDSHAKE, &[hs::FINISHED, 0, 0, 0], &mut fin).unwrap();
981        c.read_tls(&fin);
982        assert_eq!(c.process_new_packets().unwrap_err().alert(), Some(alert::UNEXPECTED_MESSAGE));
983        // a stray ChangeCipherSpec after the handshake is fatal too
984        let (_c, mut s) = handshaken12();
985        assert_eq!(feed(&mut s, &[content::CHANGE_CIPHER_SPEC, 3, 3, 0, 1, 1]).unwrap_err().alert(), Some(alert::UNEXPECTED_MESSAGE));
986    }
987
988    #[test]
989    fn oversized_records_are_record_overflow() {
990        // protected: a ciphertext over 2^14 + 256 is refused from its header alone
991        let (_, mut s) = handshaken();
992        let len = MAX_CIPHERTEXT + 1;
993        let hdr = [content::APPLICATION_DATA, 3, 3, (len >> 8) as u8, len as u8];
994        assert_eq!(feed(&mut s, &hdr).unwrap_err().alert(), Some(alert::RECORD_OVERFLOW));
995        // unprotected: a plaintext handshake record over 2^14
996        let scfg = {
997            let ss = certgen::issue(&CertParams::server(&["localhost"]), PrivateKey::generate_ec(EcCurve::P256), None);
998            Arc::new(ServerConfig::new(CertifiedKey::new(vec![ss.cert_der.clone()], ss.key.clone()).unwrap()))
999        };
1000        let mut s = ServerConnection::new(scfg);
1001        let len = MAX_PLAINTEXT + 1;
1002        let mut rec = vec![content::HANDSHAKE, 3, 1, (len >> 8) as u8, len as u8];
1003        rec.resize(5 + len, 0);
1004        assert_eq!(feed(&mut s, &rec).unwrap_err().alert(), Some(alert::RECORD_OVERFLOW));
1005    }
1006
1007    #[test]
1008    fn rejected_early_data_beyond_the_budget_is_fatal() {
1009        let ss = certgen::issue(&CertParams::server(&["localhost"]), PrivateKey::generate_ec(EcCurve::P256), None);
1010        let scfg = Arc::new(ServerConfig::new(CertifiedKey::new(vec![ss.cert_der.clone()], ss.key.clone()).unwrap()));
1011        let mut roots = RootStore::empty();
1012        roots.add_der(&ss.cert_der).unwrap();
1013        TEST_OFFER_EARLY_DATA.with(|f| f.set(true));
1014        let mut c = ClientConnection::new(Arc::new(ClientConfig::new(roots)), "localhost").unwrap();
1015        TEST_OFFER_EARLY_DATA.with(|f| f.set(false));
1016        let mut s = ServerConnection::new(scfg);
1017        let mut flight = c.tls_output().to_vec();
1018        c.consume_tls_output(flight.len());
1019        // 0-RTT the server did not accept: skipped up to 64 KiB (RFC 8446 section 4.2.10), then
1020        // treated as the forgery it is
1021        let rec: Vec<u8> = [23u8, 3, 3, 0x10, 0].iter().copied().chain(std::iter::repeat_n(0x5a, 0x1000)).collect();
1022        for _ in 0..17 {
1023            flight.extend_from_slice(&rec);
1024        }
1025        assert_eq!(feed(&mut s, &flight).unwrap_err().alert(), Some(alert::BAD_RECORD_MAC));
1026    }
1027}