1 use crate::msgs::alert::AlertMessagePayload;
2 use crate::msgs::base::Payload;
3 use crate::msgs::ccs::ChangeCipherSpecPayload;
4 use crate::msgs::codec::{Codec, Reader};
5 use crate::msgs::enums::HandshakeType;
6 use crate::msgs::enums::{AlertDescription, AlertLevel};
7 use crate::msgs::enums::{ContentType, ProtocolVersion};
8 use crate::msgs::handshake::HandshakeMessagePayload;
9 
10 use std::mem;
11 
12 #[derive(Debug)]
13 pub enum MessagePayload {
14     Alert(AlertMessagePayload),
15     Handshake(HandshakeMessagePayload),
16     ChangeCipherSpec(ChangeCipherSpecPayload),
17     Opaque(Payload),
18 }
19 
20 impl MessagePayload {
encode(&self, bytes: &mut Vec<u8>)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 
decode_given_type( &self, typ: ContentType, vers: ProtocolVersion, ) -> Option<MessagePayload>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 
length(&self) -> usize58     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 
new_opaque(data: Vec<u8>) -> MessagePayload67     pub fn new_opaque(data: Vec<u8>) -> MessagePayload {
68         MessagePayload::Opaque(Payload::new(data))
69     }
70 }
71 
72 /// A TLS frame, named TLSPlaintext in the standard.
73 /// This type owns all memory for its interior parts.
74 #[derive(Debug)]
75 pub struct Message {
76     pub typ: ContentType,
77     pub version: ProtocolVersion,
78     pub payload: MessagePayload,
79 }
80 
81 impl Message {
82     /// This is the maximum on-the-wire size of a TLSCiphertext.
83     /// That's 2^14 payload bytes, a header, and a 2KB allowance
84     /// for ciphertext overheads.
85     const MAX_PAYLOAD: u16 = 16384 + 2048;
86 
87     /// Content type, version and size.
88     const HEADER_SIZE: u16 = 1 + 2 + 2;
89 
90     /// Maximum on-wire message size.
91     pub const MAX_WIRE_SIZE: usize = (Message::MAX_PAYLOAD + Message::HEADER_SIZE) as usize;
92 }
93 
94 impl Codec for Message {
read(r: &mut Reader) -> Option<Message>95     fn read(r: &mut Reader) -> Option<Message> {
96         Message::read_with_detailed_error(r).ok()
97     }
98 
encode(&self, bytes: &mut Vec<u8>)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 
107 pub enum MessageError {
108     TooShortForHeader,
109     TooShortForLength,
110     IllegalLength,
111     IllegalContentType,
112     IllegalProtocolVersion,
113 }
114 
115 impl Message {
116     /// Like Message::read(), but allows the important distinction between:
117     /// this message might be valid if we read more data; and this message will
118     /// never be valid.
read_with_detailed_error(r: &mut Reader) -> Result<Message, MessageError>119     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         // Reject oversize messages
125         if len >= Message::MAX_PAYLOAD {
126             return Err(MessageError::IllegalLength);
127         }
128 
129         // Don't accept any new content-types.
130         if let ContentType::Unknown(_) = typ {
131             return Err(MessageError::IllegalContentType);
132         }
133 
134         // Accept only versions 0x03XX for any XX.
135         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 
is_content_type(&self, typ: ContentType) -> bool154     pub fn is_content_type(&self, typ: ContentType) -> bool {
155         self.typ == typ
156     }
157 
is_handshake_type(&self, hstyp: HandshakeType) -> bool158     pub fn is_handshake_type(&self, hstyp: HandshakeType) -> bool {
159         // Bit of a layering violation, but OK.
160         if let MessagePayload::Handshake(ref hsp) = self.payload {
161             hsp.typ == hstyp
162         } else {
163             false
164         }
165     }
166 
decode_payload(&mut self) -> bool167     pub fn decode_payload(&mut self) -> bool {
168         // Do we need a decode?
169         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 
take_payload(self) -> Vec<u8>184     pub fn take_payload(self) -> Vec<u8> {
185         self.into_opaque()
186             .take_opaque_payload()
187             .unwrap()
188             .0
189     }
190 
take_opaque_payload(&mut self) -> Option<Payload>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 
into_opaque(self) -> Message199     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 
build_alert(level: AlertLevel, desc: AlertDescription) -> Message214     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 
build_key_update_notify() -> Message225     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 
234 impl<'a> Message {
to_borrowed(&'a self) -> BorrowMessage<'a>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 
248 /// A TLS frame, named TLSPlaintext in the standard.
249 ///
250 /// This type differs from `Message` because it borrows
251 /// its payload.  You can make a `Message` from an
252 /// `BorrowMessage`, but this involves a copy.
253 ///
254 /// This type also cannot decode its internals and
255 /// is not a `Codec` type, only `Message` can do that.
256 pub struct BorrowMessage<'a> {
257     pub typ: ContentType,
258     pub version: ProtocolVersion,
259     pub payload: &'a [u8],
260 }
261