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