2022-08-29 19:01:56 +01:00
|
|
|
use crate::message::EncryptedPayload;
|
2022-02-10 19:52:28 +00:00
|
|
|
|
2022-02-12 17:18:24 +00:00
|
|
|
use aes_gcm::aead::{Aead, NewAead};
|
|
|
|
use aes_gcm::{Aes256Gcm, Key, Nonce}; // Or `Aes128Gcm`
|
2022-02-10 19:52:28 +00:00
|
|
|
use anyhow::{anyhow, Result};
|
2022-08-29 19:01:56 +01:00
|
|
|
use bytes::{Bytes, BytesMut};
|
2022-02-12 17:18:24 +00:00
|
|
|
use rand::{thread_rng, Rng};
|
2022-02-10 19:52:28 +00:00
|
|
|
use spake2::{Ed25519Group, Identity, Password, Spake2};
|
2022-08-29 19:01:56 +01:00
|
|
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
|
|
|
use tokio::net::TcpStream;
|
2022-02-10 19:52:28 +00:00
|
|
|
|
|
|
|
pub async fn handshake(
|
2022-08-29 19:01:56 +01:00
|
|
|
socket: TcpStream,
|
2022-02-10 19:52:28 +00:00
|
|
|
password: Bytes,
|
|
|
|
id: Bytes,
|
2022-08-29 19:01:56 +01:00
|
|
|
) -> Result<(TcpStream, Aes256Gcm)> {
|
|
|
|
let mut socket = socket;
|
2022-02-10 19:52:28 +00:00
|
|
|
let (s1, outbound_msg) =
|
|
|
|
Spake2::<Ed25519Group>::start_symmetric(&Password::new(password), &Identity::new(&id));
|
2022-02-12 01:50:14 +00:00
|
|
|
println!("client - sending handshake msg");
|
2022-08-29 19:01:56 +01:00
|
|
|
let mut handshake_msg = BytesMut::with_capacity(32 + 33);
|
|
|
|
handshake_msg.extend_from_slice(&id);
|
|
|
|
handshake_msg.extend_from_slice(&outbound_msg);
|
|
|
|
let handshake_msg = handshake_msg.freeze();
|
2022-08-29 17:51:37 +01:00
|
|
|
println!("client - handshake msg, {:?}", handshake_msg);
|
2022-08-29 21:14:30 +01:00
|
|
|
println!("id: {:?}. msg: {:?}", id.clone(), outbound_msg.clone());
|
2022-08-29 19:01:56 +01:00
|
|
|
socket.write_all(&handshake_msg).await?;
|
|
|
|
let mut buffer = [0; 33];
|
|
|
|
let n = socket.read_exact(&mut buffer).await?;
|
|
|
|
println!("The bytes: {:?}", &buffer[..n]);
|
|
|
|
let first_message = BytesMut::from(&buffer[..n]).freeze();
|
|
|
|
println!("client - handshake msg responded to: {:?}", first_message);
|
2022-02-10 19:52:28 +00:00
|
|
|
let key = match s1.finish(&first_message[..]) {
|
|
|
|
Ok(key_bytes) => key_bytes,
|
|
|
|
Err(e) => return Err(anyhow!(e.to_string())),
|
|
|
|
};
|
2022-08-29 21:14:30 +01:00
|
|
|
println!("Handshake successful. Key is {:?}", key);
|
2022-08-29 19:01:56 +01:00
|
|
|
return Ok((socket, new_cipher(&key)));
|
2022-02-10 19:52:28 +00:00
|
|
|
}
|
2022-02-12 17:18:24 +00:00
|
|
|
|
2022-02-12 19:59:04 +00:00
|
|
|
pub fn new_cipher(key: &Vec<u8>) -> Aes256Gcm {
|
2022-02-12 17:18:24 +00:00
|
|
|
let key = Key::from_slice(&key[..]);
|
|
|
|
Aes256Gcm::new(key)
|
|
|
|
}
|
|
|
|
|
2022-02-12 19:59:04 +00:00
|
|
|
pub const NONCE_SIZE_IN_BYTES: usize = 96 / 8;
|
|
|
|
pub fn encrypt(cipher: &Aes256Gcm, body: &Vec<u8>) -> Result<EncryptedPayload> {
|
2022-02-12 17:18:24 +00:00
|
|
|
let mut arr = [0u8; NONCE_SIZE_IN_BYTES];
|
|
|
|
thread_rng().try_fill(&mut arr[..])?;
|
|
|
|
let nonce = Nonce::from_slice(&arr);
|
|
|
|
let plaintext = body.as_ref();
|
|
|
|
match cipher.encrypt(nonce, plaintext) {
|
2022-02-12 19:59:04 +00:00
|
|
|
Ok(body) => Ok(EncryptedPayload {
|
|
|
|
nonce: arr.to_vec(),
|
|
|
|
body,
|
2022-02-12 17:18:24 +00:00
|
|
|
}),
|
2022-02-12 19:59:04 +00:00
|
|
|
Err(_) => Err(anyhow!("Encryption error")),
|
2022-02-12 17:18:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-12 19:59:04 +00:00
|
|
|
pub fn decrypt(cipher: &Aes256Gcm, payload: &EncryptedPayload) -> Result<Bytes> {
|
2022-02-12 17:18:24 +00:00
|
|
|
let nonce = Nonce::from_slice(payload.nonce.as_ref());
|
|
|
|
match cipher.decrypt(nonce, payload.body.as_ref()) {
|
2022-02-12 19:59:04 +00:00
|
|
|
Ok(payload) => Ok(Bytes::from(payload)),
|
|
|
|
Err(_) => Err(anyhow!("Decryption error")),
|
2022-02-12 17:18:24 +00:00
|
|
|
}
|
|
|
|
}
|