1use crate::enums::ProtocolVersion;
2use crate::enums::{AlertDescription, ContentType, HandshakeType};
3use crate::error::{Error, InvalidMessage};
4use crate::msgs::alert::AlertMessagePayload;
5use crate::msgs::base::Payload;
6use crate::msgs::ccs::ChangeCipherSpecPayload;
7use crate::msgs::codec::{Codec, Reader};
8use crate::msgs::enums::AlertLevel;
9use crate::msgs::handshake::HandshakeMessagePayload;
10
11#[derive(Debug)]
12pub enum MessagePayload {
13 Alert(AlertMessagePayload),
14 Handshake {
15 parsed: HandshakeMessagePayload,
16 encoded: Payload,
17 },
18 ChangeCipherSpec(ChangeCipherSpecPayload),
19 ApplicationData(Payload),
20}
21
22impl MessagePayload {
23 pub fn encode(&self, bytes: &mut Vec<u8>) {
24 match self {
25 Self::Alert(x) => x.encode(bytes),
26 Self::Handshake { encoded, .. } => bytes.extend(&encoded.0),
27 Self::ChangeCipherSpec(x) => x.encode(bytes),
28 Self::ApplicationData(x) => x.encode(bytes),
29 }
30 }
31
32 pub fn handshake(parsed: HandshakeMessagePayload) -> Self {
33 Self::Handshake {
34 encoded: Payload::new(parsed.get_encoding()),
35 parsed,
36 }
37 }
38
39 pub fn new(
40 typ: ContentType,
41 vers: ProtocolVersion,
42 payload: Payload,
43 ) -> Result<Self, InvalidMessage> {
44 let mut r = Reader::init(&payload.0);
45 match typ {
46 ContentType::ApplicationData => Ok(Self::ApplicationData(payload)),
47 ContentType::Alert => AlertMessagePayload::read(&mut r).map(MessagePayload::Alert),
48 ContentType::Handshake => {
49 HandshakeMessagePayload::read_version(&mut r, vers).map(|parsed| Self::Handshake {
50 parsed,
51 encoded: payload,
52 })
53 }
54 ContentType::ChangeCipherSpec => {
55 ChangeCipherSpecPayload::read(&mut r).map(MessagePayload::ChangeCipherSpec)
56 }
57 _ => Err(InvalidMessage::InvalidContentType),
58 }
59 }
60
61 pub fn content_type(&self) -> ContentType {
62 match self {
63 Self::Alert(_) => ContentType::Alert,
64 Self::Handshake { .. } => ContentType::Handshake,
65 Self::ChangeCipherSpec(_) => ContentType::ChangeCipherSpec,
66 Self::ApplicationData(_) => ContentType::ApplicationData,
67 }
68 }
69}
70
71#[derive(Clone, Debug)]
77pub struct OpaqueMessage {
78 pub typ: ContentType,
79 pub version: ProtocolVersion,
80 pub payload: Payload,
81}
82
83impl OpaqueMessage {
84 pub fn read(r: &mut Reader) -> Result<Self, MessageError> {
87 let typ = ContentType::read(r).map_err(|_| MessageError::TooShortForHeader)?;
88 if let ContentType::Unknown(_) = typ {
90 return Err(MessageError::InvalidContentType);
91 }
92
93 let version = ProtocolVersion::read(r).map_err(|_| MessageError::TooShortForHeader)?;
94 match version {
96 ProtocolVersion::Unknown(ref v) if (v & 0xff00) != 0x0300 => {
97 return Err(MessageError::UnknownProtocolVersion);
98 }
99 _ => {}
100 };
101
102 let len = u16::read(r).map_err(|_| MessageError::TooShortForHeader)?;
103
104 if typ != ContentType::ApplicationData && len == 0 {
108 return Err(MessageError::InvalidEmptyPayload);
109 }
110
111 if len >= Self::MAX_PAYLOAD {
113 return Err(MessageError::MessageTooLarge);
114 }
115
116 let mut sub = r
117 .sub(len as usize)
118 .map_err(|_| MessageError::TooShortForLength)?;
119 let payload = Payload::read(&mut sub);
120
121 Ok(Self {
122 typ,
123 version,
124 payload,
125 })
126 }
127
128 pub fn encode(self) -> Vec<u8> {
129 let mut buf = Vec::new();
130 self.typ.encode(&mut buf);
131 self.version.encode(&mut buf);
132 (self.payload.0.len() as u16).encode(&mut buf);
133 self.payload.encode(&mut buf);
134 buf
135 }
136
137 pub fn into_plain_message(self) -> PlainMessage {
142 PlainMessage {
143 version: self.version,
144 typ: self.typ,
145 payload: self.payload,
146 }
147 }
148
149 const MAX_PAYLOAD: u16 = 16384 + 2048;
153
154 const HEADER_SIZE: u16 = 1 + 2 + 2;
156
157 pub const MAX_WIRE_SIZE: usize = (Self::MAX_PAYLOAD + Self::HEADER_SIZE) as usize;
159}
160
161impl From<Message> for PlainMessage {
162 fn from(msg: Message) -> Self {
163 let typ = msg.payload.content_type();
164 let payload = match msg.payload {
165 MessagePayload::ApplicationData(payload) => payload,
166 _ => {
167 let mut buf = Vec::new();
168 msg.payload.encode(&mut buf);
169 Payload(buf)
170 }
171 };
172
173 Self {
174 typ,
175 version: msg.version,
176 payload,
177 }
178 }
179}
180
181#[derive(Clone, Debug)]
186pub struct PlainMessage {
187 pub typ: ContentType,
188 pub version: ProtocolVersion,
189 pub payload: Payload,
190}
191
192impl PlainMessage {
193 pub fn into_unencrypted_opaque(self) -> OpaqueMessage {
194 OpaqueMessage {
195 version: self.version,
196 typ: self.typ,
197 payload: self.payload,
198 }
199 }
200
201 pub fn borrow(&self) -> BorrowedPlainMessage<'_> {
202 BorrowedPlainMessage {
203 version: self.version,
204 typ: self.typ,
205 payload: &self.payload.0,
206 }
207 }
208}
209
210#[derive(Debug)]
212pub struct Message {
213 pub version: ProtocolVersion,
214 pub payload: MessagePayload,
215}
216
217impl Message {
218 pub fn is_handshake_type(&self, hstyp: HandshakeType) -> bool {
219 if let MessagePayload::Handshake { parsed, .. } = &self.payload {
221 parsed.typ == hstyp
222 } else {
223 false
224 }
225 }
226
227 pub fn build_alert(level: AlertLevel, desc: AlertDescription) -> Self {
228 Self {
229 version: ProtocolVersion::TLSv1_2,
230 payload: MessagePayload::Alert(AlertMessagePayload {
231 level,
232 description: desc,
233 }),
234 }
235 }
236
237 pub fn build_key_update_notify() -> Self {
238 Self {
239 version: ProtocolVersion::TLSv1_3,
240 payload: MessagePayload::handshake(HandshakeMessagePayload::build_key_update_notify()),
241 }
242 }
243}
244
245impl TryFrom<PlainMessage> for Message {
250 type Error = Error;
251
252 fn try_from(plain: PlainMessage) -> Result<Self, Self::Error> {
253 Ok(Self {
254 version: plain.version,
255 payload: MessagePayload::new(plain.typ, plain.version, plain.payload)?,
256 })
257 }
258}
259
260pub struct BorrowedPlainMessage<'a> {
269 pub typ: ContentType,
270 pub version: ProtocolVersion,
271 pub payload: &'a [u8],
272}
273
274impl<'a> BorrowedPlainMessage<'a> {
275 pub fn to_unencrypted_opaque(&self) -> OpaqueMessage {
276 OpaqueMessage {
277 version: self.version,
278 typ: self.typ,
279 payload: Payload(self.payload.to_vec()),
280 }
281 }
282}
283
284#[derive(Debug)]
285pub enum MessageError {
286 TooShortForHeader,
287 TooShortForLength,
288 InvalidEmptyPayload,
289 MessageTooLarge,
290 InvalidContentType,
291 UnknownProtocolVersion,
292}