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