Skip to main content

rustls/conn/
receive.rs

1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::marker::PhantomData;
4use core::ops::Range;
5use core::{fmt, mem};
6use std::io::{self, Read};
7
8use super::private::SideOutput;
9use super::send::{SendOutput, SendPath};
10use super::split::SendAdapter;
11use super::{Connection, SEQ_SOFT_LIMIT, SideData, StateMachine, Transport};
12use crate::common_state::{
13    ConnectionOutput, Event, Output, OutputEvent, Side, UnborrowedPayload, maybe_send_fatal_alert,
14};
15use crate::crypto::cipher::{EncodableVersion, InboundOpaque, Payload, Record, RecordDecrypter};
16use crate::enums::{ContentType, HandshakeType, ProtocolVersion};
17use crate::error::{AlertDescription, Error, PeerMisbehaved};
18use crate::msgs::{
19    AlertLevel, AlertLevelName, AlertMessagePayload, Deframed, Deframer, Delocator,
20    HandshakeAlignedProof, Locator, Message, MessagePayload,
21};
22use crate::quic::QuicOutput;
23use crate::tracing::{trace, warn};
24
25pub(crate) struct MessageIter<'a, 'm, Side: SideData, Send: SendOutput + 'a> {
26    pub(super) input: &'m mut dyn TlsInputBuffer,
27    pub(super) tls: &'a mut Vec<u8>,
28    pub(super) recv: &'a mut ReceivePath,
29    pub(super) state: &'a mut Result<Side::State, Error>,
30    pub(super) output: JoinOutput<'a, Send>,
31    pub(super) mode: MessageIterMode,
32}
33
34impl<'a, 'm, Side: SideData> MessageIter<'a, 'm, Side, SendPath> {
35    pub(crate) fn new<T: Transport>(
36        input: &'m mut dyn TlsInputBuffer,
37        tls: &'a mut Vec<u8>,
38        conn: &'a mut Connection<Side, T>,
39        mode: MessageIterMode,
40    ) -> Self {
41        Self {
42            input,
43            tls,
44            recv: &mut conn.common.recv,
45            state: &mut conn.state,
46            output: JoinOutput {
47                outputs: &mut conn.common.outputs,
48                quic: conn.transport.quic(),
49                send: &mut conn.common.send,
50                side: &mut conn.side,
51            },
52            mode,
53        }
54    }
55}
56
57impl<'a, 'm, 's, Side: SideData> MessageIter<'a, 'm, Side, SendAdapter<'s>> {
58    pub(super) fn receive(
59        input: &'m mut dyn TlsInputBuffer,
60        tls: &'a mut Vec<u8>,
61        state: &'a mut Result<Side::State, Error>,
62        recv: &'a mut ReceivePath,
63        output: JoinOutput<'a, SendAdapter<'s>>,
64        mode: MessageIterMode,
65    ) -> Self {
66        Self {
67            input,
68            tls,
69            recv,
70            state,
71            output,
72            mode,
73        }
74    }
75}
76
77impl<'a, 'm, Side: SideData, Send: SendOutput + 'a> MessageIter<'a, 'm, Side, Send> {
78    pub(crate) fn next(&mut self, early_only: bool) -> Option<Result<UnborrowedPayload, Error>> {
79        let mut st = match mem::replace(self.state, Err(Error::HandshakeNotComplete)) {
80            Ok(state) => state,
81            Err(e) => {
82                *self.state = Err(e.clone());
83                return Some(Err(e));
84            }
85        };
86
87        let mut plaintext = None;
88        while st.wants_input() {
89            let buffer = self.input.slice_mut();
90            let locator = Locator::new(buffer);
91            let res = self.recv.deframe(buffer);
92
93            let mut output = CaptureAppData {
94                recv: self.recv,
95                tls: self.tls,
96                other: &mut self.output,
97                plaintext_locator: &locator,
98                received_plaintext: &mut plaintext,
99                _message_lifetime: PhantomData,
100            };
101
102            let opt_record = match res {
103                Ok(opt_record) => opt_record,
104                Err(e) => {
105                    let _ = maybe_send_fatal_alert(output.other.send, &e, output.tls);
106                    if let Error::DecryptError = e {
107                        st.handle_decrypt_error();
108                    }
109                    *self.state = Err(e.clone());
110                    return Some(Err(e));
111                }
112            };
113
114            let Some(record) = opt_record else {
115                break;
116            };
117
118            let Decrypted {
119                plaintext: record,
120                want_close_before_decrypt,
121            } = record;
122
123            if want_close_before_decrypt {
124                let _ = output.other.send.send_alert(
125                    AlertLevel::Warning,
126                    AlertDescription::CloseNotify,
127                    output.tls,
128                );
129            } else if record.payload.is_empty()
130                && matches!(record.typ, ContentType::Handshake | ContentType::Alert)
131            {
132                // <https://datatracker.ietf.org/doc/html/rfc9846#section-5.4>
133                let _ = output.other.send.send_alert(
134                    AlertLevel::Fatal,
135                    AlertDescription::UnexpectedMessage,
136                    output.tls,
137                );
138
139                let error = Error::from(PeerMisbehaved::EmptyFragment);
140                *self.state = Err(error.clone());
141                return Some(Err(error));
142            }
143
144            let hs_aligned = output.recv.deframer.aligned();
145            let result =
146                match output
147                    .recv
148                    .receive_record(record, hs_aligned, output.tls, output.other.send)
149                {
150                    Ok(Some(input)) => st.handle(input, &mut output),
151                    Ok(None) => Ok(st),
152                    Err(e) => Err(e),
153                };
154
155            match result {
156                Ok(new) => st = new,
157                Err(e) => {
158                    let _ = maybe_send_fatal_alert(output.other.send, &e, output.tls);
159                    *self.state = Err(e.clone());
160                    return Some(Err(e));
161                }
162            }
163
164            if matches!(self.mode, MessageIterMode::All) && !st.wants_input() {
165                st = match st.handle_without_input(&mut output) {
166                    Ok(st) => st,
167                    Err(err) => {
168                        let _ = maybe_send_fatal_alert(output.other.send, &err, output.tls);
169                        *self.state = Err(err.clone());
170                        return Some(Err(err));
171                    }
172                };
173            }
174
175            if self.recv.has_received_close_notify {
176                // "Any data received after a closure alert has been received MUST be ignored."
177                // -- <https://datatracker.ietf.org/doc/html/rfc9846#section-6.1>
178
179                // First, discard actually-processed bytes.
180                self.input
181                    .discard(self.recv.deframer.take_discard());
182
183                // Then the rest of any input data.
184                let entirety = self.input.slice_mut().len();
185                self.recv.deframer.set_discard(entirety);
186                self.input.received_close_notify();
187                break;
188            }
189
190            match plaintext.take() {
191                Some(DataKind::Traffic(payload)) if !early_only => {
192                    *self.state = Ok(st);
193                    return Some(Ok(payload));
194                }
195                Some(DataKind::Early(payload)) if early_only => {
196                    *self.state = Ok(st);
197                    return Some(Ok(payload));
198                }
199                _ => {}
200            }
201
202            // Stop before consuming traffic data if the caller only wants early data.
203            if (early_only || matches!(self.mode, MessageIterMode::Handshake)) && st.is_traffic() {
204                break;
205            }
206        }
207
208        *self.state = Ok(st);
209        None
210    }
211}
212
213pub(crate) enum MessageIterMode {
214    /// Iterate through all available messages.
215    All,
216
217    /// Handshake mode.
218    ///
219    /// Stop iteration when when external input is needed to progress handshake, or the handshake ends.
220    Handshake,
221}
222
223pub(crate) struct ReceivePath {
224    side: Side,
225    pub(crate) decrypt_state: DecryptionState,
226    pub(crate) may_receive_application_data: bool,
227    /// If the peer has signaled end of stream.
228    pub(crate) has_received_close_notify: bool,
229    temper_counters: TemperCounters,
230    pub(crate) negotiated_version: Option<ProtocolVersion>,
231    pub(crate) deframer: Deframer,
232
233    /// We limit consecutive empty fragments to avoid a route for the peer to send
234    /// us significant but fruitless traffic.  That includes other record types too.
235    seen_consecutive_empty_fragments: u8,
236
237    pub(crate) tls13_tickets_received: u32,
238}
239
240impl ReceivePath {
241    pub(crate) fn new(side: Side) -> Self {
242        Self {
243            side,
244            decrypt_state: DecryptionState::new(),
245            may_receive_application_data: false,
246            has_received_close_notify: false,
247            temper_counters: TemperCounters::default(),
248            negotiated_version: None,
249            deframer: Deframer::default(),
250            seen_consecutive_empty_fragments: 0,
251            tls13_tickets_received: 0,
252        }
253    }
254
255    /// Pull a potentially coalesced record out of the deframer.
256    fn deframe<'b>(&mut self, buffer: &'b mut [u8]) -> Result<Option<Decrypted<'b>>, Error> {
257        let locator = Locator::new(buffer);
258
259        let mut want_close_before_decrypt = false;
260        loop {
261            // before processing any more of `buffer`, return any extant records from `deframer`
262            if let Some(span) = self.deframer.complete_span() {
263                let plaintext = self.deframer.record(span, buffer);
264
265                // trial decryption finishes with the first handshake message after it started.
266                self.decrypt_state
267                    .finish_trial_decryption();
268
269                return Ok(Some(Decrypted {
270                    plaintext,
271                    want_close_before_decrypt,
272                }));
273            }
274
275            let (record, bounds) = loop {
276                match self.deframe_decrypted(buffer, &locator)? {
277                    DeframeResult::Decrypted(decrypted, bounds) => break (decrypted, bounds),
278                    DeframeResult::DecryptionFailed => continue,
279                    DeframeResult::None => return Ok(None),
280                }
281            };
282
283            want_close_before_decrypt = record.want_close_before_decrypt;
284            let Decrypted {
285                plaintext: record,
286                want_close_before_decrypt: _,
287            } = record;
288
289            if self.deframer.aligned().is_none() && record.typ != ContentType::Handshake {
290                // "Handshake messages MUST NOT be interleaved with other record
291                // types.  That is, if a handshake message is split over two or more
292                // records, there MUST NOT be any other records between them."
293                // https://www.rfc-editor.org/rfc/rfc9846#section-5.1
294                return Err(PeerMisbehaved::MessageInterleavedWithHandshakeMessage.into());
295            }
296
297            match (record.payload.len(), record.typ) {
298                (0, _) => {
299                    if self.seen_consecutive_empty_fragments
300                        == ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX
301                    {
302                        return Err(PeerMisbehaved::TooManyEmptyFragments.into());
303                    }
304                    self.seen_consecutive_empty_fragments += 1;
305                }
306                (_, ContentType::Handshake | ContentType::ApplicationData) => {
307                    self.seen_consecutive_empty_fragments = 0;
308                }
309                (_, _) => {}
310            };
311
312            // do an end-run around the borrow checker, converting `record` (containing
313            // a borrowed slice) to an unborrowed one (containing a `Range` into the
314            // same buffer).  the reborrow happens inside the branch that returns the
315            // record.
316            //
317            // is fixed by -Zpolonius
318            // https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md#problem-case-3-conditional-control-flow-across-functions
319            let unborrowed = InboundUnborrowedRecord::unborrow(&locator, record);
320
321            if unborrowed.typ != ContentType::Handshake {
322                let record = unborrowed.reborrow(&Delocator::new(buffer));
323                self.deframer.discard_processed();
324                return Ok(Some(Decrypted {
325                    plaintext: record,
326                    want_close_before_decrypt,
327                }));
328            }
329
330            let record = unborrowed.reborrow(&Delocator::new(buffer));
331            self.deframer
332                .input_message(record.version.version(), bounds, buffer);
333            self.deframer.coalesce(buffer)?;
334        }
335    }
336
337    fn deframe_decrypted<'b>(
338        &mut self,
339        buffer: &'b mut [u8],
340        locator: &Locator,
341    ) -> Result<DeframeResult<'b>, Error> {
342        let (record, bounds) = match self.deframer.deframe(buffer) {
343            Some(Ok(Deframed { record, bounds })) => (record, bounds),
344            Some(Err(err)) => return Err(err),
345            None => return Ok(DeframeResult::None),
346        };
347
348        let allowed_plaintext = match record.typ {
349            // CCS messages are always plaintext.
350            ContentType::ChangeCipherSpec => true,
351            // Alerts are allowed to be plaintext if-and-only-if:
352            // * The negotiated protocol version is TLS 1.3. - In TLS 1.2 it is unambiguous when
353            //   keying changes based on the CCS message. Only TLS 1.3 requires these heuristics.
354            // * We have not yet decrypted any records from the peer - if we have we don't
355            //   expect any plaintext.
356            // * The payload size is indicative of a plaintext alert message.
357            ContentType::Alert
358                if matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
359                    && !self.decrypt_state.has_decrypted()
360                    && record.payload.len() <= 2 =>
361            {
362                true
363            }
364            // In other circumstances, we expect all records to be encrypted.
365            _ => false,
366        };
367
368        if allowed_plaintext && !self.deframer.is_active() {
369            return Ok(DeframeResult::Decrypted(
370                Decrypted {
371                    plaintext: record.into_plain_record(),
372                    want_close_before_decrypt: false,
373                },
374                bounds,
375            ));
376        }
377
378        match self
379            .decrypt_state
380            .decrypt_incoming(record)?
381        {
382            Some(decrypted) => {
383                // After decryption, the payload is shorter
384                let bounds = locator.locate(decrypted.plaintext.payload);
385                Ok(DeframeResult::Decrypted(decrypted, bounds))
386            }
387
388            // failed decryption during trial decryption is not allowed to be
389            // interleaved with partial handshake data.
390            None if self.deframer.aligned().is_none() => {
391                Err(PeerMisbehaved::RejectedEarlyDataInterleavedWithHandshakeMessage.into())
392            }
393
394            // failed decryption during trial decryption.
395            None => Ok(DeframeResult::DecryptionFailed),
396        }
397    }
398
399    /// Take a TLS record and map it into an [`Input`]
400    ///
401    /// `Input` is the input to our state machine.
402    ///
403    /// The record is mapped into `None` if it should be dropped with no further
404    /// action.
405    ///
406    /// Otherwise the caller must present the returned `Input` to the state machine to
407    /// progress the connection.
408    pub(crate) fn receive_record<'a>(
409        &mut self,
410        record: Record<&'a [u8]>,
411        aligned_handshake: Option<HandshakeAlignedProof>,
412        tls: &mut Vec<u8>,
413        send: &mut dyn SendOutput,
414    ) -> Result<Option<Input<'a>>, Error> {
415        // Drop CCS messages during handshake in TLS1.3
416        if record.typ == ContentType::ChangeCipherSpec && self.drop_tls13_ccs(&record)? {
417            trace!("Dropping CCS");
418            return Ok(None);
419        }
420
421        // Now we can fully parse the record payload.
422        let message = Message::try_from(record)?;
423
424        // For alerts, we have separate logic.
425        if let MessagePayload::Alert(alert) = &message.payload {
426            self.process_alert(alert)?;
427            return Ok(None);
428        }
429
430        // For TLS1.2, outside of the handshake, send rejection alerts for
431        // renegotiation requests.  These can occur any time.
432        if self.reject_renegotiation_request(&message, tls, send)? {
433            return Ok(None);
434        }
435
436        Ok(Some(Input {
437            message,
438            aligned_handshake,
439        }))
440    }
441
442    fn drop_tls13_ccs(&mut self, record: &Record<&'_ [u8]>) -> Result<bool, Error> {
443        if self.may_receive_application_data
444            || !matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
445        {
446            return Ok(false);
447        }
448
449        if !record.is_valid_ccs() {
450            // "An implementation which receives any other change_cipher_spec value or
451            //  which receives a protected change_cipher_spec record MUST abort the
452            //  handshake with an "unexpected_message" alert."
453            return Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into());
454        }
455
456        self.temper_counters
457            .received_tls13_change_cipher_spec()?;
458        Ok(true)
459    }
460
461    fn reject_renegotiation_request(
462        &mut self,
463        msg: &Message<'_>,
464        tls: &mut Vec<u8>,
465        send: &mut dyn SendOutput,
466    ) -> Result<bool, Error> {
467        if !self.may_receive_application_data
468            || matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
469        {
470            return Ok(false);
471        }
472
473        let reject_ty = match self.side {
474            Side::Client => HandshakeType::HelloRequest,
475            Side::Server => HandshakeType::ClientHello,
476        };
477
478        if msg.handshake_type() != Some(reject_ty) {
479            return Ok(false);
480        }
481        self.temper_counters
482            .received_renegotiation_request()?;
483        let desc = AlertDescription::NoRenegotiation;
484        warn!("sending warning alert {desc:?}");
485        send.send_alert(AlertLevel::Warning, desc, tls)?;
486        Ok(true)
487    }
488
489    fn process_alert(&mut self, alert: &AlertMessagePayload) -> Result<(), Error> {
490        // Reject unknown AlertLevels.
491        if AlertLevelName::try_from(alert.level).is_err() {
492            return Err(PeerMisbehaved::IllegalAlertLevel(alert.level.0, alert.description).into());
493        }
494
495        // If we get a CloseNotify, make a note to declare EOF to our
496        // caller.  But do not treat unauthenticated alerts like this.
497        if self.may_receive_application_data && alert.description == AlertDescription::CloseNotify {
498            self.has_received_close_notify = true;
499            return Ok(());
500        }
501
502        // Warnings are nonfatal for TLS1.2, but outlawed in TLS1.3
503        // (except, for no good reason, user_cancelled).
504        let err = Error::AlertReceived(alert.description);
505        if alert.level == AlertLevel::Warning {
506            self.temper_counters
507                .received_warning_alert()?;
508            if matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
509                && alert.description != AlertDescription::UserCanceled
510            {
511                return Err(PeerMisbehaved::IllegalWarningAlert(alert.description).into());
512            }
513
514            // Some implementations send pointless `user_canceled` alerts, don't log them
515            // in release mode (https://bugs.openjdk.org/browse/JDK-8323517).
516            if alert.description != AlertDescription::UserCanceled || cfg!(debug_assertions) {
517                warn!("TLS alert warning received: {alert:?}");
518            }
519
520            return Ok(());
521        }
522
523        Err(err)
524    }
525}
526
527enum DeframeResult<'b> {
528    Decrypted(Decrypted<'b>, Range<usize>),
529    DecryptionFailed,
530    None,
531}
532
533/// Record layer that tracks decryption keys.
534pub(crate) struct DecryptionState {
535    record_decrypter: Option<Box<dyn RecordDecrypter>>,
536    read_seq: u64,
537    has_decrypted: bool,
538
539    // Records encrypted with other keys may be encountered, so failures
540    // should be swallowed by the caller.  This struct tracks the amount
541    // of record size this is allowed for.
542    trial_decryption_len: Option<usize>,
543}
544
545impl DecryptionState {
546    /// Create new record layer with no keys.
547    pub(crate) fn new() -> Self {
548        Self {
549            record_decrypter: None,
550            read_seq: 0,
551            has_decrypted: false,
552            trial_decryption_len: None,
553        }
554    }
555
556    /// Decrypt a TLS record.
557    ///
558    /// `encr` is a decoded record allegedly received from the peer.
559    /// If it can be decrypted, its decryption is returned.  Otherwise,
560    /// an error is returned.
561    pub(crate) fn decrypt_incoming<'a>(
562        &mut self,
563        encr: Record<InboundOpaque<'a>>,
564    ) -> Result<Option<Decrypted<'a>>, Error> {
565        let Some(decrypter) = &mut self.record_decrypter else {
566            return Ok(Some(Decrypted {
567                want_close_before_decrypt: false,
568                plaintext: encr.into_plain_record(),
569            }));
570        };
571
572        // Set to `true` if the peer appears to getting close to encrypting
573        // too many records with this key.
574        //
575        // Perhaps if we send an alert well before their counter wraps, a
576        // buggy peer won't make a terrible mistake here?
577        //
578        // Note that there's no reason to refuse to decrypt: the security
579        // failure has already happened.
580        let want_close_before_decrypt = self.read_seq == SEQ_SOFT_LIMIT;
581
582        let encrypted_len = encr.payload.len();
583        match decrypter.decrypt(encr, self.read_seq) {
584            Ok(plaintext) => {
585                self.read_seq += 1;
586                if !self.has_decrypted {
587                    self.has_decrypted = true;
588                }
589                Ok(Some(Decrypted {
590                    want_close_before_decrypt,
591                    plaintext,
592                }))
593            }
594            Err(Error::DecryptError) if self.doing_trial_decryption(encrypted_len) => {
595                trace!("Dropping undecryptable record after aborted early_data");
596                Ok(None)
597            }
598            Err(err) => Err(err),
599        }
600    }
601
602    /// Set and start using the given `RecordDecrypter` for future incoming
603    /// record decryption.
604    pub(crate) fn set_record_decrypter(
605        &mut self,
606        cipher: Box<dyn RecordDecrypter>,
607        _proof: &HandshakeAlignedProof,
608    ) {
609        self.record_decrypter = Some(cipher);
610        self.read_seq = 0;
611        self.trial_decryption_len = None;
612    }
613
614    /// Set and start using the given `RecordDecrypter` for future incoming
615    /// record decryption, and enable "trial decryption" mode for when TLS1.3
616    /// 0-RTT is attempted but rejected by the server.
617    pub(crate) fn set_record_decrypter_with_trial_decryption(
618        &mut self,
619        cipher: Box<dyn RecordDecrypter>,
620        max_length: usize,
621        _proof: &HandshakeAlignedProof,
622    ) {
623        self.record_decrypter = Some(cipher);
624        self.read_seq = 0;
625        self.trial_decryption_len = Some(max_length);
626    }
627
628    pub(crate) fn finish_trial_decryption(&mut self) {
629        self.trial_decryption_len = None;
630    }
631
632    /// Return true if we have ever decrypted a record. This is used in place
633    /// of checking the read_seq since that will be reset on key updates.
634    pub(crate) fn has_decrypted(&self) -> bool {
635        self.has_decrypted
636    }
637
638    pub(crate) fn read_seq(&self) -> u64 {
639        self.read_seq
640    }
641
642    fn doing_trial_decryption(&mut self, requested: usize) -> bool {
643        match self
644            .trial_decryption_len
645            .and_then(|value| value.checked_sub(requested))
646        {
647            Some(remaining) => {
648                self.trial_decryption_len = Some(remaining);
649                true
650            }
651            _ => false,
652        }
653    }
654}
655
656/// Result of decryption.
657pub(crate) struct Decrypted<'a> {
658    /// Whether the peer appears to be getting close to encrypting too many records with this key.
659    pub(crate) want_close_before_decrypt: bool,
660    /// The decrypted record.
661    pub(crate) plaintext: Record<&'a [u8]>,
662}
663
664struct CaptureAppData<'a, 'j, 'm, Send: SendOutput + 'a> {
665    recv: &'a mut ReceivePath,
666    other: &'a mut JoinOutput<'j, Send>,
667    tls: &'a mut Vec<u8>,
668    /// Store a [`Locator`] initialized from the current receive buffer
669    ///
670    /// Allows received plaintext data to be unborrowed and stored in
671    /// `received_plaintext` for in-place decryption.
672    plaintext_locator: &'a Locator,
673    /// Unborrowed received plaintext data
674    ///
675    /// Set if plaintext data was received.
676    ///
677    /// Plaintext data may be reborrowed using a [`Delocator`] which was
678    /// initialized from the same slice as `plaintext_locator`.
679    received_plaintext: &'a mut Option<DataKind<UnborrowedPayload>>,
680    _message_lifetime: PhantomData<&'m ()>,
681}
682
683impl<'a, 'm, Send: SendOutput + 'a> Output<'m> for CaptureAppData<'a, '_, 'm, Send> {
684    fn emit(&mut self, ev: Event) {
685        self.other.side.emit(ev)
686    }
687
688    fn output(&mut self, ev: OutputEvent<'_>) {
689        if let OutputEvent::ProtocolVersion(ver) = ev {
690            self.recv.negotiated_version = Some(ver);
691            self.other.send.negotiated_version(ver);
692        }
693        self.other.outputs.handle(ev);
694    }
695
696    fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) -> Result<(), Error> {
697        match self.other.quic.as_deref_mut() {
698            Some(quic) => {
699                quic.send_msg(m, must_encrypt);
700                Ok(())
701            }
702            None => self
703                .other
704                .send
705                .send_msg(m, must_encrypt, self.tls),
706        }
707    }
708
709    fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
710        match &mut self.other.quic {
711            Some(quic) => Some(*quic),
712            None => None,
713        }
714    }
715
716    fn received_plaintext(&mut self, payload: DataKind<Payload<'m>>) {
717        // Receive plaintext data [`Payload<'_>`].
718        //
719        // Since [`Context`] does not hold a lifetime to the receive buffer the
720        // passed [`Payload`] will have it's lifetime erased by storing an index
721        // into the receive buffer as an [`UnborrowedPayload`]. This enables the
722        // data to be later reborrowed after it has been decrypted in-place.
723        let previous = self
724            .received_plaintext
725            .replace(match payload {
726                DataKind::Early(p) => {
727                    DataKind::Early(UnborrowedPayload::unborrow(self.plaintext_locator, p))
728                }
729                DataKind::Traffic(p) => {
730                    DataKind::Traffic(UnborrowedPayload::unborrow(self.plaintext_locator, p))
731                }
732            });
733        debug_assert!(previous.is_none(), "overwrote plaintext data");
734    }
735
736    fn start_traffic(&mut self) {
737        self.recv.may_receive_application_data = true;
738        self.other.send.start_traffic();
739    }
740
741    fn receive(&mut self) -> &mut ReceivePath {
742        self.recv
743    }
744
745    fn send(&mut self) -> &mut dyn SendOutput {
746        self.other.send
747    }
748}
749
750pub(crate) enum DataKind<T> {
751    Early(T),
752    Traffic(T),
753}
754
755pub(super) struct JoinOutput<'a, Send: SendOutput + 'a> {
756    pub(super) outputs: &'a mut dyn ConnectionOutput,
757    pub(super) quic: Option<&'a mut dyn QuicOutput>,
758    pub(super) send: &'a mut Send,
759    pub(super) side: &'a mut dyn SideOutput,
760}
761
762pub(super) struct Discard;
763
764impl ConnectionOutput for Discard {
765    fn handle(&mut self, _ev: OutputEvent<'_>) {}
766}
767
768impl SideOutput for Discard {
769    fn emit(&mut self, _ev: Event) {}
770}
771
772/// Tracking technically-allowed protocol actions
773/// that we limit to avoid denial-of-service vectors.
774struct TemperCounters {
775    allowed_warning_alerts: u8,
776    allowed_renegotiation_requests: u8,
777    allowed_middlebox_ccs: u8,
778}
779
780impl TemperCounters {
781    fn received_warning_alert(&mut self) -> Result<(), Error> {
782        match self.allowed_warning_alerts {
783            0 => Err(PeerMisbehaved::TooManyWarningAlertsReceived.into()),
784            _ => {
785                self.allowed_warning_alerts -= 1;
786                Ok(())
787            }
788        }
789    }
790
791    fn received_renegotiation_request(&mut self) -> Result<(), Error> {
792        match self.allowed_renegotiation_requests {
793            0 => Err(PeerMisbehaved::TooManyRenegotiationRequests.into()),
794            _ => {
795                self.allowed_renegotiation_requests -= 1;
796                Ok(())
797            }
798        }
799    }
800
801    fn received_tls13_change_cipher_spec(&mut self) -> Result<(), Error> {
802        match self.allowed_middlebox_ccs {
803            0 => Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into()),
804            _ => {
805                self.allowed_middlebox_ccs -= 1;
806                Ok(())
807            }
808        }
809    }
810}
811
812impl Default for TemperCounters {
813    fn default() -> Self {
814        Self {
815            // cf. BoringSSL `kMaxWarningAlerts`
816            // <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L137-L139>
817            allowed_warning_alerts: 4,
818
819            // we rebuff renegotiation requests with a `NoRenegotiation` warning alerts.
820            // a second request after this is fatal.
821            allowed_renegotiation_requests: 1,
822
823            // At most two CCS are allowed: one after each ClientHello (recall a second
824            // ClientHello happens after a HelloRetryRequest).
825            //
826            // note BoringSSL allows up to 32.
827            allowed_middlebox_ccs: 2,
828        }
829    }
830}
831
832pub(crate) struct TrafficTemperCounters {
833    allowed_consecutive_handshake_messages: u8,
834}
835
836impl TrafficTemperCounters {
837    pub(crate) fn received_handshake_message(&mut self) -> Result<(), Error> {
838        match self.allowed_consecutive_handshake_messages {
839            0 => Err(PeerMisbehaved::TooManyConsecutiveHandshakeMessagesAfterHandshake.into()),
840            _ => {
841                self.allowed_consecutive_handshake_messages -= 1;
842                Ok(())
843            }
844        }
845    }
846
847    pub(crate) fn received_app_data(&mut self) {
848        self.allowed_consecutive_handshake_messages = Self::MAX_CONSECUTIVE_HANDSHAKE_MESSAGES;
849    }
850
851    // cf. BoringSSL `kMaxKeyUpdates`
852    // <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls13_both.cc#L35-L38>
853    const MAX_CONSECUTIVE_HANDSHAKE_MESSAGES: u8 = 32;
854}
855
856impl Default for TrafficTemperCounters {
857    fn default() -> Self {
858        Self {
859            allowed_consecutive_handshake_messages: Self::MAX_CONSECUTIVE_HANDSHAKE_MESSAGES,
860        }
861    }
862}
863
864pub(crate) struct Input<'a> {
865    pub(crate) message: Message<'a>,
866    pub(crate) aligned_handshake: Option<HandshakeAlignedProof>,
867}
868
869impl Input<'_> {
870    // Changing the keys must not span any fragmented handshake
871    // messages.  Otherwise the defragmented messages will have
872    // been protected with two different record layer protections,
873    // which is illegal.  Not mentioned in RFC.
874    pub(crate) fn check_aligned_handshake(&self) -> Result<HandshakeAlignedProof, Error> {
875        self.aligned_handshake
876            .ok_or_else(|| PeerMisbehaved::KeyEpochWithPendingFragment.into())
877    }
878}
879
880/// An [`Record<Payload<'_>>`] which does not borrow its payload, but
881/// references a range that can later be borrowed.
882struct InboundUnborrowedRecord {
883    typ: ContentType,
884    version: EncodableVersion,
885    bounds: Range<usize>,
886}
887
888impl InboundUnborrowedRecord {
889    fn unborrow(locator: &Locator, record: Record<&'_ [u8]>) -> Self {
890        Self {
891            typ: record.typ,
892            version: record.version,
893            bounds: locator.locate(record.payload),
894        }
895    }
896
897    fn reborrow<'b>(self, delocator: &Delocator<'b>) -> Record<&'b [u8]> {
898        Record {
899            typ: self.typ,
900            version: self.version,
901            payload: delocator.slice_from_range(&self.bounds),
902        }
903    }
904}
905
906/// A buffer of TLS bytes read from a socket, stored in a `Vec<u8>`.
907#[derive(Default)]
908pub struct VecInput {
909    /// Buffer of data read from the socket, in the process of being parsed into messages.
910    ///
911    /// For buffer size management, checkout out the [`VecInput::prepare_read()`] method.
912    buf: Vec<u8>,
913
914    /// What size prefix of `buf` is used.
915    used: usize,
916
917    /// Whether we've seen a 0-byte read.
918    has_seen_eof: bool,
919
920    /// Whether a CloseNotify alert has been seen.
921    received_close_notify: bool,
922}
923
924impl VecInput {
925    /// Discard `taken` bytes from the start of our buffer.
926    pub(crate) fn discard(&mut self, taken: usize) {
927        if taken < self.used {
928            /* Before:
929             * +----------+----------+----------+
930             * | taken    | pending  |xxxxxxxxxx|
931             * +----------+----------+----------+
932             * 0          ^ taken    ^ self.used
933             *
934             * After:
935             * +----------+----------+----------+
936             * | pending  |xxxxxxxxxxxxxxxxxxxxx|
937             * +----------+----------+----------+
938             * 0          ^ self.used
939             */
940
941            self.buf
942                .copy_within(taken..self.used, 0);
943            self.used -= taken;
944        } else if taken >= self.used {
945            self.used = 0;
946        }
947    }
948
949    pub(crate) fn filled_mut(&mut self) -> &mut [u8] {
950        &mut self.buf[..self.used]
951    }
952
953    /// Read some bytes from `rd`, and add them to the buffer.
954    ///
955    /// Once the buffer contains 64 kB of data, we will not read any more bytes until some
956    /// are consumed by reading from the buffer via
957    /// [`Connection::read_tls()`][super::Connection::read_tls()].
958    pub fn read(&mut self, rd: &mut dyn Read) -> io::Result<usize> {
959        if self.received_close_notify {
960            return Ok(0);
961        } else if let Err(err) = self.prepare_read() {
962            return Err(io::Error::new(io::ErrorKind::InvalidData, err));
963        }
964
965        // Try to do the largest reads possible. Note that if
966        // we get a record with a length field out of range here,
967        // we do a zero length read.  That looks like an EOF to
968        // the next layer up, which is fine.
969        let new_bytes = rd.read(&mut self.buf[self.used..])?;
970        if new_bytes == 0 {
971            self.has_seen_eof = true;
972        }
973
974        self.used += new_bytes;
975        Ok(new_bytes)
976    }
977
978    /// Resize the internal `buf` if necessary for reading more bytes.
979    fn prepare_read(&mut self) -> Result<(), &'static str> {
980        /// TLS allows for handshake messages of up to 16MB.  We
981        /// restrict that to 64KB to limit potential for denial-of-
982        /// service.
983        const MAX_HANDSHAKE_SIZE: usize = 0xffff;
984
985        const READ_SIZE: usize = 4096;
986
987        // We allow a maximum of 64k of buffered data. Given that the first read of such a
988        // payload will only ever be 4k bytes, the next time we come around here we allow a
989        // larger buffer size. Once the large message and any following handshake messages in
990        // the same flight have been consumed, `pop()` will call `discard()` to reset `used`.
991        // At this point, the buffer resizing logic below should reduce the buffer size.
992        if self.used >= MAX_HANDSHAKE_SIZE {
993            return Err("message buffer full");
994        }
995
996        // If we can and need to increase the buffer size to allow a 4k read, do so. After
997        // dealing with a large handshake message (exceeding `MAX_HANDSHAKE_SIZE`),
998        // make sure to reduce the buffer size again (large messages should be rare).
999        // Also, reduce the buffer size if there are neither full nor partial messages in it,
1000        // which usually means that the other side suspended sending data.
1001        let need_capacity = Ord::min(MAX_HANDSHAKE_SIZE, self.used + READ_SIZE);
1002        if need_capacity > self.buf.len() {
1003            self.buf.resize(need_capacity, 0);
1004        } else if self.used == 0 || self.buf.len() > MAX_HANDSHAKE_SIZE {
1005            self.buf.resize(need_capacity, 0);
1006            self.buf.shrink_to(need_capacity);
1007        }
1008
1009        Ok(())
1010    }
1011}
1012
1013impl TlsInputBuffer for VecInput {
1014    fn slice_mut(&mut self) -> &mut [u8] {
1015        self.filled_mut()
1016    }
1017
1018    fn discard(&mut self, num_bytes: usize) {
1019        self.discard(num_bytes)
1020    }
1021
1022    fn received_close_notify(&mut self) {
1023        self.received_close_notify = true;
1024    }
1025
1026    fn has_seen_eof(&self) -> bool {
1027        self.has_seen_eof
1028    }
1029}
1030
1031impl fmt::Debug for VecInput {
1032    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1033        let Self {
1034            buf,
1035            used,
1036            has_seen_eof,
1037            received_close_notify,
1038        } = self;
1039        f.debug_struct("VecInput")
1040            .field("buf_len", &buf.len())
1041            .field("used", used)
1042            .field("has_seen_eof", has_seen_eof)
1043            .field("received_close_notify", received_close_notify)
1044            .finish_non_exhaustive()
1045    }
1046}
1047
1048/// A borrowed version of [`VecInput`] that tracks discard operations
1049pub struct SliceInput<'a> {
1050    // a fully initialized buffer that will be deframed
1051    buf: &'a mut [u8],
1052    // number of bytes to discard from the front of `buf` at a later time
1053    discard: usize,
1054    /// Whether we've seen a 0-byte read.
1055    has_seen_eof: bool,
1056    /// Whether a CloseNotify alert has been seen.
1057    received_close_notify: bool,
1058}
1059
1060impl<'a> SliceInput<'a> {
1061    /// Create a new [`SliceInput`] from a mutable slice of bytes.
1062    pub fn new(buf: &'a mut [u8]) -> Self {
1063        Self {
1064            buf,
1065            discard: 0,
1066            has_seen_eof: false,
1067            received_close_notify: false,
1068        }
1069    }
1070
1071    /// Returns how many bytes were consumed at the start of the original buffer.
1072    pub fn into_used(self) -> usize {
1073        self.discard
1074    }
1075}
1076
1077impl TlsInputBuffer for SliceInput<'_> {
1078    fn slice_mut(&mut self) -> &mut [u8] {
1079        &mut self.buf[self.discard..]
1080    }
1081
1082    fn discard(&mut self, num_bytes: usize) {
1083        self.discard += num_bytes;
1084    }
1085
1086    fn received_close_notify(&mut self) {
1087        self.received_close_notify = true;
1088    }
1089
1090    fn has_seen_eof(&self) -> bool {
1091        self.has_seen_eof
1092    }
1093}
1094
1095impl fmt::Debug for SliceInput<'_> {
1096    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1097        let Self {
1098            buf,
1099            discard,
1100            has_seen_eof,
1101            received_close_notify,
1102        } = self;
1103        f.debug_struct("SliceInput")
1104            .field("buf_len", &buf.len())
1105            .field("discard", discard)
1106            .field("has_seen_eof", has_seen_eof)
1107            .field("received_close_notify", received_close_notify)
1108            .finish_non_exhaustive()
1109    }
1110}
1111
1112/// An abstraction over received data buffers (either owned or borrowed)
1113pub trait TlsInputBuffer {
1114    /// Return the buffer which contains the received data.
1115    ///
1116    /// If no data is available, return the empty slice.
1117    ///
1118    /// This is mutable, because the buffer is used for in-place decryption
1119    /// and coalescing of TLS records.  Coalescing of TLS records can happen
1120    /// incrementally over multiple calls into rustls.  As a result the
1121    /// contents of this buffer must not be altered except to add new bytes
1122    /// at the end.
1123    fn slice_mut(&mut self) -> &mut [u8];
1124
1125    /// Discard `num_bytes` from the front of the buffer returned by `slice_mut()`.
1126    ///
1127    /// Multiple calls to `discard()` are cumulative, rather than "last wins".  In
1128    /// other words, `discard(1)` followed by `discard(1)` gives the same result
1129    /// as `discard(2)`.
1130    ///
1131    /// The next call to `slice_mut()` must reflect all previous `discard()`s. In
1132    /// other words, if `slice_mut()` returns slice `[p..q]`, it should then
1133    /// return `[p+n..q]` after `discard(n)`.
1134    ///
1135    /// Rustls guarantees it will not `discard()` more bytes than are returned
1136    /// from `slice_mut()`.
1137    fn discard(&mut self, num_bytes: usize);
1138
1139    /// Signal that the connection has received a TLS `close_notify` alert.
1140    ///
1141    /// The buffer should not accept any more data, because the peer has closed the connection.
1142    fn received_close_notify(&mut self);
1143
1144    /// Whether the buffer has seen a TCP EOF.
1145    ///
1146    /// This is not a TCP-level event, but it is signalled to the TLS state via the input buffer.
1147    fn has_seen_eof(&self) -> bool;
1148}
1149
1150/// cf. BoringSSL's `kMaxEmptyRecords`
1151/// <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L124-L128>
1152const ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX: u8 = 32;
1153
1154#[cfg(test)]
1155mod tests {
1156    use alloc::format;
1157
1158    use super::*;
1159
1160    #[test]
1161    fn test_has_decrypted() {
1162        struct PassThroughDecrypter;
1163        impl RecordDecrypter for PassThroughDecrypter {
1164            fn decrypt<'a>(
1165                &mut self,
1166                record: Record<InboundOpaque<'a>>,
1167                _: u64,
1168            ) -> Result<Record<&'a [u8]>, Error> {
1169                Ok(record.into_plain_record())
1170            }
1171        }
1172
1173        // A record layer starts out invalid, having never decrypted.
1174        let mut record_layer = DecryptionState::new();
1175        assert!(record_layer.record_decrypter.is_none());
1176        assert_eq!(record_layer.read_seq, 0);
1177        assert!(!record_layer.has_decrypted());
1178
1179        // Initializing the record layer should update the decrypt state, but shouldn't affect whether it
1180        // has decrypted.
1181        let deframer = Deframer::default();
1182        record_layer
1183            .set_record_decrypter(Box::new(PassThroughDecrypter), &deframer.aligned().unwrap());
1184        assert!(record_layer.record_decrypter.is_some());
1185        assert_eq!(record_layer.read_seq, 0);
1186        assert!(!record_layer.has_decrypted());
1187
1188        // Decrypting a record should update the read_seq and track that we have now performed
1189        // a decryption.
1190        record_layer
1191            .decrypt_incoming(Record::new(
1192                ContentType::Handshake,
1193                EncodableVersion::Legacy(ProtocolVersion::TLSv1_2),
1194                InboundOpaque(&mut [0xC0, 0xFF, 0xEE]),
1195            ))
1196            .unwrap();
1197        assert_eq!(record_layer.read_seq, 1);
1198        assert!(record_layer.has_decrypted());
1199
1200        // Resetting the record layer decrypter (as if a key update occurred) should reset
1201        // the read_seq number, but not our knowledge of whether we have decrypted previously.
1202        record_layer
1203            .set_record_decrypter(Box::new(PassThroughDecrypter), &deframer.aligned().unwrap());
1204        assert_eq!(record_layer.read_seq, 0);
1205        assert!(record_layer.has_decrypted());
1206    }
1207
1208    #[test]
1209    fn debug_of_input_types() {
1210        let mut buffer = [b'a'; 32];
1211        let mut slice = SliceInput::new(&mut buffer);
1212        slice.discard(2);
1213        assert_eq!(
1214            format!("{slice:?}"),
1215            "SliceInput { buf_len: 32, discard: 2, has_seen_eof: false, received_close_notify: false, .. }"
1216        );
1217
1218        let mut vec = VecInput::default();
1219        vec.prepare_read().unwrap();
1220        assert_eq!(
1221            format!("{vec:?}"),
1222            "VecInput { buf_len: 4096, used: 0, has_seen_eof: false, received_close_notify: false, .. }"
1223        );
1224    }
1225}