Skip to main content

rustls/conn/
receive.rs

1use alloc::vec::Vec;
2use core::marker::PhantomData;
3use core::mem;
4use core::ops::Range;
5use std::io::{self, Read};
6
7use super::send::{SendOutput, SendPath};
8use super::split::SendAdapter;
9use crate::SideData;
10use crate::common_state::{
11    ConnectionOutput, Event, Output, OutputEvent, Side, UnborrowedPayload, maybe_send_fatal_alert,
12};
13use crate::conn::private::SideOutput;
14use crate::conn::{ConnectionCommon, StateMachine};
15use crate::crypto::cipher::{
16    Decrypted, DecryptionState, EncodableVersion, EncodedMessage, Payload,
17};
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}
34
35impl<'a, 'm, Side: SideData> MessageIter<'a, 'm, Side, SendPath> {
36    pub(crate) fn new(
37        input: &'m mut dyn TlsInputBuffer,
38        tls: &'a mut Vec<u8>,
39        quic: Option<&'a mut dyn QuicOutput>,
40        conn: &'a mut ConnectionCommon<Side>,
41    ) -> Self {
42        Self {
43            input,
44            tls,
45            recv: &mut conn.common.recv,
46            state: &mut conn.state,
47            output: JoinOutput {
48                outputs: &mut conn.common.outputs,
49                quic,
50                send: &mut conn.common.send,
51                side: &mut conn.side,
52            },
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    ) -> Self {
65        Self {
66            input,
67            tls,
68            recv,
69            state,
70            output,
71        }
72    }
73}
74
75impl<'a, 'm, Side: SideData, Send: SendOutput + 'a> MessageIter<'a, 'm, Side, Send> {
76    pub(crate) fn next(&mut self) -> Option<Result<UnborrowedPayload, Error>> {
77        let mut st = match mem::replace(self.state, Err(Error::HandshakeNotComplete)) {
78            Ok(state) => state,
79            Err(e) => {
80                *self.state = Err(e.clone());
81                return Some(Err(e));
82            }
83        };
84
85        let mut plaintext = None;
86        while st.wants_input() {
87            let buffer = self.input.slice_mut();
88            let locator = Locator::new(buffer);
89            let res = self.recv.deframe(buffer);
90
91            let mut output = CaptureAppData {
92                recv: self.recv,
93                tls: self.tls,
94                other: &mut self.output,
95                plaintext_locator: &locator,
96                received_plaintext: &mut plaintext,
97                _message_lifetime: PhantomData,
98            };
99
100            let opt_msg = match res {
101                Ok(opt_msg) => opt_msg,
102                Err(e) => {
103                    maybe_send_fatal_alert(output.other.send, &e, output.tls);
104                    if let Error::DecryptError = e {
105                        st.handle_decrypt_error();
106                    }
107                    *self.state = Err(e.clone());
108                    return Some(Err(e));
109                }
110            };
111
112            let Some(msg) = opt_msg else {
113                break;
114            };
115
116            let Decrypted {
117                plaintext: msg,
118                want_close_before_decrypt,
119            } = msg;
120
121            if want_close_before_decrypt {
122                output.other.send.send_alert(
123                    AlertLevel::Warning,
124                    AlertDescription::CloseNotify,
125                    output.tls,
126                );
127            } else if msg.payload.is_empty()
128                && matches!(msg.typ, ContentType::Handshake | ContentType::Alert)
129            {
130                // <https://datatracker.ietf.org/doc/html/rfc9846#section-5.4>
131                output.other.send.send_alert(
132                    AlertLevel::Fatal,
133                    AlertDescription::UnexpectedMessage,
134                    output.tls,
135                );
136                let error = Error::from(PeerMisbehaved::EmptyFragment);
137                *self.state = Err(error.clone());
138                return Some(Err(error));
139            }
140
141            let hs_aligned = output.recv.deframer.aligned();
142            let result =
143                match output
144                    .recv
145                    .receive_message(msg, hs_aligned, output.tls, output.other.send)
146                {
147                    Ok(Some(input)) => st.handle(input, &mut output),
148                    Ok(None) => Ok(st),
149                    Err(e) => Err(e),
150                };
151
152            match result {
153                Ok(new) => st = new,
154                Err(e) => {
155                    maybe_send_fatal_alert(output.other.send, &e, output.tls);
156                    *self.state = Err(e.clone());
157                    return Some(Err(e));
158                }
159            }
160
161            if self.recv.has_received_close_notify {
162                // "Any data received after a closure alert has been received MUST be ignored."
163                // -- <https://datatracker.ietf.org/doc/html/rfc9846#section-6.1>
164
165                // First, discard actually-processed bytes.
166                self.input
167                    .discard(self.recv.deframer.take_discard());
168
169                // Then the rest of any input data.
170                let entirety = self.input.slice_mut().len();
171                self.recv.deframer.set_discard(entirety);
172                self.input.received_close_notify();
173                break;
174            }
175
176            if let Some(payload) = plaintext.take() {
177                *self.state = Ok(st);
178                return Some(Ok(payload));
179            }
180        }
181
182        *self.state = Ok(st);
183        None
184    }
185
186    pub(crate) fn state(&self) -> &Result<Side::State, Error> {
187        self.state
188    }
189}
190
191pub(crate) struct ReceivePath {
192    side: Side,
193    pub(crate) decrypt_state: DecryptionState,
194    pub(crate) may_receive_application_data: bool,
195    /// If the peer has signaled end of stream.
196    pub(crate) has_received_close_notify: bool,
197    temper_counters: TemperCounters,
198    pub(crate) negotiated_version: Option<ProtocolVersion>,
199    pub(crate) deframer: Deframer,
200
201    /// We limit consecutive empty fragments to avoid a route for the peer to send
202    /// us significant but fruitless traffic.
203    seen_consecutive_empty_fragments: u8,
204
205    pub(crate) tls13_tickets_received: u32,
206}
207
208impl ReceivePath {
209    pub(crate) fn new(side: Side) -> Self {
210        Self {
211            side,
212            decrypt_state: DecryptionState::new(),
213            may_receive_application_data: false,
214            has_received_close_notify: false,
215            temper_counters: TemperCounters::default(),
216            negotiated_version: None,
217            deframer: Deframer::default(),
218            seen_consecutive_empty_fragments: 0,
219            tls13_tickets_received: 0,
220        }
221    }
222
223    /// Pull a message out of the deframer and send any messages that need to be sent as a result.
224    fn deframe<'b>(&mut self, buffer: &'b mut [u8]) -> Result<Option<Decrypted<'b>>, Error> {
225        let locator = Locator::new(buffer);
226
227        let mut want_close_before_decrypt = false;
228        loop {
229            // before processing any more of `buffer`, return any extant messages from `deframer`
230            if let Some(span) = self.deframer.complete_span() {
231                let plaintext = self.deframer.message(span, buffer);
232
233                // trial decryption finishes with the first handshake message after it started.
234                self.decrypt_state
235                    .finish_trial_decryption();
236
237                return Ok(Some(Decrypted {
238                    plaintext,
239                    want_close_before_decrypt,
240                }));
241            }
242
243            let (message, bounds) = loop {
244                match self.deframe_decrypted(buffer, &locator)? {
245                    DeframeResult::Decrypted(decrypted, bounds) => break (decrypted, bounds),
246                    DeframeResult::DecryptionFailed => continue,
247                    DeframeResult::None => return Ok(None),
248                }
249            };
250
251            want_close_before_decrypt = message.want_close_before_decrypt;
252            let Decrypted {
253                plaintext: message,
254                want_close_before_decrypt: _,
255            } = message;
256
257            if self.deframer.aligned().is_none() && message.typ != ContentType::Handshake {
258                // "Handshake messages MUST NOT be interleaved with other record
259                // types.  That is, if a handshake message is split over two or more
260                // records, there MUST NOT be any other records between them."
261                // https://www.rfc-editor.org/rfc/rfc9846#section-5.1
262                return Err(PeerMisbehaved::MessageInterleavedWithHandshakeMessage.into());
263            }
264
265            match message.payload.len() {
266                0 => {
267                    if self.seen_consecutive_empty_fragments
268                        == ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX
269                    {
270                        return Err(PeerMisbehaved::TooManyEmptyFragments.into());
271                    }
272                    self.seen_consecutive_empty_fragments += 1;
273                }
274                _ => {
275                    self.seen_consecutive_empty_fragments = 0;
276                }
277            };
278
279            // do an end-run around the borrow checker, converting `message` (containing
280            // a borrowed slice) to an unborrowed one (containing a `Range` into the
281            // same buffer).  the reborrow happens inside the branch that returns the
282            // message.
283            //
284            // is fixed by -Zpolonius
285            // https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md#problem-case-3-conditional-control-flow-across-functions
286            let unborrowed = InboundUnborrowedMessage::unborrow(&locator, message);
287
288            if unborrowed.typ != ContentType::Handshake {
289                let message = unborrowed.reborrow(&Delocator::new(buffer));
290                self.deframer.discard_processed();
291                return Ok(Some(Decrypted {
292                    plaintext: message,
293                    want_close_before_decrypt,
294                }));
295            }
296
297            let message = unborrowed.reborrow(&Delocator::new(buffer));
298            self.deframer
299                .input_message(message.version.version(), bounds, buffer);
300            self.deframer.coalesce(buffer)?;
301        }
302    }
303
304    fn deframe_decrypted<'b>(
305        &mut self,
306        buffer: &'b mut [u8],
307        locator: &Locator,
308    ) -> Result<DeframeResult<'b>, Error> {
309        let (message, bounds) = match self.deframer.deframe(buffer) {
310            Some(Ok(Deframed { message, bounds })) => (message, bounds),
311            Some(Err(err)) => return Err(err),
312            None => return Ok(DeframeResult::None),
313        };
314
315        let allowed_plaintext = match message.typ {
316            // CCS messages are always plaintext.
317            ContentType::ChangeCipherSpec => true,
318            // Alerts are allowed to be plaintext if-and-only-if:
319            // * The negotiated protocol version is TLS 1.3. - In TLS 1.2 it is unambiguous when
320            //   keying changes based on the CCS message. Only TLS 1.3 requires these heuristics.
321            // * We have not yet decrypted any messages from the peer - if we have we don't
322            //   expect any plaintext.
323            // * The payload size is indicative of a plaintext alert message.
324            ContentType::Alert
325                if matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
326                    && !self.decrypt_state.has_decrypted()
327                    && message.payload.len() <= 2 =>
328            {
329                true
330            }
331            // In other circumstances, we expect all messages to be encrypted.
332            _ => false,
333        };
334
335        if allowed_plaintext && !self.deframer.is_active() {
336            return Ok(DeframeResult::Decrypted(
337                Decrypted {
338                    plaintext: message.into_plain_message(),
339                    want_close_before_decrypt: false,
340                },
341                bounds,
342            ));
343        }
344
345        match self
346            .decrypt_state
347            .decrypt_incoming(message)?
348        {
349            Some(decrypted) => {
350                // After decryption, the payload is shorter
351                let bounds = locator.locate(decrypted.plaintext.payload);
352                Ok(DeframeResult::Decrypted(decrypted, bounds))
353            }
354
355            // failed decryption during trial decryption is not allowed to be
356            // interleaved with partial handshake data.
357            None if self.deframer.aligned().is_none() => {
358                Err(PeerMisbehaved::RejectedEarlyDataInterleavedWithHandshakeMessage.into())
359            }
360
361            // failed decryption during trial decryption.
362            None => Ok(DeframeResult::DecryptionFailed),
363        }
364    }
365
366    /// Take a TLS message `msg` and map it into an `Input`
367    ///
368    /// `Input` is the input to our state machine.
369    ///
370    /// The message is mapped into `None` if it should be dropped with no further
371    /// action.
372    ///
373    /// Otherwise the caller must present the returned `Input` to the state machine to
374    /// progress the connection.
375    pub(crate) fn receive_message<'a>(
376        &mut self,
377        msg: EncodedMessage<&'a [u8]>,
378        aligned_handshake: Option<HandshakeAlignedProof>,
379        tls: &mut Vec<u8>,
380        send: &mut dyn SendOutput,
381    ) -> Result<Option<Input<'a>>, Error> {
382        // Drop CCS messages during handshake in TLS1.3
383        if msg.typ == ContentType::ChangeCipherSpec && self.drop_tls13_ccs(&msg)? {
384            trace!("Dropping CCS");
385            return Ok(None);
386        }
387
388        // Now we can fully parse the message payload.
389        let message = Message::try_from(msg)?;
390
391        // For alerts, we have separate logic.
392        if let MessagePayload::Alert(alert) = &message.payload {
393            self.process_alert(alert)?;
394            return Ok(None);
395        }
396
397        // For TLS1.2, outside of the handshake, send rejection alerts for
398        // renegotiation requests.  These can occur any time.
399        if self.reject_renegotiation_request(&message, tls, send)? {
400            return Ok(None);
401        }
402
403        Ok(Some(Input {
404            message,
405            aligned_handshake,
406        }))
407    }
408
409    fn drop_tls13_ccs(&mut self, msg: &EncodedMessage<&'_ [u8]>) -> Result<bool, Error> {
410        if self.may_receive_application_data
411            || !matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
412        {
413            return Ok(false);
414        }
415
416        if !msg.is_valid_ccs() {
417            // "An implementation which receives any other change_cipher_spec value or
418            //  which receives a protected change_cipher_spec record MUST abort the
419            //  handshake with an "unexpected_message" alert."
420            return Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into());
421        }
422
423        self.temper_counters
424            .received_tls13_change_cipher_spec()?;
425        Ok(true)
426    }
427
428    fn reject_renegotiation_request(
429        &mut self,
430        msg: &Message<'_>,
431        tls: &mut Vec<u8>,
432        send: &mut dyn SendOutput,
433    ) -> Result<bool, Error> {
434        if !self.may_receive_application_data
435            || matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
436        {
437            return Ok(false);
438        }
439
440        let reject_ty = match self.side {
441            Side::Client => HandshakeType::HelloRequest,
442            Side::Server => HandshakeType::ClientHello,
443        };
444
445        if msg.handshake_type() != Some(reject_ty) {
446            return Ok(false);
447        }
448        self.temper_counters
449            .received_renegotiation_request()?;
450        let desc = AlertDescription::NoRenegotiation;
451        warn!("sending warning alert {desc:?}");
452        send.send_alert(AlertLevel::Warning, desc, tls);
453        Ok(true)
454    }
455
456    fn process_alert(&mut self, alert: &AlertMessagePayload) -> Result<(), Error> {
457        // Reject unknown AlertLevels.
458        if AlertLevelName::try_from(alert.level).is_err() {
459            return Err(PeerMisbehaved::IllegalAlertLevel(alert.level.0, alert.description).into());
460        }
461
462        // If we get a CloseNotify, make a note to declare EOF to our
463        // caller.  But do not treat unauthenticated alerts like this.
464        if self.may_receive_application_data && alert.description == AlertDescription::CloseNotify {
465            self.has_received_close_notify = true;
466            return Ok(());
467        }
468
469        // Warnings are nonfatal for TLS1.2, but outlawed in TLS1.3
470        // (except, for no good reason, user_cancelled).
471        let err = Error::AlertReceived(alert.description);
472        if alert.level == AlertLevel::Warning {
473            self.temper_counters
474                .received_warning_alert()?;
475            if matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
476                && alert.description != AlertDescription::UserCanceled
477            {
478                return Err(PeerMisbehaved::IllegalWarningAlert(alert.description).into());
479            }
480
481            // Some implementations send pointless `user_canceled` alerts, don't log them
482            // in release mode (https://bugs.openjdk.org/browse/JDK-8323517).
483            if alert.description != AlertDescription::UserCanceled || cfg!(debug_assertions) {
484                warn!("TLS alert warning received: {alert:?}");
485            }
486
487            return Ok(());
488        }
489
490        Err(err)
491    }
492}
493
494enum DeframeResult<'b> {
495    Decrypted(Decrypted<'b>, Range<usize>),
496    DecryptionFailed,
497    None,
498}
499
500struct CaptureAppData<'a, 'j, 'm, Send: SendOutput + 'a> {
501    recv: &'a mut ReceivePath,
502    other: &'a mut JoinOutput<'j, Send>,
503    tls: &'a mut Vec<u8>,
504    /// Store a [`Locator`] initialized from the current receive buffer
505    ///
506    /// Allows received plaintext data to be unborrowed and stored in
507    /// `received_plaintext` for in-place decryption.
508    plaintext_locator: &'a Locator,
509    /// Unborrowed received plaintext data
510    ///
511    /// Set if plaintext data was received.
512    ///
513    /// Plaintext data may be reborrowed using a [`Delocator`] which was
514    /// initialized from the same slice as `plaintext_locator`.
515    received_plaintext: &'a mut Option<UnborrowedPayload>,
516    _message_lifetime: PhantomData<&'m ()>,
517}
518
519impl<'a, 'm, Send: SendOutput + 'a> Output<'m> for CaptureAppData<'a, '_, 'm, Send> {
520    fn emit(&mut self, ev: Event<'_>) {
521        self.other.side.emit(ev)
522    }
523
524    fn output(&mut self, ev: OutputEvent<'_>) {
525        if let OutputEvent::ProtocolVersion(ver) = ev {
526            self.recv.negotiated_version = Some(ver);
527            self.other.send.negotiated_version(ver);
528        }
529        self.other.outputs.handle(ev);
530    }
531
532    fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) {
533        match self.other.quic.as_deref_mut() {
534            Some(quic) => quic.send_msg(m, must_encrypt),
535            None => self
536                .other
537                .send
538                .send_msg(m, must_encrypt, self.tls),
539        }
540    }
541
542    fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
543        match &mut self.other.quic {
544            Some(quic) => Some(*quic),
545            None => None,
546        }
547    }
548
549    fn received_plaintext(&mut self, payload: Payload<'m>) {
550        // Receive plaintext data [`Payload<'_>`].
551        //
552        // Since [`Context`] does not hold a lifetime to the receive buffer the
553        // passed [`Payload`] will have it's lifetime erased by storing an index
554        // into the receive buffer as an [`UnborrowedPayload`]. This enables the
555        // data to be later reborrowed after it has been decrypted in-place.
556        let previous = self
557            .received_plaintext
558            .replace(UnborrowedPayload::unborrow(self.plaintext_locator, payload));
559        debug_assert!(previous.is_none(), "overwrote plaintext data");
560    }
561
562    fn start_traffic(&mut self) {
563        self.recv.may_receive_application_data = true;
564        self.other.send.start_traffic();
565    }
566
567    fn receive(&mut self) -> &mut ReceivePath {
568        self.recv
569    }
570
571    fn send(&mut self) -> &mut dyn SendOutput {
572        self.other.send
573    }
574}
575
576pub(super) struct JoinOutput<'a, Send: SendOutput + 'a> {
577    pub(super) outputs: &'a mut dyn ConnectionOutput,
578    pub(super) quic: Option<&'a mut dyn QuicOutput>,
579    pub(super) send: &'a mut Send,
580    pub(super) side: &'a mut dyn SideOutput,
581}
582
583pub(super) struct Discard;
584
585impl ConnectionOutput for Discard {
586    fn handle(&mut self, _ev: OutputEvent<'_>) {}
587}
588
589impl SideOutput for Discard {
590    fn emit(&mut self, _ev: Event<'_>) {}
591}
592
593/// Tracking technically-allowed protocol actions
594/// that we limit to avoid denial-of-service vectors.
595struct TemperCounters {
596    allowed_warning_alerts: u8,
597    allowed_renegotiation_requests: u8,
598    allowed_middlebox_ccs: u8,
599}
600
601impl TemperCounters {
602    fn received_warning_alert(&mut self) -> Result<(), Error> {
603        match self.allowed_warning_alerts {
604            0 => Err(PeerMisbehaved::TooManyWarningAlertsReceived.into()),
605            _ => {
606                self.allowed_warning_alerts -= 1;
607                Ok(())
608            }
609        }
610    }
611
612    fn received_renegotiation_request(&mut self) -> Result<(), Error> {
613        match self.allowed_renegotiation_requests {
614            0 => Err(PeerMisbehaved::TooManyRenegotiationRequests.into()),
615            _ => {
616                self.allowed_renegotiation_requests -= 1;
617                Ok(())
618            }
619        }
620    }
621
622    fn received_tls13_change_cipher_spec(&mut self) -> Result<(), Error> {
623        match self.allowed_middlebox_ccs {
624            0 => Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into()),
625            _ => {
626                self.allowed_middlebox_ccs -= 1;
627                Ok(())
628            }
629        }
630    }
631}
632
633impl Default for TemperCounters {
634    fn default() -> Self {
635        Self {
636            // cf. BoringSSL `kMaxWarningAlerts`
637            // <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L137-L139>
638            allowed_warning_alerts: 4,
639
640            // we rebuff renegotiation requests with a `NoRenegotiation` warning alerts.
641            // a second request after this is fatal.
642            allowed_renegotiation_requests: 1,
643
644            // At most two CCS are allowed: one after each ClientHello (recall a second
645            // ClientHello happens after a HelloRetryRequest).
646            //
647            // note BoringSSL allows up to 32.
648            allowed_middlebox_ccs: 2,
649        }
650    }
651}
652
653pub(crate) struct TrafficTemperCounters {
654    allowed_consecutive_handshake_messages: u8,
655}
656
657impl TrafficTemperCounters {
658    pub(crate) fn received_handshake_message(&mut self) -> Result<(), Error> {
659        match self.allowed_consecutive_handshake_messages {
660            0 => Err(PeerMisbehaved::TooManyConsecutiveHandshakeMessagesAfterHandshake.into()),
661            _ => {
662                self.allowed_consecutive_handshake_messages -= 1;
663                Ok(())
664            }
665        }
666    }
667
668    pub(crate) fn received_app_data(&mut self) {
669        self.allowed_consecutive_handshake_messages = Self::MAX_CONSECUTIVE_HANDSHAKE_MESSAGES;
670    }
671
672    // cf. BoringSSL `kMaxKeyUpdates`
673    // <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls13_both.cc#L35-L38>
674    const MAX_CONSECUTIVE_HANDSHAKE_MESSAGES: u8 = 32;
675}
676
677impl Default for TrafficTemperCounters {
678    fn default() -> Self {
679        Self {
680            allowed_consecutive_handshake_messages: Self::MAX_CONSECUTIVE_HANDSHAKE_MESSAGES,
681        }
682    }
683}
684
685pub(crate) struct Input<'a> {
686    pub(crate) message: Message<'a>,
687    pub(crate) aligned_handshake: Option<HandshakeAlignedProof>,
688}
689
690impl Input<'_> {
691    // Changing the keys must not span any fragmented handshake
692    // messages.  Otherwise the defragmented messages will have
693    // been protected with two different record layer protections,
694    // which is illegal.  Not mentioned in RFC.
695    pub(crate) fn check_aligned_handshake(&self) -> Result<HandshakeAlignedProof, Error> {
696        self.aligned_handshake
697            .ok_or_else(|| PeerMisbehaved::KeyEpochWithPendingFragment.into())
698    }
699}
700
701/// An [`EncodedMessage<Payload<'_>>`] which does not borrow its payload, but
702/// references a range that can later be borrowed.
703struct InboundUnborrowedMessage {
704    typ: ContentType,
705    version: EncodableVersion,
706    bounds: Range<usize>,
707}
708
709impl InboundUnborrowedMessage {
710    fn unborrow(locator: &Locator, msg: EncodedMessage<&'_ [u8]>) -> Self {
711        Self {
712            typ: msg.typ,
713            version: msg.version,
714            bounds: locator.locate(msg.payload),
715        }
716    }
717
718    fn reborrow<'b>(self, delocator: &Delocator<'b>) -> EncodedMessage<&'b [u8]> {
719        EncodedMessage {
720            typ: self.typ,
721            version: self.version,
722            payload: delocator.slice_from_range(&self.bounds),
723        }
724    }
725}
726
727/// A buffer of TLS bytes read from a socket, stored in a `Vec<u8>`.
728#[derive(Default, Debug)]
729pub struct VecInput {
730    /// Buffer of data read from the socket, in the process of being parsed into messages.
731    ///
732    /// For buffer size management, checkout out the [`VecInput::prepare_read()`] method.
733    buf: Vec<u8>,
734
735    /// What size prefix of `buf` is used.
736    used: usize,
737
738    /// Whether we've seen a 0-byte read.
739    has_seen_eof: bool,
740
741    /// Whether a CloseNotify alert has been seen.
742    received_close_notify: bool,
743}
744
745impl VecInput {
746    /// Discard `taken` bytes from the start of our buffer.
747    pub(crate) fn discard(&mut self, taken: usize) {
748        if taken < self.used {
749            /* Before:
750             * +----------+----------+----------+
751             * | taken    | pending  |xxxxxxxxxx|
752             * +----------+----------+----------+
753             * 0          ^ taken    ^ self.used
754             *
755             * After:
756             * +----------+----------+----------+
757             * | pending  |xxxxxxxxxxxxxxxxxxxxx|
758             * +----------+----------+----------+
759             * 0          ^ self.used
760             */
761
762            self.buf
763                .copy_within(taken..self.used, 0);
764            self.used -= taken;
765        } else if taken >= self.used {
766            self.used = 0;
767        }
768    }
769
770    pub(crate) fn filled_mut(&mut self) -> &mut [u8] {
771        &mut self.buf[..self.used]
772    }
773
774    /// Read some bytes from `rd`, and add them to the buffer.
775    ///
776    /// Once the buffer contains 64 kB of data, we will not read any more bytes until some
777    /// are consumed by reading from the buffer via
778    /// [`Connection::process_new_packets()`][super::Connection::process_new_packets()].
779    pub fn read(&mut self, rd: &mut dyn Read) -> io::Result<usize> {
780        if self.received_close_notify {
781            return Ok(0);
782        } else if let Err(err) = self.prepare_read() {
783            return Err(io::Error::new(io::ErrorKind::InvalidData, err));
784        }
785
786        // Try to do the largest reads possible. Note that if
787        // we get a message with a length field out of range here,
788        // we do a zero length read.  That looks like an EOF to
789        // the next layer up, which is fine.
790        let new_bytes = rd.read(&mut self.buf[self.used..])?;
791        if new_bytes == 0 {
792            self.has_seen_eof = true;
793        }
794
795        self.used += new_bytes;
796        Ok(new_bytes)
797    }
798
799    /// Resize the internal `buf` if necessary for reading more bytes.
800    fn prepare_read(&mut self) -> Result<(), &'static str> {
801        /// TLS allows for handshake messages of up to 16MB.  We
802        /// restrict that to 64KB to limit potential for denial-of-
803        /// service.
804        const MAX_HANDSHAKE_SIZE: usize = 0xffff;
805
806        const READ_SIZE: usize = 4096;
807
808        // We allow a maximum of 64k of buffered data. Given that the first read of such a
809        // payload will only ever be 4k bytes, the next time we come around here we allow a
810        // larger buffer size. Once the large message and any following handshake messages in
811        // the same flight have been consumed, `pop()` will call `discard()` to reset `used`.
812        // At this point, the buffer resizing logic below should reduce the buffer size.
813        if self.used >= MAX_HANDSHAKE_SIZE {
814            return Err("message buffer full");
815        }
816
817        // If we can and need to increase the buffer size to allow a 4k read, do so. After
818        // dealing with a large handshake message (exceeding `MAX_HANDSHAKE_SIZE`),
819        // make sure to reduce the buffer size again (large messages should be rare).
820        // Also, reduce the buffer size if there are neither full nor partial messages in it,
821        // which usually means that the other side suspended sending data.
822        let need_capacity = Ord::min(MAX_HANDSHAKE_SIZE, self.used + READ_SIZE);
823        if need_capacity > self.buf.len() {
824            self.buf.resize(need_capacity, 0);
825        } else if self.used == 0 || self.buf.len() > MAX_HANDSHAKE_SIZE {
826            self.buf.resize(need_capacity, 0);
827            self.buf.shrink_to(need_capacity);
828        }
829
830        Ok(())
831    }
832}
833
834impl TlsInputBuffer for VecInput {
835    fn slice_mut(&mut self) -> &mut [u8] {
836        self.filled_mut()
837    }
838
839    fn discard(&mut self, num_bytes: usize) {
840        self.discard(num_bytes)
841    }
842
843    fn received_close_notify(&mut self) {
844        self.received_close_notify = true;
845    }
846
847    fn has_seen_eof(&self) -> bool {
848        self.has_seen_eof
849    }
850}
851
852/// A borrowed version of [`VecInput`] that tracks discard operations
853#[derive(Debug)]
854pub struct SliceInput<'a> {
855    // a fully initialized buffer that will be deframed
856    buf: &'a mut [u8],
857    // number of bytes to discard from the front of `buf` at a later time
858    discard: usize,
859    /// Whether we've seen a 0-byte read.
860    has_seen_eof: bool,
861    /// Whether a CloseNotify alert has been seen.
862    received_close_notify: bool,
863}
864
865impl<'a> SliceInput<'a> {
866    /// Create a new [`SliceInput`] from a mutable slice of bytes.
867    pub fn new(buf: &'a mut [u8]) -> Self {
868        Self {
869            buf,
870            discard: 0,
871            has_seen_eof: false,
872            received_close_notify: false,
873        }
874    }
875
876    /// Returns how many bytes were consumed at the start of the original buffer.
877    pub fn into_used(self) -> usize {
878        self.discard
879    }
880}
881
882impl TlsInputBuffer for SliceInput<'_> {
883    fn slice_mut(&mut self) -> &mut [u8] {
884        &mut self.buf[self.discard..]
885    }
886
887    fn discard(&mut self, num_bytes: usize) {
888        self.discard += num_bytes;
889    }
890
891    fn received_close_notify(&mut self) {
892        self.received_close_notify = true;
893    }
894
895    fn has_seen_eof(&self) -> bool {
896        self.has_seen_eof
897    }
898}
899
900/// An abstraction over received data buffers (either owned or borrowed)
901pub trait TlsInputBuffer {
902    /// Return the buffer which contains the received data.
903    ///
904    /// If no data is available, return the empty slice.
905    ///
906    /// This is mutable, because the buffer is used for in-place decryption
907    /// and coalescing of TLS records.  Coalescing of TLS records can happen
908    /// incrementally over multiple calls into rustls.  As a result the
909    /// contents of this buffer must not be altered except to add new bytes
910    /// at the end.
911    fn slice_mut(&mut self) -> &mut [u8];
912
913    /// Discard `num_bytes` from the front of the buffer returned by `slice_mut()`.
914    ///
915    /// Multiple calls to `discard()` are cumulative, rather than "last wins".  In
916    /// other words, `discard(1)` followed by `discard(1)` gives the same result
917    /// as `discard(2)`.
918    ///
919    /// The next call to `slice_mut()` must reflect all previous `discard()`s. In
920    /// other words, if `slice_mut()` returns slice `[p..q]`, it should then
921    /// return `[p+n..q]` after `discard(n)`.
922    ///
923    /// Rustls guarantees it will not `discard()` more bytes than are returned
924    /// from `slice_mut()`.
925    fn discard(&mut self, num_bytes: usize);
926
927    /// Signal that the connection has received a TLS `close_notify` alert.
928    ///
929    /// The buffer should not accept any more data, because the peer has closed the connection.
930    fn received_close_notify(&mut self);
931
932    /// Whether the buffer has seen a TCP EOF.
933    ///
934    /// This is not a TCP-level event, but it is signalled to the TLS state via the input buffer.
935    fn has_seen_eof(&self) -> bool;
936}
937
938/// cf. BoringSSL's `kMaxEmptyRecords`
939/// <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L124-L128>
940const ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX: u8 = 32;