1use crate::{
2 abstractions::{
3 Serializable,
4 SerializationError::{self, InvalidFormat, MissingInfo},
5 SerializationInfo, KEY_SIZE, SIGNATURE_SIZE, TYPE_APPEND, TYPE_CONNECT, TYPE_CREATE,
6 TYPE_ERROR, TYPE_PUT, TYPE_REQUEST, TYPE_SUBSCRIBE, TYPE_UNSUBSCRIBE, TYPE_WIPE,
7 },
8 codec::{
9 common::{assert_len, SlotBody},
10 objects::Certificate,
11 ptp_packet::PtpBody,
12 },
13};
14
15pub enum ResponseBody {
28 CONNECT {
29 pub_key: [u8; KEY_SIZE],
30 signature: [u8; SIGNATURE_SIZE],
31 certificates: Vec<Certificate>,
32 },
33 CREATE,
34 PUT,
35 APPEND,
36 WIPE,
37 REQUEST {
38 slots: SlotBody,
39 },
40 SUBSCRIBE {
41 slots: Option<SlotBody>,
42 },
43 UNSUBSCRIBE,
44 ERROR(u8, String),
45}
46
47impl PtpBody for ResponseBody {
48 fn packet_type(&self) -> u8 {
49 match self {
50 ResponseBody::CONNECT { .. } => TYPE_CONNECT,
51 ResponseBody::CREATE => TYPE_CREATE,
52 ResponseBody::PUT => TYPE_PUT,
53 ResponseBody::APPEND => TYPE_APPEND,
54 ResponseBody::WIPE => TYPE_WIPE,
55 ResponseBody::REQUEST { .. } => TYPE_REQUEST,
56 ResponseBody::SUBSCRIBE { .. } => TYPE_SUBSCRIBE,
57 ResponseBody::UNSUBSCRIBE => TYPE_UNSUBSCRIBE,
58 ResponseBody::ERROR(..) => TYPE_ERROR,
59 }
60 }
61}
62
63impl Serializable for ResponseBody {
64 fn size(&self) -> usize {
65 match self {
66 ResponseBody::CONNECT {
67 pub_key: _,
68 signature: _,
69 certificates,
70 } => {
71 KEY_SIZE
72 + SIGNATURE_SIZE
73 + certificates.iter().map(|c| c.size()).sum::<usize>()
74 + certificates.len()
75 }
76 ResponseBody::REQUEST { slots } => slots.size(),
77 ResponseBody::SUBSCRIBE { slots: Some(slots) } => slots.size(),
78 ResponseBody::SUBSCRIBE { slots: None } => 0,
79 ResponseBody::ERROR(_, e) => 1 + e.len(),
80 _ => 0,
81 }
82 }
83
84 fn get_bytes(&self) -> Vec<u8> {
85 let mut buff = Vec::new();
86 match self {
87 ResponseBody::CONNECT {
88 pub_key,
89 signature,
90 certificates,
91 } => {
92 buff.extend_from_slice(pub_key);
93 buff.extend_from_slice(signature);
94 for c in certificates.iter() {
95 let mut bytes = c.get_bytes();
96 buff.push(bytes.len() as u8);
97 buff.append(&mut bytes);
98 }
99 }
100 ResponseBody::REQUEST { slots } => {
101 buff = slots.get_bytes();
102 }
103 ResponseBody::SUBSCRIBE { slots: Some(slots) } => {
104 buff = slots.get_bytes();
105 }
106 ResponseBody::ERROR(code, err) => {
107 buff.push(*code);
108 buff.extend_from_slice(err.as_bytes());
109 }
110 _ => (),
111 }
112
113 buff
114 }
115
116 fn from_bytes(data: &[u8], info: Option<SerializationInfo>) -> Result<Self, SerializationError>
117 where
118 Self: Sized,
119 {
120 if let Some(SerializationInfo::PacketType(packet_type)) = info {
121 match packet_type {
122 TYPE_CONNECT => {
123 let len = KEY_SIZE + SIGNATURE_SIZE;
124 assert_len(data, len)?;
125 let mut pub_key = [0u8; KEY_SIZE];
126 pub_key.copy_from_slice(&data[..KEY_SIZE]);
127 let mut signature = [0u8; SIGNATURE_SIZE];
128 signature.copy_from_slice(&data[KEY_SIZE..len]);
129
130 let mut certificates = Vec::new();
131 let mut bytes_read = len;
132 while bytes_read != data.len() {
133 assert_len(data, bytes_read + 1)?;
134 let cert_len = data[bytes_read] as usize;
135 bytes_read += 1;
136 assert_len(data, cert_len)?;
137 certificates.push(Certificate::from_bytes(
138 &data[bytes_read..(bytes_read + cert_len)],
139 None,
140 )?);
141 bytes_read += cert_len;
142 }
143
144 Ok(ResponseBody::CONNECT {
145 pub_key,
146 signature,
147 certificates,
148 })
149 }
150 TYPE_CREATE => Ok(ResponseBody::CREATE),
151 TYPE_PUT => Ok(ResponseBody::PUT),
152 TYPE_APPEND => Ok(ResponseBody::APPEND),
153 TYPE_WIPE => Ok(ResponseBody::WIPE),
154 TYPE_REQUEST => Ok(ResponseBody::REQUEST {
155 slots: SlotBody::from_bytes(data, None)?,
156 }),
157 TYPE_SUBSCRIBE => Ok(ResponseBody::SUBSCRIBE {
158 slots: if !data.is_empty() {
159 Some(SlotBody::from_bytes(data, None)?)
160 } else {
161 None
162 },
163 }),
164 TYPE_UNSUBSCRIBE => Ok(ResponseBody::UNSUBSCRIBE),
165 TYPE_ERROR => {
166 assert_len(data, 1)?;
167 let res = String::from_utf8_lossy(&data[1..]).to_string();
168 Ok(ResponseBody::ERROR(data[0], res))
169 }
170 _ => Err(InvalidFormat(format!(
171 "Packet type {} is not supported",
172 packet_type
173 ))),
174 }
175 } else {
176 Err(MissingInfo(String::from("Missing info parameter")))
177 }
178 }
179}
180
181#[cfg(test)]
182mod parse_test {
183 use time_macros::datetime;
184
185 use crate::abstractions::Serializable;
186
187 use super::*;
188
189 #[test]
190 fn can_parse_connect_wo_certs() {
191 let connect = &[
192 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
193 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195 0, 0, 0, 0, 0, 0, 0, 0, 0,
196 ];
197 let connect =
198 ResponseBody::from_bytes(connect, Some(SerializationInfo::PacketType(0))).unwrap();
199
200 assert_eq!(96, connect.size());
201 assert_eq!(0, connect.packet_type());
202
203 if let ResponseBody::CONNECT {
204 pub_key,
205 signature,
206 certificates,
207 } = connect
208 {
209 assert_eq!(
210 &[
211 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
212 7, 8, 9, 0, 1, 2
213 ],
214 &pub_key
215 );
216 assert_eq!(&[0u8; 64], &signature);
217 assert_eq!(0, certificates.len());
218 } else {
219 panic!("Not a connect");
220 }
221 }
222
223 #[test]
224 fn can_parse_connect_with_2_certs() {
225 let mut connect = Vec::new();
226 connect.extend_from_slice(&[1u8; 32]);
227 connect.extend_from_slice(&[0u8; 64]);
228 let mut cert1 = Certificate {
229 public_key: [2u8; 32],
230 signature: [3u8; 64],
231 valid_from: datetime!(2020-01-01 00:00:00 UTC),
232 valid_to: datetime!(2020-01-01 00:00:00 UTC),
233 domain_or_ip: String::from("cert.plabble.org"),
234 }
235 .get_bytes();
236 let mut cert2 = Certificate {
237 public_key: [3u8; 32],
238 signature: [4u8; 64],
239 valid_from: datetime!(2020-01-01 00:00:00 UTC),
240 valid_to: datetime!(2020-01-01 00:00:00 UTC),
241 domain_or_ip: String::from("cert2.plabble.org"),
242 }
243 .get_bytes();
244 connect.push(cert1.len() as u8);
245 connect.append(&mut cert1);
246 connect.push(cert2.len() as u8);
247 connect.append(&mut cert2);
248
249 let conn = ResponseBody::from_bytes(&connect, Some(SerializationInfo::PacketType(0)));
250 let conn = conn.unwrap();
251 assert_eq!(connect.len(), conn.size());
252
253 if let ResponseBody::CONNECT {
254 pub_key,
255 signature,
256 certificates,
257 } = conn
258 {
259 assert_eq!(&[1u8; 32], &pub_key);
260 assert_eq!(&[0u8; 64], &signature);
261 assert_eq!(2, certificates.len());
262 assert_eq!(&[2u8; 32], &certificates[0].public_key);
263 assert_eq!("cert.plabble.org", &certificates[0].domain_or_ip);
264 assert_eq!(&[3u8; 32], &certificates[1].public_key);
265 assert_eq!("cert2.plabble.org", &certificates[1].domain_or_ip);
266 } else {
267 panic!("Not a connect");
268 }
269 }
270
271 #[test]
272 fn can_parse_subscribe_without_slots() {
273 let bytes = &[];
274 let subscribe =
275 ResponseBody::from_bytes(bytes, Some(SerializationInfo::PacketType(6))).unwrap();
276
277 assert_eq!(0, subscribe.size());
278 if let ResponseBody::SUBSCRIBE { slots } = subscribe {
279 assert_eq!(slots, None);
280 } else {
281 panic!("Not a subscribe");
282 }
283 }
284
285 #[test]
286 fn can_deserialize_error() {
287 let bytes = &[7, 97, 110, 32, 101, 114, 114, 111, 114, 33];
288 let error =
289 ResponseBody::from_bytes(bytes, Some(SerializationInfo::PacketType(15))).unwrap();
290
291 assert_eq!(10, error.size());
292 if let ResponseBody::ERROR(code, e) = error {
293 assert_eq!("an error!", &e);
294 assert_eq!(7, code);
295 } else {
296 panic!("not an error");
297 }
298 }
299}
300
301#[cfg(test)]
302mod serialize_test {
303 use super::*;
304
305 #[test]
306 fn can_serialize_connect_wo_certificates() {
307 let expected = &[
308 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
309 25, 26, 27, 28, 29, 30, 31, 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
310 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
311 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
312 61, 62, 63, 64,
313 ];
314 let mut pub_key = [0u8; 32];
315 pub_key.copy_from_slice((1u8..=32).collect::<Vec<u8>>().as_slice());
316 let mut signature = [0u8; 64];
317 signature.copy_from_slice((1u8..=64).collect::<Vec<u8>>().as_slice());
318
319 let connect = ResponseBody::CONNECT {
320 pub_key,
321 signature,
322 certificates: Vec::new(),
323 };
324 assert_eq!(&connect.get_bytes(), expected);
325 }
326
327 #[test]
328 fn can_serialize_subscribe_without_range() {
329 let subscribe = ResponseBody::SUBSCRIBE { slots: None };
330 assert_eq!(Vec::<u8>::new(), subscribe.get_bytes());
331 }
332
333 #[test]
334 fn can_serialize_error() {
335 let error = ResponseBody::ERROR(7, String::from("an error!"));
336 let bytes = error.get_bytes();
337 assert_eq!(vec![7, 97, 110, 32, 101, 114, 114, 111, 114, 33], bytes);
338 }
339}