Skip to main content

rustls/
common_state.rs

1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt;
4use core::ops::{Deref, DerefMut, Range};
5
6use pki_types::DnsName;
7
8use crate::client::EchStatus;
9use crate::conn::Exporter;
10use crate::conn::unbuffered::{EncryptError, InsufficientSizeError};
11use crate::crypto::Identity;
12use crate::crypto::cipher::{
13    Decrypted, DecryptionState, EncodedMessage, EncryptionState, MessageDecrypter,
14    MessageEncrypter, OutboundOpaque, OutboundPlain, Payload, PreEncryptAction,
15};
16use crate::crypto::kx::SupportedKxGroup;
17use crate::crypto::tls13::OkmBlock;
18use crate::enums::{ApplicationProtocol, ContentType, HandshakeType, ProtocolVersion};
19use crate::error::{AlertDescription, Error, PeerMisbehaved};
20use crate::hash_hs::HandshakeHash;
21use crate::log::{debug, error, trace, warn};
22use crate::msgs::{
23    AlertLevel, AlertMessagePayload, BufferProgress, Codec, DeframerIter, Delocator,
24    HandshakeAlignedProof, HandshakeDeframer, HandshakeMessagePayload, Locator, Message,
25    MessageFragmenter, MessagePayload,
26};
27use crate::quic;
28use crate::suites::SupportedCipherSuite;
29use crate::tls13::key_schedule::KeyScheduleTrafficSend;
30use crate::vecbuf::ChunkVecBuffer;
31
32/// Connection state common to both client and server connections.
33pub struct CommonState {
34    pub(crate) outputs: ConnectionOutputs,
35    pub(crate) send: SendPath,
36    pub(crate) recv: ReceivePath,
37    pub(crate) quic: quic::Quic,
38
39    /// Protocol whose key schedule should be used. Unused for TLS < 1.3.
40    pub(crate) protocol: Protocol,
41}
42
43impl CommonState {
44    pub(crate) fn new(side: Side, protocol: Protocol) -> Self {
45        Self {
46            outputs: ConnectionOutputs::default(),
47            send: SendPath::default(),
48            recv: ReceivePath::new(side),
49            quic: quic::Quic::default(),
50            protocol,
51        }
52    }
53
54    /// Returns true if the caller should call [`Connection::write_tls`] as soon as possible.
55    ///
56    /// [`Connection::write_tls`]: crate::Connection::write_tls
57    pub fn wants_write(&self) -> bool {
58        !self.send.sendable_tls.is_empty()
59    }
60
61    /// Queues a `close_notify` warning alert to be sent in the next
62    /// [`Connection::write_tls`] call.  This informs the peer that the
63    /// connection is being closed.
64    ///
65    /// Does nothing if any `close_notify` or fatal alert was already sent.
66    ///
67    /// [`Connection::write_tls`]: crate::Connection::write_tls
68    pub fn send_close_notify(&mut self) {
69        self.send.send_close_notify()
70    }
71
72    /// Returns true if the connection is currently performing the TLS handshake.
73    ///
74    /// During this time plaintext written to the connection is buffered in memory. After
75    /// [`Connection::process_new_packets()`] has been called, this might start to return `false`
76    /// while the final handshake packets still need to be extracted from the connection's buffers.
77    ///
78    /// [`Connection::process_new_packets()`]: crate::Connection::process_new_packets
79    pub fn is_handshaking(&self) -> bool {
80        !(self.send.may_send_application_data && self.recv.may_receive_application_data)
81    }
82}
83
84impl Output for CommonState {
85    fn emit(&mut self, ev: Event<'_>) {
86        match ev.disposition() {
87            EventDisposition::MessageOutput => match self.protocol {
88                Protocol::Tcp => self.send.emit(ev),
89                Protocol::Quic(_) => self.quic.emit(ev),
90            },
91
92            EventDisposition::SendPath => self.send.emit(ev),
93            EventDisposition::ReceivePath => self.recv.emit(ev),
94            EventDisposition::ConnectionOutputs => self.outputs.emit(ev),
95            EventDisposition::Quic => self.quic.emit(ev),
96            EventDisposition::SideSpecific => unreachable!(),
97
98            EventDisposition::ProtocolVersion(ver) => {
99                self.outputs
100                    .emit(Event::ProtocolVersion(ver));
101                self.recv
102                    .emit(Event::ProtocolVersion(ver));
103                self.send
104                    .emit(Event::ProtocolVersion(ver));
105            }
106            EventDisposition::StartTraffic => {
107                self.recv.emit(Event::StartTraffic);
108                self.send.emit(Event::StartTraffic);
109            }
110        }
111    }
112}
113
114impl Deref for CommonState {
115    type Target = ConnectionOutputs;
116
117    fn deref(&self) -> &Self::Target {
118        &self.outputs
119    }
120}
121
122impl DerefMut for CommonState {
123    fn deref_mut(&mut self) -> &mut Self::Target {
124        &mut self.outputs
125    }
126}
127
128impl fmt::Debug for CommonState {
129    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130        f.debug_struct("CommonState")
131            .finish_non_exhaustive()
132    }
133}
134
135/// Facts about the connection learned through the handshake.
136#[derive(Default)]
137pub struct ConnectionOutputs {
138    negotiated_version: Option<ProtocolVersion>,
139    handshake_kind: Option<HandshakeKind>,
140    suite: Option<SupportedCipherSuite>,
141    negotiated_kx_group: Option<&'static dyn SupportedKxGroup>,
142    alpn_protocol: Option<ApplicationProtocol<'static>>,
143    peer_identity: Option<Identity<'static>>,
144    pub(crate) exporter: Option<Box<dyn Exporter>>,
145    pub(crate) early_exporter: Option<Box<dyn Exporter>>,
146}
147
148impl ConnectionOutputs {
149    /// Retrieves the certificate chain or the raw public key used by the peer to authenticate.
150    ///
151    /// This is made available for both full and resumed handshakes.
152    ///
153    /// For clients, this is the identity of the server. For servers, this is the identity of the
154    /// client, if client authentication was completed.
155    ///
156    /// The return value is None until this value is available.
157    pub fn peer_identity(&self) -> Option<&Identity<'static>> {
158        self.peer_identity.as_ref()
159    }
160
161    /// Retrieves the protocol agreed with the peer via ALPN.
162    ///
163    /// A return value of `None` after handshake completion
164    /// means no protocol was agreed (because no protocols
165    /// were offered or accepted by the peer).
166    pub fn alpn_protocol(&self) -> Option<&ApplicationProtocol<'static>> {
167        self.alpn_protocol.as_ref()
168    }
169
170    /// Retrieves the cipher suite agreed with the peer.
171    ///
172    /// This returns None until the cipher suite is agreed.
173    pub fn negotiated_cipher_suite(&self) -> Option<SupportedCipherSuite> {
174        self.suite
175    }
176
177    /// Retrieves the key exchange group agreed with the peer.
178    ///
179    /// This function may return `None` depending on the state of the connection,
180    /// the type of handshake, and the protocol version.
181    ///
182    /// If [`CommonState::is_handshaking()`] is true this function will return `None`.
183    /// Similarly, if the [`ConnectionOutputs::handshake_kind()`] is [`HandshakeKind::Resumed`]
184    /// and the [`ConnectionOutputs::protocol_version()`] is TLS 1.2, then no key exchange will have
185    /// occurred and this function will return `None`.
186    pub fn negotiated_key_exchange_group(&self) -> Option<&'static dyn SupportedKxGroup> {
187        self.negotiated_kx_group
188    }
189
190    /// Retrieves the protocol version agreed with the peer.
191    ///
192    /// This returns `None` until the version is agreed.
193    pub fn protocol_version(&self) -> Option<ProtocolVersion> {
194        self.negotiated_version
195    }
196
197    /// Which kind of handshake was performed.
198    ///
199    /// This tells you whether the handshake was a resumption or not.
200    ///
201    /// This will return `None` before it is known which sort of
202    /// handshake occurred.
203    pub fn handshake_kind(&self) -> Option<HandshakeKind> {
204        self.handshake_kind
205    }
206
207    pub(super) fn into_kernel_parts(self) -> Option<(ProtocolVersion, SupportedCipherSuite)> {
208        let Self {
209            negotiated_version,
210            suite,
211            ..
212        } = self;
213
214        match (negotiated_version, suite) {
215            (Some(version), Some(suite)) => Some((version, suite)),
216            _ => None,
217        }
218    }
219}
220
221impl Output for ConnectionOutputs {
222    fn emit(&mut self, ev: Event<'_>) {
223        match ev {
224            Event::ApplicationProtocol(protocol) => {
225                self.alpn_protocol = Some(ApplicationProtocol::from(protocol.as_ref()).to_owned())
226            }
227            Event::CipherSuite(suite) => self.suite = Some(suite),
228            Event::EarlyExporter(exporter) => self.early_exporter = Some(exporter),
229            Event::Exporter(exporter) => self.exporter = Some(exporter),
230            Event::HandshakeKind(hk) => {
231                assert!(self.handshake_kind.is_none());
232                self.handshake_kind = Some(hk);
233            }
234            Event::KeyExchangeGroup(kxg) => {
235                assert!(self.negotiated_kx_group.is_none());
236                self.negotiated_kx_group = Some(kxg);
237            }
238            Event::PeerIdentity(identity) => self.peer_identity = Some(identity),
239            Event::ProtocolVersion(ver) => {
240                self.negotiated_version = Some(ver);
241            }
242            _ => unreachable!(),
243        }
244    }
245}
246
247/// Send an alert via `output` if `error` specifies one.
248pub(crate) fn maybe_send_fatal_alert(output: &mut dyn Output, error: &Error) {
249    let Ok(alert) = AlertDescription::try_from(error) else {
250        return;
251    };
252    output.emit(Event::SendAlert(AlertLevel::Fatal, alert));
253}
254
255/// The data path from us to the peer.
256pub(crate) struct SendPath {
257    pub(crate) encrypt_state: EncryptionState,
258    pub(crate) may_send_application_data: bool,
259    has_sent_fatal_alert: bool,
260    /// If we signaled end of stream.
261    pub(crate) has_sent_close_notify: bool,
262    message_fragmenter: MessageFragmenter,
263    pub(crate) sendable_tls: ChunkVecBuffer,
264    queued_key_update_message: Option<Vec<u8>>,
265    pub(crate) refresh_traffic_keys_pending: bool,
266    negotiated_version: Option<ProtocolVersion>,
267    pub(crate) tls13_key_schedule: Option<Box<KeyScheduleTrafficSend>>,
268}
269
270impl SendPath {
271    #[expect(dead_code)]
272    pub(crate) fn write_plaintext(
273        &mut self,
274        payload: OutboundPlain<'_>,
275        outgoing_tls: &mut [u8],
276    ) -> Result<usize, EncryptError> {
277        if payload.is_empty() {
278            return Ok(0);
279        }
280
281        let fragments = self
282            .message_fragmenter
283            .fragment_payload(
284                ContentType::ApplicationData,
285                ProtocolVersion::TLSv1_2,
286                payload.clone(),
287            );
288
289        for f in 0..fragments.len() {
290            match self
291                .encrypt_state
292                .pre_encrypt_action(f as u64)
293            {
294                PreEncryptAction::Nothing => {}
295                PreEncryptAction::RefreshOrClose => match self.negotiated_version {
296                    Some(ProtocolVersion::TLSv1_3) => {
297                        // driven by caller, as we don't have the `State` here
298                        self.refresh_traffic_keys_pending = true;
299                    }
300                    _ => {
301                        error!(
302                            "traffic keys exhausted, closing connection to prevent security failure"
303                        );
304                        self.send_close_notify();
305                        return Err(EncryptError::EncryptExhausted);
306                    }
307                },
308                PreEncryptAction::Refuse => {
309                    return Err(EncryptError::EncryptExhausted);
310                }
311            }
312        }
313
314        self.perhaps_write_key_update();
315
316        self.check_required_size(outgoing_tls, fragments)?;
317
318        let fragments = self
319            .message_fragmenter
320            .fragment_payload(
321                ContentType::ApplicationData,
322                ProtocolVersion::TLSv1_2,
323                payload,
324            );
325
326        Ok(self.write_fragments(outgoing_tls, fragments))
327    }
328
329    pub(crate) fn send_early_plaintext(&mut self, data: &[u8]) -> usize {
330        debug_assert!(self.encrypt_state.is_encrypting());
331
332        // Limit on `sendable_tls` should apply to encrypted data but is enforced
333        // for plaintext data instead which does not include cipher+record overhead.
334        let len = self
335            .sendable_tls
336            .apply_limit(data.len());
337        if len == 0 {
338            // Don't send empty fragments.
339            return 0;
340        }
341
342        self.send_appdata_encrypt(data[..len].into())
343    }
344
345    /// Fragment `m`, encrypt the fragments, and then queue
346    /// the encrypted fragments for sending.
347    fn send_msg_encrypt(&mut self, m: EncodedMessage<Payload<'_>>) {
348        let iter = self
349            .message_fragmenter
350            .fragment_message(&m);
351        for m in iter {
352            self.send_single_fragment(m);
353        }
354    }
355
356    /// Like send_msg_encrypt, but operate on an appdata directly.
357    fn send_appdata_encrypt(&mut self, payload: OutboundPlain<'_>) -> usize {
358        let len = payload.len();
359        let iter = self
360            .message_fragmenter
361            .fragment_payload(
362                ContentType::ApplicationData,
363                ProtocolVersion::TLSv1_2,
364                payload,
365            );
366        for m in iter {
367            self.send_single_fragment(m);
368        }
369
370        len
371    }
372
373    fn send_single_fragment(&mut self, m: EncodedMessage<OutboundPlain<'_>>) {
374        if m.typ == ContentType::Alert {
375            // Alerts are always sendable -- never quashed by a PreEncryptAction.
376            let em = self.encrypt_state.encrypt_outgoing(m);
377            self.queue_tls_message(em);
378            return;
379        }
380
381        match self
382            .encrypt_state
383            .next_pre_encrypt_action()
384        {
385            PreEncryptAction::Nothing => {}
386
387            // Close connection once we start to run out of
388            // sequence space.
389            PreEncryptAction::RefreshOrClose => {
390                match self.negotiated_version {
391                    Some(ProtocolVersion::TLSv1_3) => {
392                        // driven by caller, as we don't have the `State` here
393                        self.refresh_traffic_keys_pending = true;
394                    }
395                    _ => {
396                        error!(
397                            "traffic keys exhausted, closing connection to prevent security failure"
398                        );
399                        self.send_close_notify();
400                        return;
401                    }
402                }
403            }
404
405            // Refuse to wrap counter at all costs.  This
406            // is basically untestable unfortunately.
407            PreEncryptAction::Refuse => {
408                return;
409            }
410        };
411
412        let em = self.encrypt_state.encrypt_outgoing(m);
413        self.queue_tls_message(em);
414    }
415
416    /// Send plaintext application data, fragmenting and
417    /// encrypting it as it goes out.
418    ///
419    /// If internal buffers are too small, this function will not accept
420    /// all the data.
421    pub(crate) fn buffer_plaintext(
422        &mut self,
423        payload: OutboundPlain<'_>,
424        sendable_plaintext: &mut ChunkVecBuffer,
425    ) -> usize {
426        self.perhaps_write_key_update();
427        if !self.may_send_application_data {
428            // If we haven't completed handshaking, buffer
429            // plaintext to send once we do.
430            return sendable_plaintext.append_limited_copy(payload);
431        }
432
433        // Limit on `sendable_tls` should apply to encrypted data but is enforced
434        // for plaintext data instead which does not include cipher+record overhead.
435        let len = self
436            .sendable_tls
437            .apply_limit(payload.len());
438        if len == 0 {
439            // Don't send empty fragments.
440            return 0;
441        }
442
443        debug_assert!(self.encrypt_state.is_encrypting());
444        self.send_appdata_encrypt(payload.split_at(len).0)
445    }
446
447    pub(crate) fn send_buffered_plaintext(&mut self, plaintext: &mut ChunkVecBuffer) {
448        while let Some(buf) = plaintext.pop() {
449            self.send_appdata_encrypt(buf.as_slice().into());
450        }
451    }
452
453    fn start_outgoing_traffic(&mut self) {
454        self.may_send_application_data = true;
455        debug_assert!(self.encrypt_state.is_encrypting());
456    }
457
458    // Put m into sendable_tls for writing.
459    fn queue_tls_message(&mut self, m: EncodedMessage<OutboundOpaque>) {
460        self.perhaps_write_key_update();
461        self.sendable_tls.append(m.encode());
462    }
463
464    fn perhaps_write_key_update(&mut self) {
465        if let Some(message) = self.queued_key_update_message.take() {
466            self.sendable_tls.append(message);
467        }
468    }
469
470    /// Send a raw TLS message, fragmenting it if needed.
471    fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) {
472        if !must_encrypt {
473            let msg = &m.into();
474            let iter = self
475                .message_fragmenter
476                .fragment_message(msg);
477            for m in iter {
478                self.queue_tls_message(m.to_unencrypted_opaque());
479            }
480        } else {
481            self.send_msg_encrypt(m.into());
482        }
483    }
484
485    fn send_close_notify(&mut self) {
486        if self.has_sent_close_notify {
487            return;
488        }
489        debug!("Sending warning alert {:?}", AlertDescription::CloseNotify);
490        self.has_sent_close_notify = true;
491        self.send_alert(AlertLevel::Warning, AlertDescription::CloseNotify);
492    }
493
494    #[expect(dead_code)]
495    pub(crate) fn eager_send_close_notify(
496        &mut self,
497        outgoing_tls: &mut [u8],
498    ) -> Result<usize, EncryptError> {
499        self.send_close_notify();
500        self.check_required_size(outgoing_tls, [].into_iter())?;
501        Ok(self.write_fragments(outgoing_tls, [].into_iter()))
502    }
503
504    fn send_alert(&mut self, level: AlertLevel, desc: AlertDescription) {
505        match level {
506            AlertLevel::Fatal if self.has_sent_fatal_alert => return,
507            AlertLevel::Fatal => self.has_sent_fatal_alert = true,
508            _ => {}
509        };
510        self.send_msg(
511            Message::build_alert(level, desc),
512            self.encrypt_state.is_encrypting(),
513        );
514    }
515
516    fn check_required_size<'a>(
517        &self,
518        outgoing_tls: &[u8],
519        fragments: impl Iterator<Item = EncodedMessage<OutboundPlain<'a>>>,
520    ) -> Result<(), EncryptError> {
521        let mut required_size = self.sendable_tls.len();
522
523        for m in fragments {
524            required_size += m.encoded_len(&self.encrypt_state);
525        }
526
527        if required_size > outgoing_tls.len() {
528            return Err(EncryptError::InsufficientSize(InsufficientSizeError {
529                required_size,
530            }));
531        }
532
533        Ok(())
534    }
535
536    fn write_fragments<'a>(
537        &mut self,
538        outgoing_tls: &mut [u8],
539        fragments: impl Iterator<Item = EncodedMessage<OutboundPlain<'a>>>,
540    ) -> usize {
541        let mut written = 0;
542
543        // Any pre-existing encrypted messages in `sendable_tls` must
544        // be output before encrypting any of the `fragments`.
545        while let Some(message) = self.sendable_tls.pop() {
546            let len = message.len();
547            outgoing_tls[written..written + len].copy_from_slice(&message);
548            written += len;
549        }
550
551        for m in fragments {
552            let em = self
553                .encrypt_state
554                .encrypt_outgoing(m)
555                .encode();
556
557            let len = em.len();
558            outgoing_tls[written..written + len].copy_from_slice(&em);
559            written += len;
560        }
561
562        written
563    }
564
565    pub(crate) fn set_max_fragment_size(&mut self, new: Option<usize>) -> Result<(), Error> {
566        self.message_fragmenter
567            .set_max_fragment_size(new)
568    }
569
570    fn ensure_key_update_queued(&mut self) -> bool {
571        if self.queued_key_update_message.is_some() {
572            return false;
573        }
574        let message = EncodedMessage::<Payload<'static>>::from(Message::build_key_update_notify());
575        self.queued_key_update_message = Some(
576            self.encrypt_state
577                .encrypt_outgoing(message.borrow_outbound())
578                .encode(),
579        );
580        true
581    }
582
583    /// Trigger a `refresh_traffic_keys` if required.
584    pub(crate) fn maybe_refresh_traffic_keys(&mut self) {
585        if self.refresh_traffic_keys_pending {
586            let _ = self.refresh_traffic_keys();
587        }
588    }
589
590    pub(crate) fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
591        let ks = self.tls13_key_schedule.take();
592
593        let Some(mut ks) = ks else {
594            return Err(Error::HandshakeNotComplete);
595        };
596
597        ks.request_key_update_and_update_encrypter(self);
598        self.refresh_traffic_keys_pending = false;
599        self.tls13_key_schedule = Some(ks);
600        Ok(())
601    }
602}
603
604impl Output for SendPath {
605    fn emit(&mut self, ev: Event<'_>) {
606        match ev {
607            Event::EncryptMessage(m) => self.send_msg(m, true),
608            Event::MaybeKeyUpdateRequest => {
609                if self.ensure_key_update_queued() {
610                    if let Some(mut ks) = self.tls13_key_schedule.take() {
611                        ks.update_encrypter_for_key_update(self);
612                        self.tls13_key_schedule = Some(ks);
613                    }
614                }
615            }
616            Event::MessageEncrypter { encrypter, limit } => self
617                .encrypt_state
618                .set_message_encrypter(encrypter, limit),
619            Event::OutgoingKeySchedule(klc) => self.tls13_key_schedule = Some(klc),
620            Event::PlainMessage(m) => self.send_msg(m, false),
621            Event::ProtocolVersion(ver) => self.negotiated_version = Some(ver),
622            Event::SendAlert(level, desc) => self.send_alert(level, desc),
623            Event::StartHalfRttTraffic | Event::StartTraffic => self.start_outgoing_traffic(),
624            _ => unreachable!(),
625        }
626    }
627}
628
629impl Default for SendPath {
630    fn default() -> Self {
631        Self {
632            encrypt_state: EncryptionState::new(),
633            may_send_application_data: false,
634            has_sent_fatal_alert: false,
635            has_sent_close_notify: false,
636            message_fragmenter: MessageFragmenter::default(),
637            sendable_tls: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
638            queued_key_update_message: None,
639            refresh_traffic_keys_pending: false,
640            negotiated_version: None,
641            tls13_key_schedule: None,
642        }
643    }
644}
645
646pub(crate) struct ReceivePath {
647    side: Side,
648    pub(crate) decrypt_state: DecryptionState,
649    may_receive_application_data: bool,
650    /// If the peer has signaled end of stream.
651    pub(crate) has_received_close_notify: bool,
652    temper_counters: TemperCounters,
653    negotiated_version: Option<ProtocolVersion>,
654    pub(crate) hs_deframer: HandshakeDeframer,
655
656    /// We limit consecutive empty fragments to avoid a route for the peer to send
657    /// us significant but fruitless traffic.
658    seen_consecutive_empty_fragments: u8,
659
660    pub(crate) tls13_tickets_received: u32,
661}
662
663impl ReceivePath {
664    fn new(side: Side) -> Self {
665        Self {
666            side,
667            decrypt_state: DecryptionState::new(),
668            may_receive_application_data: false,
669            has_received_close_notify: false,
670            temper_counters: TemperCounters::default(),
671            negotiated_version: None,
672            hs_deframer: HandshakeDeframer::default(),
673            seen_consecutive_empty_fragments: 0,
674            tls13_tickets_received: 0,
675        }
676    }
677
678    /// Pull a message out of the deframer and send any messages that need to be sent as a result.
679    pub(crate) fn deframe<'b>(
680        &mut self,
681        buffer: &'b mut [u8],
682        buffer_progress: &mut BufferProgress,
683    ) -> Result<Option<Decrypted<'b>>, Error> {
684        // before processing any more of `buffer`, return any extant messages from `hs_deframer`
685        if self.hs_deframer.has_message_ready() {
686            Ok(self.take_handshake_message(buffer, buffer_progress))
687        } else {
688            self.process_more_input(buffer, buffer_progress)
689        }
690    }
691
692    fn take_handshake_message<'b>(
693        &mut self,
694        buffer: &'b [u8],
695        buffer_progress: &mut BufferProgress,
696    ) -> Option<Decrypted<'b>> {
697        self.hs_deframer
698            .iter(buffer)
699            .next()
700            .map(|(message, discard)| {
701                buffer_progress.add_discard(discard);
702                Decrypted {
703                    want_close_before_decrypt: false,
704                    plaintext: message,
705                }
706            })
707    }
708
709    fn process_more_input<'b>(
710        &mut self,
711        buffer: &'b mut [u8],
712        buffer_progress: &mut BufferProgress,
713    ) -> Result<Option<Decrypted<'b>>, Error> {
714        let version_is_tls13 = matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3));
715
716        let locator = Locator::new(buffer);
717
718        loop {
719            let mut iter = DeframerIter::new(&mut buffer[buffer_progress.processed()..]);
720
721            let (message, processed) = loop {
722                let message = match iter.next().transpose() {
723                    Ok(Some(message)) => message,
724                    Ok(None) => return Ok(None),
725                    Err(err) => return Err(err),
726                };
727
728                let allowed_plaintext = match message.typ {
729                    // CCS messages are always plaintext.
730                    ContentType::ChangeCipherSpec => true,
731                    // Alerts are allowed to be plaintext if-and-only-if:
732                    // * The negotiated protocol version is TLS 1.3. - In TLS 1.2 it is unambiguous when
733                    //   keying changes based on the CCS message. Only TLS 1.3 requires these heuristics.
734                    // * We have not yet decrypted any messages from the peer - if we have we don't
735                    //   expect any plaintext.
736                    // * The payload size is indicative of a plaintext alert message.
737                    ContentType::Alert
738                        if version_is_tls13
739                            && !self.decrypt_state.has_decrypted()
740                            && message.payload.len() <= 2 =>
741                    {
742                        true
743                    }
744                    // In other circumstances, we expect all messages to be encrypted.
745                    _ => false,
746                };
747
748                if allowed_plaintext && !self.hs_deframer.is_active() {
749                    break (
750                        Decrypted {
751                            plaintext: message.into_plain_message(),
752                            want_close_before_decrypt: false,
753                        },
754                        iter.bytes_consumed(),
755                    );
756                }
757
758                let message = match self
759                    .decrypt_state
760                    .decrypt_incoming(message)
761                {
762                    // failed decryption during trial decryption is not allowed to be
763                    // interleaved with partial handshake data.
764                    Ok(None) if self.hs_deframer.aligned().is_none() => {
765                        return Err(
766                            PeerMisbehaved::RejectedEarlyDataInterleavedWithHandshakeMessage.into(),
767                        );
768                    }
769
770                    // failed decryption during trial decryption.
771                    Ok(None) => continue,
772
773                    Ok(Some(message)) => message,
774
775                    Err(err) => return Err(err),
776                };
777
778                break (message, iter.bytes_consumed());
779            };
780
781            let Decrypted {
782                plaintext: message,
783                want_close_before_decrypt,
784            } = message;
785
786            if self.hs_deframer.aligned().is_none() && message.typ != ContentType::Handshake {
787                // "Handshake messages MUST NOT be interleaved with other record
788                // types.  That is, if a handshake message is split over two or more
789                // records, there MUST NOT be any other records between them."
790                // https://www.rfc-editor.org/rfc/rfc8446#section-5.1
791                return Err(PeerMisbehaved::MessageInterleavedWithHandshakeMessage.into());
792            }
793
794            match message.payload.len() {
795                0 => {
796                    if self.seen_consecutive_empty_fragments
797                        == ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX
798                    {
799                        return Err(PeerMisbehaved::TooManyEmptyFragments.into());
800                    }
801                    self.seen_consecutive_empty_fragments += 1;
802                }
803                _ => {
804                    self.seen_consecutive_empty_fragments = 0;
805                }
806            };
807
808            buffer_progress.add_processed(processed);
809
810            // do an end-run around the borrow checker, converting `message` (containing
811            // a borrowed slice) to an unborrowed one (containing a `Range` into the
812            // same buffer).  the reborrow happens inside the branch that returns the
813            // message.
814            //
815            // is fixed by -Zpolonius
816            // https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md#problem-case-3-conditional-control-flow-across-functions
817            let unborrowed = InboundUnborrowedMessage::unborrow(&locator, message);
818
819            if unborrowed.typ != ContentType::Handshake {
820                let message = unborrowed.reborrow(&Delocator::new(buffer));
821                buffer_progress.add_discard(processed);
822                return Ok(Some(Decrypted {
823                    plaintext: message,
824                    want_close_before_decrypt,
825                }));
826            }
827
828            let message = unborrowed.reborrow(&Delocator::new(buffer));
829            self.hs_deframer
830                .input_message(message, &locator, buffer_progress.processed());
831            self.hs_deframer.coalesce(buffer)?;
832
833            if self.hs_deframer.has_message_ready() {
834                // trial decryption finishes with the first handshake message after it started.
835                self.decrypt_state
836                    .finish_trial_decryption();
837
838                return Ok(self
839                    .take_handshake_message(buffer, buffer_progress)
840                    .map(|decrypted| Decrypted {
841                        plaintext: decrypted.plaintext,
842                        want_close_before_decrypt,
843                    }));
844            }
845        }
846    }
847
848    /// Take a TLS message `msg` and map it into an `Input`
849    ///
850    /// `Input` is the input to our state machine.
851    ///
852    /// The message is mapped into `None` if it should be dropped with no further
853    /// action.
854    ///
855    /// Otherwise the caller must present the returned `Input` to the state machine to
856    /// progress the connection.
857    pub(crate) fn receive_message<'a>(
858        &mut self,
859        msg: EncodedMessage<&'a [u8]>,
860        aligned_handshake: Option<HandshakeAlignedProof>,
861        send_path: &mut dyn Output,
862    ) -> Result<Option<Input<'a>>, Error> {
863        // Drop CCS messages during handshake in TLS1.3
864        if msg.typ == ContentType::ChangeCipherSpec && self.drop_tls13_ccs(&msg)? {
865            trace!("Dropping CCS");
866            return Ok(None);
867        }
868
869        // Now we can fully parse the message payload.
870        let message = Message::try_from(msg)?;
871
872        // For alerts, we have separate logic.
873        if let MessagePayload::Alert(alert) = &message.payload {
874            self.process_alert(alert)?;
875            return Ok(None);
876        }
877
878        // For TLS1.2, outside of the handshake, send rejection alerts for
879        // renegotiation requests.  These can occur any time.
880        if self.reject_renegotiation_request(&message, send_path)? {
881            return Ok(None);
882        }
883
884        Ok(Some(Input {
885            message,
886            aligned_handshake,
887        }))
888    }
889
890    fn drop_tls13_ccs(&mut self, msg: &EncodedMessage<&'_ [u8]>) -> Result<bool, Error> {
891        if self.may_receive_application_data
892            || !matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
893        {
894            return Ok(false);
895        }
896
897        if !msg.is_valid_ccs() {
898            // "An implementation which receives any other change_cipher_spec value or
899            //  which receives a protected change_cipher_spec record MUST abort the
900            //  handshake with an "unexpected_message" alert."
901            return Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into());
902        }
903
904        self.temper_counters
905            .received_tls13_change_cipher_spec()?;
906        Ok(true)
907    }
908
909    fn reject_renegotiation_request(
910        &mut self,
911        msg: &Message<'_>,
912        output: &mut dyn Output,
913    ) -> Result<bool, Error> {
914        if !self.may_receive_application_data
915            || matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
916        {
917            return Ok(false);
918        }
919
920        let reject_ty = match self.side {
921            Side::Client => HandshakeType::HelloRequest,
922            Side::Server => HandshakeType::ClientHello,
923        };
924
925        if msg.handshake_type() != Some(reject_ty) {
926            return Ok(false);
927        }
928        self.temper_counters
929            .received_renegotiation_request()?;
930        let desc = AlertDescription::NoRenegotiation;
931        warn!("sending warning alert {desc:?}");
932        output.emit(Event::SendAlert(AlertLevel::Warning, desc));
933        Ok(true)
934    }
935
936    fn process_alert(&mut self, alert: &AlertMessagePayload) -> Result<(), Error> {
937        // Reject unknown AlertLevels.
938        if let AlertLevel::Unknown(level) = alert.level {
939            return Err(PeerMisbehaved::IllegalAlertLevel(level, alert.description).into());
940        }
941
942        // If we get a CloseNotify, make a note to declare EOF to our
943        // caller.  But do not treat unauthenticated alerts like this.
944        if self.may_receive_application_data && alert.description == AlertDescription::CloseNotify {
945            self.has_received_close_notify = true;
946            return Ok(());
947        }
948
949        // Warnings are nonfatal for TLS1.2, but outlawed in TLS1.3
950        // (except, for no good reason, user_cancelled).
951        let err = Error::AlertReceived(alert.description);
952        if alert.level == AlertLevel::Warning {
953            self.temper_counters
954                .received_warning_alert()?;
955            if matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
956                && alert.description != AlertDescription::UserCanceled
957            {
958                return Err(PeerMisbehaved::IllegalWarningAlert(alert.description).into());
959            }
960
961            // Some implementations send pointless `user_canceled` alerts, don't log them
962            // in release mode (https://bugs.openjdk.org/browse/JDK-8323517).
963            if alert.description != AlertDescription::UserCanceled || cfg!(debug_assertions) {
964                warn!("TLS alert warning received: {alert:?}");
965            }
966
967            return Ok(());
968        }
969
970        Err(err)
971    }
972}
973
974impl Output for ReceivePath {
975    fn emit(&mut self, ev: Event<'_>) {
976        match ev {
977            Event::MessageDecrypter { decrypter, proof } => self
978                .decrypt_state
979                .set_message_decrypter(decrypter, &proof),
980            Event::MessageDecrypterWithTrialDecryption {
981                decrypter,
982                max_length,
983                proof,
984            } => self
985                .decrypt_state
986                .set_message_decrypter_with_trial_decryption(decrypter, max_length, &proof),
987            Event::ProtocolVersion(ver) => self.negotiated_version = Some(ver),
988            Event::ReceivedTicket => {
989                self.tls13_tickets_received = self
990                    .tls13_tickets_received
991                    .saturating_add(1)
992            }
993            Event::StartTraffic => self.may_receive_application_data = true,
994            _ => unreachable!(),
995        }
996    }
997}
998
999/// Describes which sort of handshake happened.
1000#[derive(Debug, PartialEq, Clone, Copy)]
1001#[non_exhaustive]
1002pub enum HandshakeKind {
1003    /// A full handshake.
1004    ///
1005    /// This is the typical TLS connection initiation process when resumption is
1006    /// not yet unavailable, and the initial `ClientHello` was accepted by the server.
1007    Full,
1008
1009    /// A full TLS1.3 handshake, with an extra round-trip for a `HelloRetryRequest`.
1010    ///
1011    /// The server can respond with a `HelloRetryRequest` if the initial `ClientHello`
1012    /// is unacceptable for several reasons, the most likely being if no supported key
1013    /// shares were offered by the client.
1014    FullWithHelloRetryRequest,
1015
1016    /// A resumed handshake.
1017    ///
1018    /// Resumed handshakes involve fewer round trips and less cryptography than
1019    /// full ones, but can only happen when the peers have previously done a full
1020    /// handshake together, and then remember data about it.
1021    Resumed,
1022
1023    /// A resumed handshake, with an extra round-trip for a `HelloRetryRequest`.
1024    ///
1025    /// The server can respond with a `HelloRetryRequest` if the initial `ClientHello`
1026    /// is unacceptable for several reasons, but this does not prevent the client
1027    /// from resuming.
1028    ResumedWithHelloRetryRequest,
1029}
1030
1031pub(crate) struct CaptureAppData<'a> {
1032    pub(crate) data: &'a mut dyn Output,
1033    /// Store a [`Locator`] initialized from the current receive buffer
1034    ///
1035    /// Allows received plaintext data to be unborrowed and stored in
1036    /// `received_plaintext` for in-place decryption.
1037    pub(crate) plaintext_locator: &'a Locator,
1038    /// Unborrowed received plaintext data
1039    ///
1040    /// Set if plaintext data was received.
1041    ///
1042    /// Plaintext data may be reborrowed using a [`Delocator`] which was
1043    /// initialized from the same slice as `plaintext_locator`.
1044    pub(crate) received_plaintext: &'a mut Option<UnborrowedPayload>,
1045}
1046
1047impl Output for CaptureAppData<'_> {
1048    fn emit(&mut self, ev: Event<'_>) {
1049        self.data.emit(ev)
1050    }
1051
1052    fn received_plaintext(&mut self, payload: Payload<'_>) {
1053        // Receive plaintext data [`Payload<'_>`].
1054        //
1055        // Since [`Context`] does not hold a lifetime to the receive buffer the
1056        // passed [`Payload`] will have it's lifetime erased by storing an index
1057        // into the receive buffer as an [`UnborrowedPayload`]. This enables the
1058        // data to be later reborrowed after it has been decrypted in-place.
1059        let previous = self
1060            .received_plaintext
1061            .replace(UnborrowedPayload::unborrow(self.plaintext_locator, payload));
1062        debug_assert!(previous.is_none(), "overwrote plaintext data");
1063    }
1064}
1065
1066pub(crate) struct SplitReceive<'a> {
1067    pub(crate) recv: &'a mut dyn Output,
1068    pub(crate) other: &'a mut dyn Output,
1069}
1070
1071impl Output for SplitReceive<'_> {
1072    fn emit(&mut self, ev: Event<'_>) {
1073        match ev.disposition() {
1074            EventDisposition::ReceivePath => self.recv.emit(ev),
1075            EventDisposition::ProtocolVersion(ver) => {
1076                self.recv
1077                    .emit(Event::ProtocolVersion(ver));
1078                self.other
1079                    .emit(Event::ProtocolVersion(ver));
1080            }
1081            EventDisposition::StartTraffic => {
1082                self.recv.emit(Event::StartTraffic);
1083                self.other.emit(Event::StartTraffic);
1084            }
1085            _ => self.other.emit(ev),
1086        }
1087    }
1088}
1089
1090pub(crate) struct JoinOutput<'a> {
1091    pub(crate) protocol: Protocol,
1092    pub(crate) outputs: &'a mut dyn Output,
1093    pub(crate) quic: &'a mut dyn Output,
1094    pub(crate) send: &'a mut dyn Output,
1095    pub(crate) side: &'a mut dyn Output,
1096}
1097
1098impl Output for JoinOutput<'_> {
1099    fn emit(&mut self, ev: Event<'_>) {
1100        match ev.disposition() {
1101            EventDisposition::ReceivePath => unreachable!(),
1102            EventDisposition::ProtocolVersion(ver) => {
1103                self.outputs
1104                    .emit(Event::ProtocolVersion(ver));
1105                self.quic
1106                    .emit(Event::ProtocolVersion(ver));
1107                self.send
1108                    .emit(Event::ProtocolVersion(ver));
1109            }
1110            EventDisposition::ConnectionOutputs => self.outputs.emit(ev),
1111            EventDisposition::Quic => self.quic.emit(ev),
1112            EventDisposition::SendPath => self.send.emit(ev),
1113            EventDisposition::MessageOutput => match self.protocol {
1114                Protocol::Tcp => self.send.emit(ev),
1115                Protocol::Quic(_) => self.quic.emit(ev),
1116            },
1117            EventDisposition::StartTraffic => self.send.emit(ev),
1118            EventDisposition::SideSpecific => self.side.emit(ev),
1119        }
1120    }
1121}
1122
1123pub(crate) struct Input<'a> {
1124    pub(crate) message: Message<'a>,
1125    pub(crate) aligned_handshake: Option<HandshakeAlignedProof>,
1126}
1127
1128impl Input<'_> {
1129    // Changing the keys must not span any fragmented handshake
1130    // messages.  Otherwise the defragmented messages will have
1131    // been protected with two different record layer protections,
1132    // which is illegal.  Not mentioned in RFC.
1133    pub(crate) fn check_aligned_handshake(&self) -> Result<HandshakeAlignedProof, Error> {
1134        self.aligned_handshake
1135            .ok_or_else(|| PeerMisbehaved::KeyEpochWithPendingFragment.into())
1136    }
1137}
1138
1139/// The route for handshake state machine to surface determinations about the connection.
1140pub(crate) trait Output {
1141    fn emit(&mut self, ev: Event<'_>);
1142
1143    fn received_plaintext(&mut self, _payload: Payload<'_>) {}
1144}
1145
1146/// The set of events output by the low-level handshake state machine.
1147pub(crate) enum Event<'a> {
1148    ApplicationProtocol(ApplicationProtocol<'a>),
1149    CipherSuite(SupportedCipherSuite),
1150    EarlyApplicationData(Payload<'a>),
1151    EarlyData(EarlyDataEvent),
1152    EarlyExporter(Box<dyn Exporter>),
1153    EchStatus(EchStatus),
1154    EncryptMessage(Message<'a>),
1155    Exporter(Box<dyn Exporter>),
1156    HandshakeKind(HandshakeKind),
1157    KeyExchangeGroup(&'static dyn SupportedKxGroup),
1158    MaybeKeyUpdateRequest,
1159    MessageDecrypter {
1160        decrypter: Box<dyn MessageDecrypter>,
1161        proof: HandshakeAlignedProof,
1162    },
1163    MessageDecrypterWithTrialDecryption {
1164        decrypter: Box<dyn MessageDecrypter>,
1165        max_length: usize,
1166        proof: HandshakeAlignedProof,
1167    },
1168    MessageEncrypter {
1169        encrypter: Box<dyn MessageEncrypter>,
1170        limit: u64,
1171    },
1172    OutgoingKeySchedule(Box<KeyScheduleTrafficSend>),
1173    PeerIdentity(Identity<'static>),
1174    PlainMessage(Message<'a>),
1175    ProtocolVersion(ProtocolVersion),
1176    QuicEarlySecret(Option<OkmBlock>),
1177    QuicHandshakeSecrets(quic::Secrets),
1178    QuicTrafficSecrets(quic::Secrets),
1179    QuicTransportParameters(Vec<u8>),
1180    ReceivedServerName(Option<DnsName<'static>>),
1181    ReceivedTicket,
1182    ResumptionData(Vec<u8>),
1183    SendAlert(AlertLevel, AlertDescription),
1184    /// Mark the connection as ready to send half-RTT traffic (server only)
1185    StartHalfRttTraffic,
1186    /// Mark the connection as ready to send and receive application data.
1187    StartTraffic,
1188}
1189
1190impl Event<'_> {
1191    pub(crate) fn disposition(&self) -> EventDisposition {
1192        match self {
1193            // message dispatch
1194            Event::EncryptMessage(_) | Event::PlainMessage(_) => EventDisposition::MessageOutput,
1195
1196            // send-specific events
1197            Event::MaybeKeyUpdateRequest
1198            | Event::MessageEncrypter { .. }
1199            | Event::OutgoingKeySchedule(_)
1200            | Event::SendAlert(..)
1201            | Event::StartHalfRttTraffic => EventDisposition::SendPath,
1202
1203            // recv-specific events
1204            Event::MessageDecrypter { .. }
1205            | Event::MessageDecrypterWithTrialDecryption { .. }
1206            | Event::ReceivedTicket => EventDisposition::ReceivePath,
1207
1208            // presentation API events
1209            Event::ApplicationProtocol(_)
1210            | Event::CipherSuite(_)
1211            | Event::EarlyExporter(_)
1212            | Event::Exporter(_)
1213            | Event::HandshakeKind(_)
1214            | Event::KeyExchangeGroup(_)
1215            | Event::PeerIdentity(_) => EventDisposition::ConnectionOutputs,
1216
1217            // quic-specific events
1218            Event::QuicEarlySecret(_)
1219            | Event::QuicHandshakeSecrets(_)
1220            | Event::QuicTrafficSecrets(_)
1221            | Event::QuicTransportParameters(_) => EventDisposition::Quic,
1222
1223            // broadcast events
1224            Event::ProtocolVersion(ver) => EventDisposition::ProtocolVersion(*ver),
1225
1226            Event::StartTraffic => EventDisposition::StartTraffic,
1227
1228            // higher levels
1229            Event::EarlyApplicationData(_)
1230            | Event::EarlyData(_)
1231            | Event::EchStatus(_)
1232            | Event::ReceivedServerName(_)
1233            | Event::ResumptionData(_) => EventDisposition::SideSpecific,
1234        }
1235    }
1236}
1237
1238/// Where a given `Event` should be routed to.
1239#[derive(Clone, Copy, Debug)]
1240pub(crate) enum EventDisposition {
1241    /// Events related to message output
1242    MessageOutput,
1243
1244    /// Events destined for `SendPath`
1245    SendPath,
1246
1247    /// Events destined for `ReceivePath`
1248    ReceivePath,
1249
1250    /// Events destined for `ConnectionOutputs`
1251    ConnectionOutputs,
1252
1253    /// Events related only to QUIC
1254    Quic,
1255
1256    /// Event broadcast into `SendPath`, `ReceivePath`, and `ConnectionOutputs`
1257    ProtocolVersion(ProtocolVersion),
1258
1259    /// Event broadcast into `SendPath` and `ReceivePath`
1260    StartTraffic,
1261
1262    /// Events which are side (client or server) specific
1263    SideSpecific,
1264}
1265
1266pub(crate) enum EarlyDataEvent {
1267    /// server: we accepted an early_data offer
1268    Accepted,
1269    /// client: declares the maximum amount of early data that can be sent
1270    Enable(usize),
1271    /// client: early data can now be sent using the record layer as normal
1272    Start,
1273    /// client: early data phase has closed after sending EndOfEarlyData
1274    Finished,
1275    /// client: the server rejected our request for early data
1276    Rejected,
1277}
1278
1279/// Lifetime-erased equivalent to [`Payload`]
1280///
1281/// Stores an index into [`Payload`] buffer enabling in-place decryption
1282/// without holding a lifetime to the receive buffer.
1283pub(crate) enum UnborrowedPayload {
1284    Unborrowed(Range<usize>),
1285    Owned(Vec<u8>),
1286}
1287
1288impl UnborrowedPayload {
1289    /// Convert [`Payload`] into [`UnborrowedPayload`] which stores a range
1290    /// into the [`Payload`] slice without borrowing such that it can be later
1291    /// reborrowed.
1292    ///
1293    /// # Panics
1294    ///
1295    /// Passed [`Locator`] must have been created from the same slice which
1296    /// contains the payload.
1297    pub(crate) fn unborrow(locator: &Locator, payload: Payload<'_>) -> Self {
1298        match payload {
1299            Payload::Borrowed(payload) => Self::Unborrowed(locator.locate(payload)),
1300            Payload::Owned(payload) => Self::Owned(payload),
1301        }
1302    }
1303
1304    /// Convert [`UnborrowedPayload`] back into [`Payload`]
1305    ///
1306    /// # Panics
1307    ///
1308    /// Passed [`Delocator`] must have been created from the same slice that
1309    /// [`UnborrowedPayload`] was originally unborrowed from.
1310    pub(crate) fn reborrow<'b>(self, delocator: &Delocator<'b>) -> Payload<'b> {
1311        match self {
1312            Self::Unborrowed(range) => Payload::Borrowed(delocator.slice_from_range(&range)),
1313            Self::Owned(payload) => Payload::Owned(payload),
1314        }
1315    }
1316}
1317
1318/// Side of the connection.
1319#[expect(clippy::exhaustive_enums)]
1320#[derive(Clone, Copy, Debug, PartialEq)]
1321pub enum Side {
1322    /// A client initiates the connection.
1323    Client,
1324    /// A server waits for a client to connect.
1325    Server,
1326}
1327
1328#[derive(Copy, Clone, Eq, PartialEq, Debug)]
1329pub(crate) enum Protocol {
1330    /// TCP-TLS, standardized in RFC5246 and RFC8446
1331    Tcp,
1332    /// QUIC, standardized in RFC9001
1333    Quic(quic::Version),
1334}
1335
1336impl Protocol {
1337    pub(crate) fn is_quic(&self) -> bool {
1338        matches!(self, Self::Quic(_))
1339    }
1340}
1341
1342/// Tracking technically-allowed protocol actions
1343/// that we limit to avoid denial-of-service vectors.
1344struct TemperCounters {
1345    allowed_warning_alerts: u8,
1346    allowed_renegotiation_requests: u8,
1347    allowed_middlebox_ccs: u8,
1348}
1349
1350impl TemperCounters {
1351    fn received_warning_alert(&mut self) -> Result<(), Error> {
1352        match self.allowed_warning_alerts {
1353            0 => Err(PeerMisbehaved::TooManyWarningAlertsReceived.into()),
1354            _ => {
1355                self.allowed_warning_alerts -= 1;
1356                Ok(())
1357            }
1358        }
1359    }
1360
1361    fn received_renegotiation_request(&mut self) -> Result<(), Error> {
1362        match self.allowed_renegotiation_requests {
1363            0 => Err(PeerMisbehaved::TooManyRenegotiationRequests.into()),
1364            _ => {
1365                self.allowed_renegotiation_requests -= 1;
1366                Ok(())
1367            }
1368        }
1369    }
1370
1371    fn received_tls13_change_cipher_spec(&mut self) -> Result<(), Error> {
1372        match self.allowed_middlebox_ccs {
1373            0 => Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into()),
1374            _ => {
1375                self.allowed_middlebox_ccs -= 1;
1376                Ok(())
1377            }
1378        }
1379    }
1380}
1381
1382impl Default for TemperCounters {
1383    fn default() -> Self {
1384        Self {
1385            // cf. BoringSSL `kMaxWarningAlerts`
1386            // <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L137-L139>
1387            allowed_warning_alerts: 4,
1388
1389            // we rebuff renegotiation requests with a `NoRenegotiation` warning alerts.
1390            // a second request after this is fatal.
1391            allowed_renegotiation_requests: 1,
1392
1393            // At most two CCS are allowed: one after each ClientHello (recall a second
1394            // ClientHello happens after a HelloRetryRequest).
1395            //
1396            // note BoringSSL allows up to 32.
1397            allowed_middlebox_ccs: 2,
1398        }
1399    }
1400}
1401
1402pub(crate) struct TrafficTemperCounters {
1403    allowed_key_update_requests: u8,
1404}
1405
1406impl TrafficTemperCounters {
1407    pub(crate) fn received_key_update_request(&mut self) -> Result<(), Error> {
1408        match self.allowed_key_update_requests {
1409            0 => Err(PeerMisbehaved::TooManyKeyUpdateRequests.into()),
1410            _ => {
1411                self.allowed_key_update_requests -= 1;
1412                Ok(())
1413            }
1414        }
1415    }
1416
1417    pub(crate) fn received_app_data(&mut self) {
1418        self.allowed_key_update_requests = Self::INITIAL_KEY_UPDATE_REQUESTS;
1419    }
1420
1421    // cf. BoringSSL `kMaxKeyUpdates`
1422    // <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls13_both.cc#L35-L38>
1423    const INITIAL_KEY_UPDATE_REQUESTS: u8 = 32;
1424}
1425
1426impl Default for TrafficTemperCounters {
1427    fn default() -> Self {
1428        Self {
1429            allowed_key_update_requests: Self::INITIAL_KEY_UPDATE_REQUESTS,
1430        }
1431    }
1432}
1433
1434pub(crate) struct HandshakeFlight<'a, const TLS13: bool> {
1435    pub(crate) transcript: &'a mut HandshakeHash,
1436    body: Vec<u8>,
1437}
1438
1439impl<'a, const TLS13: bool> HandshakeFlight<'a, TLS13> {
1440    pub(crate) fn new(transcript: &'a mut HandshakeHash) -> Self {
1441        Self {
1442            transcript,
1443            body: Vec::new(),
1444        }
1445    }
1446
1447    pub(crate) fn add(&mut self, hs: HandshakeMessagePayload<'_>) {
1448        let start_len = self.body.len();
1449        hs.encode(&mut self.body);
1450        self.transcript
1451            .add(&self.body[start_len..]);
1452    }
1453
1454    pub(crate) fn finish(self, output: &mut dyn Output) {
1455        let m = Message {
1456            version: match TLS13 {
1457                true => ProtocolVersion::TLSv1_3,
1458                false => ProtocolVersion::TLSv1_2,
1459            },
1460            payload: MessagePayload::HandshakeFlight(Payload::new(self.body)),
1461        };
1462
1463        output.emit(match TLS13 {
1464            true => Event::EncryptMessage(m),
1465            false => Event::PlainMessage(m),
1466        });
1467    }
1468}
1469
1470pub(crate) type HandshakeFlightTls12<'a> = HandshakeFlight<'a, false>;
1471pub(crate) type HandshakeFlightTls13<'a> = HandshakeFlight<'a, true>;
1472
1473/// An [`EncodedMessage<Payload<'_>>`] which does not borrow its payload, but
1474/// references a range that can later be borrowed.
1475struct InboundUnborrowedMessage {
1476    typ: ContentType,
1477    version: ProtocolVersion,
1478    bounds: Range<usize>,
1479}
1480
1481impl InboundUnborrowedMessage {
1482    fn unborrow(locator: &Locator, msg: EncodedMessage<&'_ [u8]>) -> Self {
1483        Self {
1484            typ: msg.typ,
1485            version: msg.version,
1486            bounds: locator.locate(msg.payload),
1487        }
1488    }
1489
1490    fn reborrow<'b>(self, delocator: &Delocator<'b>) -> EncodedMessage<&'b [u8]> {
1491        EncodedMessage {
1492            typ: self.typ,
1493            version: self.version,
1494            payload: delocator.slice_from_range(&self.bounds),
1495        }
1496    }
1497}
1498
1499/// cf. BoringSSL's `kMaxEmptyRecords`
1500/// <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L124-L128>
1501const ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX: u8 = 32;
1502
1503pub(crate) const DEFAULT_BUFFER_LIMIT: usize = 64 * 1024;