ConnTrack with ciphers
Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
parent
f53ef95c73
commit
7bddc9bf55
|
@ -9,6 +9,11 @@ pub use handshake::Handshake;
|
|||
pub use packet::ConnectionID as ID;
|
||||
pub use packet::{Packet, PacketData};
|
||||
|
||||
use crate::enc::{
|
||||
hkdf::HkdfSha3,
|
||||
sym::{CipherKind, CipherRecv, CipherSend},
|
||||
};
|
||||
|
||||
/// Version of the fenrir protocol in use
|
||||
#[derive(::num_derive::FromPrimitive, Debug, Copy, Clone)]
|
||||
#[repr(u8)]
|
||||
|
@ -33,11 +38,43 @@ pub struct Connection {
|
|||
/// Connection ID
|
||||
pub id: ID,
|
||||
/// The main hkdf used for all secrets in this connection
|
||||
pub hkdf: crate::enc::hkdf::HkdfSha3,
|
||||
pub hkdf: HkdfSha3,
|
||||
/// Cipher for decrypting data
|
||||
pub cipher_recv: CipherRecv,
|
||||
/// Cipher for encrypting data
|
||||
pub cipher_send: CipherSend,
|
||||
}
|
||||
|
||||
/// Role: used to set the correct secrets
|
||||
/// * Server: Connection is Incoming
|
||||
/// * Client: Connection is Outgoing
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(u8)]
|
||||
pub enum Role {
|
||||
/// Server: we receive the connection
|
||||
Server = 0,
|
||||
/// Client: we initate the connection
|
||||
Client,
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
pub(crate) fn new(id: ID, hkdf: crate::enc::hkdf::HkdfSha3) -> Self {
|
||||
Self { id, hkdf }
|
||||
pub(crate) fn new(hkdf: HkdfSha3, cipher: CipherKind, role: Role) -> Self {
|
||||
let (secret_recv, secret_send) = match role {
|
||||
Role::Server => {
|
||||
(hkdf.get_secret(b"to_server"), hkdf.get_secret(b"to_client"))
|
||||
}
|
||||
Role::Client => {
|
||||
(hkdf.get_secret(b"to_client"), hkdf.get_secret(b"to_server"))
|
||||
}
|
||||
};
|
||||
let mut cipher_recv = CipherRecv::new(cipher, secret_recv);
|
||||
let mut cipher_send = CipherSend::new(cipher, secret_send);
|
||||
|
||||
Self {
|
||||
id: ID::Handshake,
|
||||
hkdf,
|
||||
cipher_recv,
|
||||
cipher_send,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,8 +200,15 @@ impl Cipher {
|
|||
}
|
||||
|
||||
/// Receive only cipher
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct CipherRecv(Cipher);
|
||||
impl ::core::fmt::Debug for CipherRecv {
|
||||
fn fmt(
|
||||
&self,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
) -> Result<(), ::std::fmt::Error> {
|
||||
::core::fmt::Debug::fmt("[hidden cipher recv]", f)
|
||||
}
|
||||
}
|
||||
|
||||
impl CipherRecv {
|
||||
/// Build a new Cipher
|
||||
|
@ -253,17 +260,24 @@ impl Data {
|
|||
}
|
||||
|
||||
/// Send only cipher
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct CipherSend {
|
||||
nonce: Nonce,
|
||||
nonce: NonceSync,
|
||||
cipher: Cipher,
|
||||
}
|
||||
impl ::core::fmt::Debug for CipherSend {
|
||||
fn fmt(
|
||||
&self,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
) -> Result<(), ::std::fmt::Error> {
|
||||
::core::fmt::Debug::fmt("[hidden cipher send]", f)
|
||||
}
|
||||
}
|
||||
|
||||
impl CipherSend {
|
||||
/// Build a new Cipher
|
||||
pub fn new(kind: CipherKind, secret: Secret) -> Self {
|
||||
Self {
|
||||
nonce: Nonce::new(),
|
||||
nonce: NonceSync::new(),
|
||||
cipher: Cipher::new(kind, secret),
|
||||
}
|
||||
}
|
||||
|
@ -276,9 +290,9 @@ impl CipherSend {
|
|||
}
|
||||
}
|
||||
/// Encrypt the given data
|
||||
pub fn encrypt(&mut self, aad: AAD, data: &mut Data) -> Result<(), Error> {
|
||||
self.cipher.encrypt(&self.nonce, aad, data)?;
|
||||
self.nonce.advance();
|
||||
pub fn encrypt(&self, aad: AAD, data: &mut Data) -> Result<(), Error> {
|
||||
let old_nonce = self.nonce.advance();
|
||||
self.cipher.encrypt(&old_nonce, aad, data)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -372,3 +386,27 @@ impl Nonce {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Synchronize the mutex acess with a nonce for multithread safety
|
||||
#[derive(Debug)]
|
||||
pub struct NonceSync {
|
||||
nonce: ::std::sync::Mutex<Nonce>,
|
||||
}
|
||||
impl NonceSync {
|
||||
/// Create a new thread safe nonce
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
nonce: ::std::sync::Mutex::new(Nonce::new()),
|
||||
}
|
||||
}
|
||||
/// Advance the nonce and return the *old* value
|
||||
pub fn advance(&self) -> Nonce {
|
||||
let old_nonce: Nonce;
|
||||
{
|
||||
let mut nonce = self.nonce.lock().unwrap();
|
||||
old_nonce = *nonce;
|
||||
nonce.advance();
|
||||
}
|
||||
old_nonce
|
||||
}
|
||||
}
|
||||
|
|
33
src/lib.rs
33
src/lib.rs
|
@ -305,7 +305,7 @@ impl ConnList {
|
|||
ids_used: vec![bitmap_id],
|
||||
}
|
||||
}
|
||||
fn reserve_first(&mut self, hkdf: HkdfSha3) -> Arc<Connection> {
|
||||
fn reserve_first(&mut self, mut conn: Connection) -> Arc<Connection> {
|
||||
// uhm... bad things are going on here:
|
||||
// * id must be initialized, but only because:
|
||||
// * rust does not understand that after the `!found` id is always
|
||||
|
@ -332,14 +332,15 @@ impl ConnList {
|
|||
self.ids_used.push(new_bitmap);
|
||||
}
|
||||
let new_id = connection::ID::new_u64(id);
|
||||
let new_conn = Arc::new(connection::Connection::new(new_id, hkdf));
|
||||
conn.id = new_id;
|
||||
let conn = Arc::new(conn);
|
||||
if (self.connections.len() as u64) < id {
|
||||
self.connections.push(Some(new_conn.clone()));
|
||||
self.connections.push(Some(conn.clone()));
|
||||
} else {
|
||||
// very probably redundant
|
||||
self.connections[id as usize] = Some(new_conn.clone());
|
||||
self.connections[id as usize] = Some(conn.clone());
|
||||
}
|
||||
new_conn
|
||||
conn
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,11 +657,16 @@ impl Fenrir {
|
|||
let srv_secret =
|
||||
enc::sym::Secret::new_rand(&self.rand);
|
||||
|
||||
let raw_conn = Connection::new(
|
||||
authinfo.hkdf,
|
||||
req.cipher,
|
||||
connection::Role::Server,
|
||||
);
|
||||
// track connection
|
||||
let auth_conn = {
|
||||
let mut lock =
|
||||
self.connections.write().await;
|
||||
lock.reserve_first(authinfo.hkdf)
|
||||
lock.reserve_first(raw_conn)
|
||||
};
|
||||
|
||||
// TODO: move all the next bits into
|
||||
|
@ -672,20 +678,15 @@ impl Fenrir {
|
|||
service_id: srv_conn_id,
|
||||
service_key: srv_secret,
|
||||
};
|
||||
// build response
|
||||
let secret_send =
|
||||
auth_conn.hkdf.get_secret(b"to_client");
|
||||
let mut cipher_send = CipherSend::new(
|
||||
authinfo.cipher,
|
||||
secret_send,
|
||||
);
|
||||
use crate::enc::sym::AAD;
|
||||
let aad = AAD(&mut []); // no aad for now
|
||||
let mut data = cipher_send
|
||||
let mut data = auth_conn
|
||||
.cipher_send
|
||||
.make_data(dirsync::RespData::len());
|
||||
|
||||
if let Err(e) =
|
||||
cipher_send.encrypt(aad, &mut data)
|
||||
if let Err(e) = auth_conn
|
||||
.cipher_send
|
||||
.encrypt(aad, &mut data)
|
||||
{
|
||||
::tracing::error!("can't encrypt: {:?}", e);
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue