1use crate::msgs::alert::AlertMessagePayload;
2use crate::msgs::base::Payload;
3use crate::msgs::ccs::ChangeCipherSpecPayload;
4use crate::msgs::codec::{Codec, Reader};
5use crate::msgs::enums::HandshakeType;
6use crate::msgs::enums::{AlertDescription, AlertLevel};
7use crate::msgs::enums::{ContentType, ProtocolVersion};
8use crate::msgs::handshake::HandshakeMessagePayload;
9
10use std::mem;
11
12#[derive(Debug)]
13pub enum MessagePayload {
14 Alert(AlertMessagePayload),
15 Handshake(HandshakeMessagePayload),
16 ChangeCipherSpec(ChangeCipherSpecPayload),
17 Opaque(Payload),
18}
19
20impl MessagePayload {
21 pub fn encode(&self, bytes: &mut Vec<u8>) {
22 match *self {
23 MessagePayload::Alert(ref x) => x.encode(bytes),
24 MessagePayload::Handshake(ref x) => x.encode(bytes),
25 MessagePayload::ChangeCipherSpec(ref x) => x.encode(bytes),
26 MessagePayload::Opaque(ref x) => x.encode(bytes),
27 }
28 }
29
30 pub fn decode_given_type(
31 &self,
32 typ: ContentType,
33 vers: ProtocolVersion,
34 ) -> Option<MessagePayload> {
35 if let MessagePayload::Opaque(ref payload) = *self {
36 let mut r = Reader::init(&payload.0);
37 let parsed = match typ {
38 ContentType::Alert => {
39 Some(MessagePayload::Alert(AlertMessagePayload::read(&mut r)?))
40 }
41 ContentType::Handshake => {
42 let p = HandshakeMessagePayload::read_version(&mut r, vers)?;
43 Some(MessagePayload::Handshake(p))
44 }
45 ContentType::ChangeCipherSpec => {
46 let p = ChangeCipherSpecPayload::read(&mut r)?;
47 Some(MessagePayload::ChangeCipherSpec(p))
48 }
49 _ => None,
50 };
51
52 if r.any_left() { None } else { parsed }
53 } else {
54 None
55 }
56 }
57
58 pub fn length(&self) -> usize {
59 match *self {
60 MessagePayload::Alert(ref x) => x.length(),
61 MessagePayload::Handshake(ref x) => x.length(),
62 MessagePayload::ChangeCipherSpec(ref x) => x.length(),
63 MessagePayload::Opaque(ref x) => x.0.len(),
64 }
65 }
66
67 pub fn new_opaque(data: Vec<u8>) -> MessagePayload {
68 MessagePayload::Opaque(Payload::new(data))
69 }
70}
71
72#[derive(Debug)]
75pub struct Message {
76 pub typ: ContentType,
77 pub version: ProtocolVersion,
78 pub payload: MessagePayload,
79}
80
81impl Message {
82 const MAX_PAYLOAD: u16 = 16384 + 2048;
86
87 const HEADER_SIZE: u16 = 1 + 2 + 2;
89
90 pub const MAX_WIRE_SIZE: usize = (Message::MAX_PAYLOAD + Message::HEADER_SIZE) as usize;
92}
93
94impl Codec for Message {
95 fn read(r: &mut Reader) -> Option<Message> {
96 Message::read_with_detailed_error(r).ok()
97 }
98
99 fn encode(&self, bytes: &mut Vec<u8>) {
100 self.typ.encode(bytes);
101 self.version.encode(bytes);
102 (self.payload.length() as u16).encode(bytes);
103 self.payload.encode(bytes);
104 }
105}
106
107pub enum MessageError {
108 TooShortForHeader,
109 TooShortForLength,
110 IllegalLength,
111 IllegalContentType,
112 IllegalProtocolVersion,
113}
114
115impl Message {
116 pub fn read_with_detailed_error(r: &mut Reader) -> Result<Message, MessageError> {
120 let typ = ContentType::read(r).ok_or(MessageError::TooShortForHeader)?;
121 let version = ProtocolVersion::read(r).ok_or(MessageError::TooShortForHeader)?;
122 let len = u16::read(r).ok_or(MessageError::TooShortForHeader)?;
123
124 if len >= Message::MAX_PAYLOAD {
126 return Err(MessageError::IllegalLength);
127 }
128
129 if let ContentType::Unknown(_) = typ {
131 return Err(MessageError::IllegalContentType);
132 }
133
134 match version {
136 ProtocolVersion::Unknown(ref v) if (v & 0xff00) != 0x0300 => {
137 return Err(MessageError::IllegalProtocolVersion);
138 }
139 _ => {}
140 };
141
142 let mut sub = r
143 .sub(len as usize)
144 .ok_or(MessageError::TooShortForLength)?;
145 let payload = Payload::read(&mut sub).unwrap();
146
147 Ok(Message {
148 typ,
149 version,
150 payload: MessagePayload::Opaque(payload),
151 })
152 }
153
154 pub fn is_content_type(&self, typ: ContentType) -> bool {
155 self.typ == typ
156 }
157
158 pub fn is_handshake_type(&self, hstyp: HandshakeType) -> bool {
159 if let MessagePayload::Handshake(ref hsp) = self.payload {
161 hsp.typ == hstyp
162 } else {
163 false
164 }
165 }
166
167 pub fn decode_payload(&mut self) -> bool {
168 if self.typ == ContentType::ApplicationData {
170 return true;
171 }
172
173 if let Some(x) = self
174 .payload
175 .decode_given_type(self.typ, self.version)
176 {
177 self.payload = x;
178 true
179 } else {
180 false
181 }
182 }
183
184 pub fn take_payload(self) -> Vec<u8> {
185 self.into_opaque()
186 .take_opaque_payload()
187 .unwrap()
188 .0
189 }
190
191 pub fn take_opaque_payload(&mut self) -> Option<Payload> {
192 if let MessagePayload::Opaque(ref mut op) = self.payload {
193 Some(mem::replace(op, Payload::empty()))
194 } else {
195 None
196 }
197 }
198
199 pub fn into_opaque(self) -> Message {
200 if let MessagePayload::Opaque(_) = self.payload {
201 return self;
202 }
203
204 let mut buf = Vec::new();
205 self.payload.encode(&mut buf);
206
207 Message {
208 typ: self.typ,
209 version: self.version,
210 payload: MessagePayload::new_opaque(buf),
211 }
212 }
213
214 pub fn build_alert(level: AlertLevel, desc: AlertDescription) -> Message {
215 Message {
216 typ: ContentType::Alert,
217 version: ProtocolVersion::TLSv1_2,
218 payload: MessagePayload::Alert(AlertMessagePayload {
219 level,
220 description: desc,
221 }),
222 }
223 }
224
225 pub fn build_key_update_notify() -> Message {
226 Message {
227 typ: ContentType::Handshake,
228 version: ProtocolVersion::TLSv1_3,
229 payload: MessagePayload::Handshake(HandshakeMessagePayload::build_key_update_notify()),
230 }
231 }
232}
233
234impl<'a> Message {
235 pub fn to_borrowed(&'a self) -> BorrowMessage<'a> {
236 if let MessagePayload::Opaque(ref p) = self.payload {
237 BorrowMessage {
238 typ: self.typ,
239 version: self.version,
240 payload: &p.0,
241 }
242 } else {
243 unreachable!("to_borrowed must have opaque message");
244 }
245 }
246}
247
248pub struct BorrowMessage<'a> {
257 pub typ: ContentType,
258 pub version: ProtocolVersion,
259 pub payload: &'a [u8],
260}