ruck/src/crypto.rs

70 lines
2.4 KiB
Rust
Raw Normal View History

2022-02-12 17:18:24 +00:00
use crate::message::{EncryptedPayload, HandshakePayload, Message, MessageStream};
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};
use bytes::Bytes;
use futures::prelude::*;
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};
pub async fn handshake(
stream: &mut MessageStream,
password: Bytes,
id: Bytes,
2022-02-12 19:59:04 +00:00
) -> Result<(&mut MessageStream, Aes256Gcm)> {
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");
let handshake_msg = Message::HandshakeMessage(HandshakePayload {
id,
msg: Bytes::from(outbound_msg),
});
// println!("client - handshake msg, {:?}", handshake_msg);
2022-02-12 01:50:14 +00:00
stream.send(handshake_msg).await?;
2022-02-10 19:52:28 +00:00
let first_message = match stream.next().await {
Some(Ok(msg)) => match msg {
Message::HandshakeMessage(response) => response.msg,
_ => return Err(anyhow!("Expecting handshake message response")),
},
_ => {
return Err(anyhow!("No response to handshake message"));
}
};
2022-02-12 01:50:14 +00:00
println!("client - handshake msg responded to");
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())),
};
// println!("Handshake successful. Key is {:?}", key);
2022-02-12 19:59:04 +00:00
return Ok((stream, 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
}
}