pub use rsa::RsaPublicKey;
use std::{collections::VecDeque, io::Write};
use aes::cipher::{AsyncStreamCipher, Key, KeyIvInit};
use arrayvec::ArrayVec;
use rand::thread_rng;
use rsa::Oaep;
use serde::{Deserialize, Serialize};
use sha1::Sha1;
use super::SecurePacket;
type Aes128CfbEnc = cfb_mode::Encryptor<aes::Aes128>;
type Aes128CfbDec = cfb_mode::Decryptor<aes::Aes128>;
#[derive(Debug)]
pub struct LocoClientSecureLayer {
key: Key<aes::Aes128>,
pub read_buffer: VecDeque<u8>,
pub write_buffer: VecDeque<u8>,
}
impl LocoClientSecureLayer {
pub fn new(encrypt_key: [u8; 16]) -> Self {
Self {
key: encrypt_key.into(),
read_buffer: VecDeque::new(),
write_buffer: VecDeque::new(),
}
}
pub fn handshake(&mut self, key: &RsaPublicKey) {
#[derive(Serialize)]
struct RawHandshakeHeader {
encrypted_key_size: u32,
key_type: u32,
encrypt_type: u32,
}
let encrypted_key = key
.encrypt(
&mut thread_rng(),
Oaep::new_with_mgf_hash::<Sha1, Sha1>(),
self.key.as_slice(),
)
.unwrap();
bincode::serialize_into(
&mut self.write_buffer,
&RawHandshakeHeader {
encrypted_key_size: encrypted_key.len() as u32,
key_type: 15, encrypt_type: 2, },
)
.unwrap();
self.write_buffer.write_all(&encrypted_key).unwrap();
}
pub fn read(&mut self) -> Option<SecurePacket<Box<[u8]>>> {
if self.read_buffer.len() < 20 {
return None;
}
let raw_header = {
let buf = self
.read_buffer
.iter()
.take(20)
.copied()
.collect::<ArrayVec<u8, 20>>();
bincode::deserialize::<RawHeader>(&buf).unwrap()
};
if self.read_buffer.len() < 4 + raw_header.size as usize {
return None;
}
let mut data = self
.read_buffer
.drain(..4 + raw_header.size as usize)
.skip(20)
.collect::<Box<[u8]>>();
Aes128CfbDec::new(&self.key, &raw_header.iv.into()).decrypt(&mut data);
Some(SecurePacket {
iv: raw_header.iv,
data,
})
}
pub fn send(&mut self, mut packet: SecurePacket<impl AsMut<[u8]> + 'static>) {
let encrypted_data = {
let data = packet.data.as_mut();
Aes128CfbEnc::new(&self.key, &packet.iv.into()).encrypt(data);
data
};
bincode::serialize_into(
&mut self.write_buffer,
&RawHeader {
size: 16 + encrypted_data.len() as u32,
iv: packet.iv,
},
)
.unwrap();
self.write_buffer.write_all(encrypted_data).unwrap();
}
}
#[derive(Serialize, Deserialize)]
struct RawHeader {
size: u32,
iv: [u8; 16],
}