hexgate/common/packets/
disconnect.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5use crate::common::crypto::Crypto;
6
7use super::*;
8
9pub struct Disconnect<'a> {
10    pub data: &'a [u8],
11}
12
13// 2^96 - 5
14const NONCE: [u8; 12] = [
15    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb,
16];
17impl<'a> Disconnect<'a> {
18    pub fn serialize(&self, crypto: &Crypto, buf: &mut [u8]) -> usize {
19        assert!(
20            self.data.len() <= 1183,
21            "Disconnect payload cannot be larger than 1183 bytes"
22        );
23        buf[0] = PacketIdentifier::Disconnect as u8;
24        buf[1..1 + self.data.len()].copy_from_slice(self.data);
25        let aad: [u8; 1] = buf[0..1].try_into().unwrap();
26        let tag = crypto.encrypt(&NONCE, &aad, &mut buf[1..1 + self.data.len()]);
27        buf[1 + self.data.len()..17 + self.data.len()].copy_from_slice(&tag);
28        17 + self.data.len()
29    }
30
31    pub fn deserialize(crypto: &Crypto, buf: &'a mut [u8]) -> Result<Self, &'static str> {
32        if buf.len() < 17 || buf.len() > 1200 {
33            return Err(ERROR_INVALID_DATA_SIZE);
34        }
35        let aad: [u8; 1] = buf[0..1].try_into().unwrap();
36        let tag: [u8; 16] = buf[buf.len() - 16..].try_into().unwrap();
37        let len = buf.len();
38        if crypto
39            .decrypt(&NONCE, &aad, &mut buf[1..len - 16], &tag)
40            .is_err()
41        {
42            return Err(ERROR_INVALID_TAG);
43        }
44        Ok(Disconnect {
45            data: &buf[1..buf.len() - 16],
46        })
47    }
48}