1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::marker::PhantomData;
4use core::ops::Range;
5use core::{fmt, mem};
6#[cfg(feature = "std")]
7use std::io::{self, Read};
8
9use super::private::SideOutput;
10use super::send::{SendOutput, SendPath};
11#[cfg(feature = "std")]
12use super::split::SendAdapter;
13use super::{Connection, SEQ_SOFT_LIMIT, SideData, StateMachine, Transport};
14use crate::common_state::{
15 ConnectionOutput, Event, Output, OutputEvent, Side, UnborrowedPayload, maybe_send_fatal_alert,
16};
17use crate::crypto::cipher::{EncodableVersion, InboundOpaque, Payload, Record, RecordDecrypter};
18use crate::enums::{ContentType, HandshakeType, ProtocolVersion};
19use crate::error::{AlertDescription, Error, PeerMisbehaved};
20use crate::msgs::{
21 AlertLevel, AlertLevelName, AlertMessagePayload, Deframed, Deframer, Delocator,
22 HandshakeAlignedProof, Locator, Message, MessagePayload,
23};
24use crate::quic::QuicOutput;
25use crate::tracing::{trace, warn};
26
27pub(crate) struct MessageIter<'a, 'm, Side: SideData, Send: SendOutput + 'a> {
28 pub(super) input: &'m mut dyn TlsInputBuffer,
29 pub(super) tls: &'a mut Vec<u8>,
30 pub(super) recv: &'a mut ReceivePath,
31 pub(super) state: &'a mut Result<Side::State, Error>,
32 pub(super) output: JoinOutput<'a, Send>,
33 pub(super) mode: MessageIterMode,
34}
35
36impl<'a, 'm, Side: SideData> MessageIter<'a, 'm, Side, SendPath> {
37 pub(crate) fn new<T: Transport>(
38 input: &'m mut dyn TlsInputBuffer,
39 tls: &'a mut Vec<u8>,
40 conn: &'a mut Connection<Side, T>,
41 mode: MessageIterMode,
42 ) -> Self {
43 Self {
44 input,
45 tls,
46 recv: &mut conn.common.recv,
47 state: &mut conn.state,
48 output: JoinOutput {
49 outputs: &mut conn.common.outputs,
50 quic: conn.transport.quic(),
51 send: &mut conn.common.send,
52 side: &mut conn.side,
53 },
54 mode,
55 }
56 }
57}
58
59#[cfg(feature = "std")]
60impl<'a, 'm, 's, Side: SideData> MessageIter<'a, 'm, Side, SendAdapter<'s>> {
61 pub(super) fn receive(
62 input: &'m mut dyn TlsInputBuffer,
63 tls: &'a mut Vec<u8>,
64 state: &'a mut Result<Side::State, Error>,
65 recv: &'a mut ReceivePath,
66 output: JoinOutput<'a, SendAdapter<'s>>,
67 mode: MessageIterMode,
68 ) -> Self {
69 Self {
70 input,
71 tls,
72 recv,
73 state,
74 output,
75 mode,
76 }
77 }
78}
79
80impl<'a, 'm, Side: SideData, Send: SendOutput + 'a> MessageIter<'a, 'm, Side, Send> {
81 pub(crate) fn next(&mut self, early_only: bool) -> Option<Result<UnborrowedPayload, Error>> {
82 let mut st = match mem::replace(self.state, Err(Error::HandshakeNotComplete)) {
83 Ok(state) => state,
84 Err(e) => {
85 *self.state = Err(e.clone());
86 return Some(Err(e));
87 }
88 };
89
90 let mut plaintext = None;
91 while st.wants_input() {
92 let buffer = self.input.slice_mut();
93 let locator = Locator::new(buffer);
94 let res = self.recv.deframe(buffer);
95
96 let mut output = CaptureAppData {
97 recv: self.recv,
98 tls: self.tls,
99 other: &mut self.output,
100 plaintext_locator: &locator,
101 received_plaintext: &mut plaintext,
102 _message_lifetime: PhantomData,
103 };
104
105 let opt_record = match res {
106 Ok(opt_record) => opt_record,
107 Err(e) => {
108 let _ = maybe_send_fatal_alert(output.other.send, &e, output.tls);
109 if let Error::DecryptError = e {
110 st.handle_decrypt_error();
111 }
112 *self.state = Err(e.clone());
113 return Some(Err(e));
114 }
115 };
116
117 let Some(record) = opt_record else {
118 break;
119 };
120
121 let Decrypted {
122 plaintext: record,
123 want_close_before_decrypt,
124 } = record;
125
126 if want_close_before_decrypt {
127 let _ = output.other.send.send_alert(
128 AlertLevel::Warning,
129 AlertDescription::CloseNotify,
130 output.tls,
131 );
132 } else if record.payload.is_empty()
133 && matches!(record.typ, ContentType::Handshake | ContentType::Alert)
134 {
135 let _ = output.other.send.send_alert(
137 AlertLevel::Fatal,
138 AlertDescription::UnexpectedMessage,
139 output.tls,
140 );
141
142 let error = Error::from(PeerMisbehaved::EmptyFragment);
143 *self.state = Err(error.clone());
144 return Some(Err(error));
145 }
146
147 let hs_aligned = output.recv.deframer.aligned();
148 let result =
149 match output
150 .recv
151 .receive_record(record, hs_aligned, output.tls, output.other.send)
152 {
153 Ok(Some(input)) => st.handle(input, &mut output),
154 Ok(None) => Ok(st),
155 Err(e) => Err(e),
156 };
157
158 match result {
159 Ok(new) => st = new,
160 Err(e) => {
161 let _ = maybe_send_fatal_alert(output.other.send, &e, output.tls);
162 *self.state = Err(e.clone());
163 return Some(Err(e));
164 }
165 }
166
167 if matches!(self.mode, MessageIterMode::All) && !st.wants_input() {
168 st = match st.handle_without_input(&mut output) {
169 Ok(st) => st,
170 Err(err) => {
171 let _ = maybe_send_fatal_alert(output.other.send, &err, output.tls);
172 *self.state = Err(err.clone());
173 return Some(Err(err));
174 }
175 };
176 }
177
178 if self.recv.has_received_close_notify {
179 self.input
184 .discard(self.recv.deframer.take_discard());
185
186 let entirety = self.input.slice_mut().len();
188 self.recv.deframer.set_discard(entirety);
189 self.input.received_close_notify();
190 break;
191 }
192
193 match plaintext.take() {
194 Some(DataKind::Traffic(payload)) if !early_only => {
195 *self.state = Ok(st);
196 return Some(Ok(payload));
197 }
198 Some(DataKind::Early(payload)) if early_only => {
199 *self.state = Ok(st);
200 return Some(Ok(payload));
201 }
202 _ => {}
203 }
204
205 if (early_only || matches!(self.mode, MessageIterMode::Handshake)) && st.is_traffic() {
207 break;
208 }
209 }
210
211 *self.state = Ok(st);
212 None
213 }
214}
215
216pub(crate) enum MessageIterMode {
217 All,
219
220 Handshake,
224}
225
226pub(crate) struct ReceivePath {
227 side: Side,
228 pub(crate) decrypt_state: DecryptionState,
229 pub(crate) may_receive_application_data: bool,
230 pub(crate) has_received_close_notify: bool,
232 temper_counters: TemperCounters,
233 pub(crate) negotiated_version: Option<ProtocolVersion>,
234 pub(crate) deframer: Deframer,
235
236 seen_consecutive_empty_fragments: u8,
239
240 pub(crate) tls13_tickets_received: u32,
241}
242
243impl ReceivePath {
244 pub(crate) fn new(side: Side) -> Self {
245 Self {
246 side,
247 decrypt_state: DecryptionState::new(),
248 may_receive_application_data: false,
249 has_received_close_notify: false,
250 temper_counters: TemperCounters::default(),
251 negotiated_version: None,
252 deframer: Deframer::default(),
253 seen_consecutive_empty_fragments: 0,
254 tls13_tickets_received: 0,
255 }
256 }
257
258 fn deframe<'b>(&mut self, buffer: &'b mut [u8]) -> Result<Option<Decrypted<'b>>, Error> {
260 let locator = Locator::new(buffer);
261
262 let mut want_close_before_decrypt = false;
263 loop {
264 if let Some(span) = self.deframer.complete_span() {
266 let plaintext = self.deframer.record(span, buffer);
267
268 self.decrypt_state
270 .finish_trial_decryption();
271
272 return Ok(Some(Decrypted {
273 plaintext,
274 want_close_before_decrypt,
275 }));
276 }
277
278 let (record, bounds) = loop {
279 match self.deframe_decrypted(buffer, &locator)? {
280 DeframeResult::Decrypted(decrypted, bounds) => break (decrypted, bounds),
281 DeframeResult::DecryptionFailed => continue,
282 DeframeResult::None => return Ok(None),
283 }
284 };
285
286 want_close_before_decrypt = record.want_close_before_decrypt;
287 let Decrypted {
288 plaintext: record,
289 want_close_before_decrypt: _,
290 } = record;
291
292 if self.deframer.aligned().is_none() && record.typ != ContentType::Handshake {
293 return Err(PeerMisbehaved::MessageInterleavedWithHandshakeMessage.into());
298 }
299
300 match (record.payload.len(), record.typ) {
301 (0, _) => {
302 if self.seen_consecutive_empty_fragments
303 == ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX
304 {
305 return Err(PeerMisbehaved::TooManyEmptyFragments.into());
306 }
307 self.seen_consecutive_empty_fragments += 1;
308 }
309 (_, ContentType::Handshake | ContentType::ApplicationData) => {
310 self.seen_consecutive_empty_fragments = 0;
311 }
312 (_, _) => {}
313 };
314
315 let unborrowed = InboundUnborrowedRecord::unborrow(&locator, record);
323
324 if unborrowed.typ != ContentType::Handshake {
325 let record = unborrowed.reborrow(&Delocator::new(buffer));
326 self.deframer.discard_processed();
327 return Ok(Some(Decrypted {
328 plaintext: record,
329 want_close_before_decrypt,
330 }));
331 }
332
333 let record = unborrowed.reborrow(&Delocator::new(buffer));
334 self.deframer
335 .input_message(record.version.version(), bounds, buffer);
336 self.deframer.coalesce(buffer)?;
337 }
338 }
339
340 fn deframe_decrypted<'b>(
341 &mut self,
342 buffer: &'b mut [u8],
343 locator: &Locator,
344 ) -> Result<DeframeResult<'b>, Error> {
345 let (record, bounds) = match self.deframer.deframe(buffer) {
346 Some(Ok(Deframed { record, bounds })) => (record, bounds),
347 Some(Err(err)) => return Err(err),
348 None => return Ok(DeframeResult::None),
349 };
350
351 let allowed_plaintext = match record.typ {
352 ContentType::ChangeCipherSpec => true,
354 ContentType::Alert
361 if matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
362 && !self.decrypt_state.has_decrypted()
363 && record.payload.len() <= 2 =>
364 {
365 true
366 }
367 _ => false,
369 };
370
371 if allowed_plaintext && !self.deframer.is_active() {
372 return Ok(DeframeResult::Decrypted(
373 Decrypted {
374 plaintext: record.into_plain_record(),
375 want_close_before_decrypt: false,
376 },
377 bounds,
378 ));
379 }
380
381 match self
382 .decrypt_state
383 .decrypt_incoming(record)?
384 {
385 Some(decrypted) => {
386 let bounds = locator.locate(decrypted.plaintext.payload);
388 Ok(DeframeResult::Decrypted(decrypted, bounds))
389 }
390
391 None if self.deframer.aligned().is_none() => {
394 Err(PeerMisbehaved::RejectedEarlyDataInterleavedWithHandshakeMessage.into())
395 }
396
397 None => Ok(DeframeResult::DecryptionFailed),
399 }
400 }
401
402 pub(crate) fn receive_record<'a>(
412 &mut self,
413 record: Record<&'a [u8]>,
414 aligned_handshake: Option<HandshakeAlignedProof>,
415 tls: &mut Vec<u8>,
416 send: &mut dyn SendOutput,
417 ) -> Result<Option<Input<'a>>, Error> {
418 if record.typ == ContentType::ChangeCipherSpec && self.drop_tls13_ccs(&record)? {
420 trace!("Dropping CCS");
421 return Ok(None);
422 }
423
424 let message = Message::try_from(record)?;
426
427 if let MessagePayload::Alert(alert) = &message.payload {
429 self.process_alert(alert)?;
430 return Ok(None);
431 }
432
433 if self.reject_renegotiation_request(&message, tls, send)? {
436 return Ok(None);
437 }
438
439 Ok(Some(Input {
440 message,
441 aligned_handshake,
442 }))
443 }
444
445 fn drop_tls13_ccs(&mut self, record: &Record<&'_ [u8]>) -> Result<bool, Error> {
446 if self.may_receive_application_data
447 || !matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
448 {
449 return Ok(false);
450 }
451
452 if !record.is_valid_ccs() {
453 return Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into());
457 }
458
459 self.temper_counters
460 .received_tls13_change_cipher_spec()?;
461 Ok(true)
462 }
463
464 fn reject_renegotiation_request(
465 &mut self,
466 msg: &Message<'_>,
467 tls: &mut Vec<u8>,
468 send: &mut dyn SendOutput,
469 ) -> Result<bool, Error> {
470 if !self.may_receive_application_data
471 || matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
472 {
473 return Ok(false);
474 }
475
476 let reject_ty = match self.side {
477 Side::Client => HandshakeType::HelloRequest,
478 Side::Server => HandshakeType::ClientHello,
479 };
480
481 if msg.handshake_type() != Some(reject_ty) {
482 return Ok(false);
483 }
484 self.temper_counters
485 .received_renegotiation_request()?;
486 let desc = AlertDescription::NoRenegotiation;
487 warn!("sending warning alert {desc:?}");
488 send.send_alert(AlertLevel::Warning, desc, tls)?;
489 Ok(true)
490 }
491
492 fn process_alert(&mut self, alert: &AlertMessagePayload) -> Result<(), Error> {
493 if AlertLevelName::try_from(alert.level).is_err() {
495 return Err(PeerMisbehaved::IllegalAlertLevel(alert.level.0, alert.description).into());
496 }
497
498 if self.may_receive_application_data && alert.description == AlertDescription::CloseNotify {
501 self.has_received_close_notify = true;
502 return Ok(());
503 }
504
505 let err = Error::AlertReceived(alert.description);
508 if alert.level == AlertLevel::Warning {
509 self.temper_counters
510 .received_warning_alert()?;
511 if matches!(self.negotiated_version, Some(ProtocolVersion::TLSv1_3))
512 && alert.description != AlertDescription::UserCanceled
513 {
514 return Err(PeerMisbehaved::IllegalWarningAlert(alert.description).into());
515 }
516
517 if alert.description != AlertDescription::UserCanceled || cfg!(debug_assertions) {
520 warn!("TLS alert warning received: {alert:?}");
521 }
522
523 return Ok(());
524 }
525
526 Err(err)
527 }
528}
529
530enum DeframeResult<'b> {
531 Decrypted(Decrypted<'b>, Range<usize>),
532 DecryptionFailed,
533 None,
534}
535
536pub(crate) struct DecryptionState {
538 record_decrypter: Option<Box<dyn RecordDecrypter>>,
539 read_seq: u64,
540 has_decrypted: bool,
541
542 trial_decryption_len: Option<usize>,
546}
547
548impl DecryptionState {
549 pub(crate) fn new() -> Self {
551 Self {
552 record_decrypter: None,
553 read_seq: 0,
554 has_decrypted: false,
555 trial_decryption_len: None,
556 }
557 }
558
559 pub(crate) fn decrypt_incoming<'a>(
565 &mut self,
566 encr: Record<InboundOpaque<'a>>,
567 ) -> Result<Option<Decrypted<'a>>, Error> {
568 let Some(decrypter) = &mut self.record_decrypter else {
569 return Ok(Some(Decrypted {
570 want_close_before_decrypt: false,
571 plaintext: encr.into_plain_record(),
572 }));
573 };
574
575 let want_close_before_decrypt = self.read_seq == SEQ_SOFT_LIMIT;
584
585 let encrypted_len = encr.payload.len();
586 match decrypter.decrypt(encr, self.read_seq) {
587 Ok(plaintext) => {
588 self.read_seq += 1;
589 if !self.has_decrypted {
590 self.has_decrypted = true;
591 }
592 Ok(Some(Decrypted {
593 want_close_before_decrypt,
594 plaintext,
595 }))
596 }
597 Err(Error::DecryptError) if self.doing_trial_decryption(encrypted_len) => {
598 trace!("Dropping undecryptable record after aborted early_data");
599 Ok(None)
600 }
601 Err(err) => Err(err),
602 }
603 }
604
605 pub(crate) fn set_record_decrypter(
608 &mut self,
609 cipher: Box<dyn RecordDecrypter>,
610 _proof: &HandshakeAlignedProof,
611 ) {
612 self.record_decrypter = Some(cipher);
613 self.read_seq = 0;
614 self.trial_decryption_len = None;
615 }
616
617 pub(crate) fn set_record_decrypter_with_trial_decryption(
621 &mut self,
622 cipher: Box<dyn RecordDecrypter>,
623 max_length: usize,
624 _proof: &HandshakeAlignedProof,
625 ) {
626 self.record_decrypter = Some(cipher);
627 self.read_seq = 0;
628 self.trial_decryption_len = Some(max_length);
629 }
630
631 pub(crate) fn finish_trial_decryption(&mut self) {
632 self.trial_decryption_len = None;
633 }
634
635 pub(crate) fn has_decrypted(&self) -> bool {
638 self.has_decrypted
639 }
640
641 pub(crate) fn read_seq(&self) -> u64 {
642 self.read_seq
643 }
644
645 fn doing_trial_decryption(&mut self, requested: usize) -> bool {
646 match self
647 .trial_decryption_len
648 .and_then(|value| value.checked_sub(requested))
649 {
650 Some(remaining) => {
651 self.trial_decryption_len = Some(remaining);
652 true
653 }
654 _ => false,
655 }
656 }
657}
658
659pub(crate) struct Decrypted<'a> {
661 pub(crate) want_close_before_decrypt: bool,
663 pub(crate) plaintext: Record<&'a [u8]>,
665}
666
667struct CaptureAppData<'a, 'j, 'm, Send: SendOutput + 'a> {
668 recv: &'a mut ReceivePath,
669 other: &'a mut JoinOutput<'j, Send>,
670 tls: &'a mut Vec<u8>,
671 plaintext_locator: &'a Locator,
676 received_plaintext: &'a mut Option<DataKind<UnborrowedPayload>>,
683 _message_lifetime: PhantomData<&'m ()>,
684}
685
686impl<'a, 'm, Send: SendOutput + 'a> Output<'m> for CaptureAppData<'a, '_, 'm, Send> {
687 fn emit(&mut self, ev: Event) {
688 self.other.side.emit(ev)
689 }
690
691 fn output(&mut self, ev: OutputEvent<'_>) {
692 if let OutputEvent::ProtocolVersion(ver) = ev {
693 self.recv.negotiated_version = Some(ver);
694 self.other.send.negotiated_version(ver);
695 }
696 self.other.outputs.handle(ev);
697 }
698
699 fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) -> Result<(), Error> {
700 match self.other.quic.as_deref_mut() {
701 Some(quic) => {
702 quic.send_msg(m, must_encrypt);
703 Ok(())
704 }
705 None => self
706 .other
707 .send
708 .send_msg(m, must_encrypt, self.tls),
709 }
710 }
711
712 fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
713 match &mut self.other.quic {
714 Some(quic) => Some(*quic),
715 None => None,
716 }
717 }
718
719 fn received_plaintext(&mut self, payload: DataKind<Payload<'m>>) {
720 let previous = self
727 .received_plaintext
728 .replace(match payload {
729 DataKind::Early(p) => {
730 DataKind::Early(UnborrowedPayload::unborrow(self.plaintext_locator, p))
731 }
732 DataKind::Traffic(p) => {
733 DataKind::Traffic(UnborrowedPayload::unborrow(self.plaintext_locator, p))
734 }
735 });
736 debug_assert!(previous.is_none(), "overwrote plaintext data");
737 }
738
739 fn start_traffic(&mut self) {
740 self.recv.may_receive_application_data = true;
741 self.other.send.start_traffic();
742 }
743
744 fn receive(&mut self) -> &mut ReceivePath {
745 self.recv
746 }
747
748 fn send(&mut self) -> &mut dyn SendOutput {
749 self.other.send
750 }
751}
752
753pub(crate) enum DataKind<T> {
754 Early(T),
755 Traffic(T),
756}
757
758pub(super) struct JoinOutput<'a, Send: SendOutput + 'a> {
759 pub(super) outputs: &'a mut dyn ConnectionOutput,
760 pub(super) quic: Option<&'a mut dyn QuicOutput>,
761 pub(super) send: &'a mut Send,
762 pub(super) side: &'a mut dyn SideOutput,
763}
764
765struct TemperCounters {
768 allowed_warning_alerts: u8,
769 allowed_renegotiation_requests: u8,
770 allowed_middlebox_ccs: u8,
771}
772
773impl TemperCounters {
774 fn received_warning_alert(&mut self) -> Result<(), Error> {
775 match self.allowed_warning_alerts {
776 0 => Err(PeerMisbehaved::TooManyWarningAlertsReceived.into()),
777 _ => {
778 self.allowed_warning_alerts -= 1;
779 Ok(())
780 }
781 }
782 }
783
784 fn received_renegotiation_request(&mut self) -> Result<(), Error> {
785 match self.allowed_renegotiation_requests {
786 0 => Err(PeerMisbehaved::TooManyRenegotiationRequests.into()),
787 _ => {
788 self.allowed_renegotiation_requests -= 1;
789 Ok(())
790 }
791 }
792 }
793
794 fn received_tls13_change_cipher_spec(&mut self) -> Result<(), Error> {
795 match self.allowed_middlebox_ccs {
796 0 => Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into()),
797 _ => {
798 self.allowed_middlebox_ccs -= 1;
799 Ok(())
800 }
801 }
802 }
803}
804
805impl Default for TemperCounters {
806 fn default() -> Self {
807 Self {
808 allowed_warning_alerts: 4,
811
812 allowed_renegotiation_requests: 1,
815
816 allowed_middlebox_ccs: 2,
821 }
822 }
823}
824
825pub(crate) struct TrafficTemperCounters {
826 allowed_consecutive_handshake_messages: u8,
827}
828
829impl TrafficTemperCounters {
830 pub(crate) fn received_handshake_message(&mut self) -> Result<(), Error> {
831 match self.allowed_consecutive_handshake_messages {
832 0 => Err(PeerMisbehaved::TooManyConsecutiveHandshakeMessagesAfterHandshake.into()),
833 _ => {
834 self.allowed_consecutive_handshake_messages -= 1;
835 Ok(())
836 }
837 }
838 }
839
840 pub(crate) fn received_app_data(&mut self) {
841 self.allowed_consecutive_handshake_messages = Self::MAX_CONSECUTIVE_HANDSHAKE_MESSAGES;
842 }
843
844 const MAX_CONSECUTIVE_HANDSHAKE_MESSAGES: u8 = 32;
847}
848
849impl Default for TrafficTemperCounters {
850 fn default() -> Self {
851 Self {
852 allowed_consecutive_handshake_messages: Self::MAX_CONSECUTIVE_HANDSHAKE_MESSAGES,
853 }
854 }
855}
856
857pub(crate) struct Input<'a> {
858 pub(crate) message: Message<'a>,
859 pub(crate) aligned_handshake: Option<HandshakeAlignedProof>,
860}
861
862impl Input<'_> {
863 pub(crate) fn check_aligned_handshake(&self) -> Result<HandshakeAlignedProof, Error> {
868 self.aligned_handshake
869 .ok_or_else(|| PeerMisbehaved::KeyEpochWithPendingFragment.into())
870 }
871}
872
873struct InboundUnborrowedRecord {
876 typ: ContentType,
877 version: EncodableVersion,
878 bounds: Range<usize>,
879}
880
881impl InboundUnborrowedRecord {
882 fn unborrow(locator: &Locator, record: Record<&'_ [u8]>) -> Self {
883 Self {
884 typ: record.typ,
885 version: record.version,
886 bounds: locator.locate(record.payload),
887 }
888 }
889
890 fn reborrow<'b>(self, delocator: &Delocator<'b>) -> Record<&'b [u8]> {
891 Record {
892 typ: self.typ,
893 version: self.version,
894 payload: delocator.slice_from_range(&self.bounds),
895 }
896 }
897}
898
899#[derive(Default)]
901pub struct VecInput {
902 buf: Vec<u8>,
906
907 used: usize,
909
910 has_seen_eof: bool,
912
913 received_close_notify: bool,
915}
916
917impl VecInput {
918 pub(crate) fn discard(&mut self, taken: usize) {
920 if taken < self.used {
921 self.buf
935 .copy_within(taken..self.used, 0);
936 self.used -= taken;
937 } else if taken >= self.used {
938 self.used = 0;
939 }
940 }
941
942 pub(crate) fn filled_mut(&mut self) -> &mut [u8] {
943 &mut self.buf[..self.used]
944 }
945
946 #[cfg(feature = "std")]
952 pub fn read(&mut self, rd: &mut dyn Read) -> io::Result<usize> {
953 if self.received_close_notify {
954 return Ok(0);
955 } else if let Err(err) = self.prepare_read() {
956 return Err(io::Error::new(io::ErrorKind::InvalidData, err));
957 }
958
959 let new_bytes = rd.read(&mut self.buf[self.used..])?;
964 if new_bytes == 0 {
965 self.has_seen_eof = true;
966 }
967
968 self.used += new_bytes;
969 Ok(new_bytes)
970 }
971
972 #[cfg(feature = "std")]
974 fn prepare_read(&mut self) -> Result<(), &'static str> {
975 const MAX_HANDSHAKE_SIZE: usize = 0xffff;
979
980 const READ_SIZE: usize = 4096;
981
982 if self.used >= MAX_HANDSHAKE_SIZE {
988 return Err("message buffer full");
989 }
990
991 let need_capacity = Ord::min(MAX_HANDSHAKE_SIZE, self.used + READ_SIZE);
997 if need_capacity > self.buf.len() {
998 self.buf.resize(need_capacity, 0);
999 } else if self.used == 0 || self.buf.len() > MAX_HANDSHAKE_SIZE {
1000 self.buf.resize(need_capacity, 0);
1001 self.buf.shrink_to(need_capacity);
1002 }
1003
1004 Ok(())
1005 }
1006}
1007
1008impl TlsInputBuffer for VecInput {
1009 fn slice_mut(&mut self) -> &mut [u8] {
1010 self.filled_mut()
1011 }
1012
1013 fn discard(&mut self, num_bytes: usize) {
1014 self.discard(num_bytes)
1015 }
1016
1017 fn received_close_notify(&mut self) {
1018 self.received_close_notify = true;
1019 }
1020
1021 fn has_seen_eof(&self) -> bool {
1022 self.has_seen_eof
1023 }
1024}
1025
1026impl fmt::Debug for VecInput {
1027 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1028 let Self {
1029 buf,
1030 used,
1031 has_seen_eof,
1032 received_close_notify,
1033 } = self;
1034 f.debug_struct("VecInput")
1035 .field("buf_len", &buf.len())
1036 .field("used", used)
1037 .field("has_seen_eof", has_seen_eof)
1038 .field("received_close_notify", received_close_notify)
1039 .finish_non_exhaustive()
1040 }
1041}
1042
1043pub struct SliceInput<'a> {
1045 buf: &'a mut [u8],
1047 discard: usize,
1049 has_seen_eof: bool,
1051 received_close_notify: bool,
1053}
1054
1055impl<'a> SliceInput<'a> {
1056 pub fn new(buf: &'a mut [u8]) -> Self {
1058 Self {
1059 buf,
1060 discard: 0,
1061 has_seen_eof: false,
1062 received_close_notify: false,
1063 }
1064 }
1065
1066 pub fn into_used(self) -> usize {
1068 self.discard
1069 }
1070}
1071
1072impl TlsInputBuffer for SliceInput<'_> {
1073 fn slice_mut(&mut self) -> &mut [u8] {
1074 &mut self.buf[self.discard..]
1075 }
1076
1077 fn discard(&mut self, num_bytes: usize) {
1078 self.discard += num_bytes;
1079 }
1080
1081 fn received_close_notify(&mut self) {
1082 self.received_close_notify = true;
1083 }
1084
1085 fn has_seen_eof(&self) -> bool {
1086 self.has_seen_eof
1087 }
1088}
1089
1090impl fmt::Debug for SliceInput<'_> {
1091 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1092 let Self {
1093 buf,
1094 discard,
1095 has_seen_eof,
1096 received_close_notify,
1097 } = self;
1098 f.debug_struct("SliceInput")
1099 .field("buf_len", &buf.len())
1100 .field("discard", discard)
1101 .field("has_seen_eof", has_seen_eof)
1102 .field("received_close_notify", received_close_notify)
1103 .finish_non_exhaustive()
1104 }
1105}
1106
1107pub trait TlsInputBuffer {
1109 fn slice_mut(&mut self) -> &mut [u8];
1119
1120 fn discard(&mut self, num_bytes: usize);
1133
1134 fn received_close_notify(&mut self);
1138
1139 fn has_seen_eof(&self) -> bool;
1143}
1144
1145const ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX: u8 = 32;
1148
1149#[cfg(test)]
1150mod tests {
1151 use alloc::format;
1152
1153 use super::*;
1154
1155 #[test]
1156 fn test_has_decrypted() {
1157 struct PassThroughDecrypter;
1158 impl RecordDecrypter for PassThroughDecrypter {
1159 fn decrypt<'a>(
1160 &mut self,
1161 record: Record<InboundOpaque<'a>>,
1162 _: u64,
1163 ) -> Result<Record<&'a [u8]>, Error> {
1164 Ok(record.into_plain_record())
1165 }
1166 }
1167
1168 let mut record_layer = DecryptionState::new();
1170 assert!(record_layer.record_decrypter.is_none());
1171 assert_eq!(record_layer.read_seq, 0);
1172 assert!(!record_layer.has_decrypted());
1173
1174 let deframer = Deframer::default();
1177 record_layer
1178 .set_record_decrypter(Box::new(PassThroughDecrypter), &deframer.aligned().unwrap());
1179 assert!(record_layer.record_decrypter.is_some());
1180 assert_eq!(record_layer.read_seq, 0);
1181 assert!(!record_layer.has_decrypted());
1182
1183 record_layer
1186 .decrypt_incoming(Record::new(
1187 ContentType::Handshake,
1188 EncodableVersion::Legacy(ProtocolVersion::TLSv1_2),
1189 InboundOpaque(&mut [0xC0, 0xFF, 0xEE]),
1190 ))
1191 .unwrap();
1192 assert_eq!(record_layer.read_seq, 1);
1193 assert!(record_layer.has_decrypted());
1194
1195 record_layer
1198 .set_record_decrypter(Box::new(PassThroughDecrypter), &deframer.aligned().unwrap());
1199 assert_eq!(record_layer.read_seq, 0);
1200 assert!(record_layer.has_decrypted());
1201 }
1202
1203 #[test]
1204 fn debug_of_input_types() {
1205 let mut buffer = [b'a'; 32];
1206 let mut slice = SliceInput::new(&mut buffer);
1207 slice.discard(2);
1208 assert_eq!(
1209 format!("{slice:?}"),
1210 "SliceInput { buf_len: 32, discard: 2, has_seen_eof: false, received_close_notify: false, .. }"
1211 );
1212
1213 let mut vec = VecInput::default();
1214 vec.prepare_read().unwrap();
1215 assert_eq!(
1216 format!("{vec:?}"),
1217 "VecInput { buf_len: 4096, used: 0, has_seen_eof: false, received_close_notify: false, .. }"
1218 );
1219 }
1220}