rustls/msgs/message/
inbound.rs1use core::ops::{Deref, DerefMut, Range};
2
3use crate::enums::{ContentType, ProtocolVersion};
4use crate::error::{Error, PeerMisbehaved};
5use crate::msgs::fragmenter::MAX_FRAGMENT_LEN;
6
7pub struct InboundOpaqueMessage<'a> {
12 pub typ: ContentType,
13 pub version: ProtocolVersion,
14 pub payload: BorrowedPayload<'a>,
15}
16
17impl<'a> InboundOpaqueMessage<'a> {
18 pub fn new(typ: ContentType, version: ProtocolVersion, payload: &'a mut [u8]) -> Self {
22 Self {
23 typ,
24 version,
25 payload: BorrowedPayload(payload),
26 }
27 }
28
29 pub fn into_plain_message(self) -> InboundPlainMessage<'a> {
34 InboundPlainMessage {
35 typ: self.typ,
36 version: self.version,
37 payload: self.payload.into_inner(),
38 }
39 }
40
41 pub fn into_plain_message_range(self, range: Range<usize>) -> InboundPlainMessage<'a> {
49 InboundPlainMessage {
50 typ: self.typ,
51 version: self.version,
52 payload: &self.payload.into_inner()[range],
53 }
54 }
55
56 pub fn into_tls13_unpadded_message(mut self) -> Result<InboundPlainMessage<'a>, Error> {
62 let payload = &mut self.payload;
63
64 if payload.len() > MAX_FRAGMENT_LEN + 1 {
65 return Err(Error::PeerSentOversizedRecord);
66 }
67
68 self.typ = unpad_tls13_payload(payload);
69 if self.typ == ContentType::Unknown(0) {
70 return Err(PeerMisbehaved::IllegalTlsInnerPlaintext.into());
71 }
72
73 if self.typ == ContentType::ChangeCipherSpec {
78 return Err(PeerMisbehaved::IllegalMiddleboxChangeCipherSpec.into());
79 }
80
81 if payload.len() > MAX_FRAGMENT_LEN {
82 return Err(Error::PeerSentOversizedRecord);
83 }
84
85 self.version = ProtocolVersion::TLSv1_3;
86 Ok(self.into_plain_message())
87 }
88}
89
90pub struct BorrowedPayload<'a>(&'a mut [u8]);
91
92impl Deref for BorrowedPayload<'_> {
93 type Target = [u8];
94
95 fn deref(&self) -> &Self::Target {
96 self.0
97 }
98}
99
100impl DerefMut for BorrowedPayload<'_> {
101 fn deref_mut(&mut self) -> &mut Self::Target {
102 self.0
103 }
104}
105
106impl<'a> BorrowedPayload<'a> {
107 pub fn truncate(&mut self, len: usize) {
108 if len >= self.len() {
109 return;
110 }
111
112 self.0 = core::mem::take(&mut self.0)
113 .split_at_mut(len)
114 .0;
115 }
116
117 pub(crate) fn into_inner(self) -> &'a mut [u8] {
118 self.0
119 }
120
121 pub(crate) fn pop(&mut self) -> Option<u8> {
122 if self.is_empty() {
123 return None;
124 }
125
126 let len = self.len();
127 let last = self[len - 1];
128 self.truncate(len - 1);
129 Some(last)
130 }
131}
132
133#[derive(Debug)]
138pub struct InboundPlainMessage<'a> {
139 pub typ: ContentType,
140 pub version: ProtocolVersion,
141 pub payload: &'a [u8],
142}
143
144impl InboundPlainMessage<'_> {
145 pub(crate) fn is_valid_ccs(&self) -> bool {
151 self.typ == ContentType::ChangeCipherSpec && self.payload == [0x01]
152 }
153}
154
155fn unpad_tls13_payload(p: &mut BorrowedPayload<'_>) -> ContentType {
163 loop {
164 match p.pop() {
165 Some(0) => {}
166 Some(content_type) => return ContentType::from(content_type),
167 None => return ContentType::Unknown(0),
168 }
169 }
170}