From 4df73b658ac7c3993cca4858e8f19ac96a982dfc Mon Sep 17 00:00:00 2001 From: Luca Fulchir Date: Fri, 9 Jun 2023 20:01:18 +0200 Subject: [PATCH] Correctly test for equality the DirSync::Req Signed-off-by: Luca Fulchir --- src/auth/mod.rs | 4 ++-- src/connection/handshake/dirsync.rs | 26 ++++++++++++++------------ src/connection/handshake/mod.rs | 11 ++++++++--- src/connection/handshake/tests.rs | 16 +++++++++++++++- src/connection/mod.rs | 2 +- src/enc/mod.rs | 2 +- 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/auth/mod.rs b/src/auth/mod.rs index 20df6f7..84be8cb 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -4,7 +4,7 @@ use crate::enc::Random; use ::zeroize::Zeroize; /// User identifier. 16 bytes for easy uuid conversion -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub struct UserID(pub [u8; 16]); impl From<[u8; 16]> for UserID { @@ -34,7 +34,7 @@ impl UserID { } } /// Authentication Token, basically just 32 random bytes -#[derive(Clone, Zeroize)] +#[derive(Clone, Zeroize, PartialEq)] #[zeroize(drop)] pub struct Token(pub [u8; 32]); diff --git a/src/connection/handshake/dirsync.rs b/src/connection/handshake/dirsync.rs index e387d2c..68d58da 100644 --- a/src/connection/handshake/dirsync.rs +++ b/src/connection/handshake/dirsync.rs @@ -24,8 +24,8 @@ use ::arrayref::array_mut_ref; // TODO: merge with crate::enc::sym::Nonce /// random nonce -#[derive(Debug, Clone, Copy)] -pub struct Nonce([u8; 16]); +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct Nonce(pub(crate) [u8; 16]); impl Nonce { /// Create a new random Nonce @@ -51,7 +51,7 @@ impl From<&[u8; 16]> for Nonce { } /// Parsed handshake -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum DirSync { /// Directory synchronized handshake: client request Req(Req), @@ -83,7 +83,7 @@ impl DirSync { } /// Client request of a directory synchronized handshake -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct Req { /// Id of the server key used for the key exchange pub key_id: KeyID, @@ -107,6 +107,7 @@ impl Req { /// NOTE: starts from the beginning of the fenrir packet pub fn encrypted_offset(&self) -> usize { ProtocolVersion::len() + + crate::handshake::HandshakeID::len() + KeyID::len() + KeyExchangeKind::len() + HkdfKind::len() @@ -195,7 +196,7 @@ impl super::HandshakeParsing for Req { } /// Quick way to avoid mixing cipher and clear text -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum ReqInner { /// Data is still encrytped, we only keep the length CipherText(usize), @@ -211,16 +212,17 @@ impl ReqInner { } } /// parse the cleartext + // FIXME: return Result<> pub fn deserialize_as_cleartext(&mut self, raw: &[u8]) { let clear = match self { ReqInner::CipherText(len) => { assert!( - *len == raw.len(), + *len > raw.len(), "DirSync::ReqInner::CipherText length mismatch" ); match ReqData::deserialize(raw) { Ok(clear) => clear, - Err(_) => return, + Err(_e) => return, } } _ => return, @@ -230,7 +232,7 @@ impl ReqInner { } /// Informations needed for authentication -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct AuthInfo { /// User of the domain pub user: auth::UserID, @@ -308,7 +310,7 @@ impl AuthInfo { } /// Decrypted request data -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct ReqData { /// Random nonce, the client can use this to track multiple key exchanges pub nonce: Nonce, @@ -373,7 +375,7 @@ impl ReqData { } /// Quick way to avoid mixing cipher and clear text -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum RespInner { /// Server data, still in ciphertext CipherText(usize), @@ -412,7 +414,7 @@ impl RespInner { } /// Server response in a directory synchronized handshake -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct Resp { /// Tells the client with which key the exchange was done pub client_key_id: KeyID, @@ -476,7 +478,7 @@ impl Resp { } /// Decrypted response data -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct RespData { /// Client nonce, copied from the request pub client_nonce: Nonce, diff --git a/src/connection/handshake/mod.rs b/src/connection/handshake/mod.rs index bd0b501..8796566 100644 --- a/src/connection/handshake/mod.rs +++ b/src/connection/handshake/mod.rs @@ -13,7 +13,6 @@ use crate::{ }, }; use ::num_traits::FromPrimitive; -use ::std::{collections::VecDeque, rc::Rc}; /// Handshake errors #[derive(::thiserror::Error, Debug, Copy, Clone)] @@ -65,6 +64,12 @@ pub enum HandshakeID { #[strum(serialize = "stateless")] Stateless, } +impl HandshakeID { + /// The length of the serialized field + pub const fn len() -> usize { + 1 + } +} pub(crate) struct HandshakeServer { pub id: KeyID, @@ -166,7 +171,7 @@ impl HandshakeClientList { } /// Parsed handshake -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum HandshakeData { /// Directory synchronized handhsake DirSync(dirsync::DirSync), @@ -220,7 +225,7 @@ impl HandshakeKind { } /// Parsed handshake -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct Handshake { /// Fenrir Protocol version pub fenrir_version: ProtocolVersion, diff --git a/src/connection/handshake/tests.rs b/src/connection/handshake/tests.rs index df485d7..d37012b 100644 --- a/src/connection/handshake/tests.rs +++ b/src/connection/handshake/tests.rs @@ -55,11 +55,25 @@ fn test_handshake_dirsync_req() { &mut bytes, ); - let deserialized = match Handshake::deserialize(&bytes) { + let mut deserialized = match Handshake::deserialize(&bytes) { Ok(deserialized) => deserialized, Err(e) => { assert!(false, "{}", e.to_string()); return; } }; + if let HandshakeData::DirSync(dirsync::DirSync::Req(r_a)) = + &mut deserialized.data + { + let enc_start = + r_a.encrypted_offset() + cipher_send.kind().nonce_len().0; + r_a.data.deserialize_as_cleartext( + &bytes[enc_start..(bytes.len() - cipher_send.kind().tag_len().0)], + ); + }; + + assert!( + deserialized == h_req, + "DirSync Req (de)serialization not working", + ); } diff --git a/src/connection/mod.rs b/src/connection/mod.rs index ee71c4e..07b7c18 100644 --- a/src/connection/mod.rs +++ b/src/connection/mod.rs @@ -30,7 +30,7 @@ pub struct IDRecv(pub ID); pub struct IDSend(pub ID); /// Version of the fenrir protocol in use -#[derive(::num_derive::FromPrimitive, Debug, Copy, Clone)] +#[derive(::num_derive::FromPrimitive, Debug, Copy, Clone, PartialEq)] #[repr(u8)] pub enum ProtocolVersion { /// First Fenrir Protocol Version diff --git a/src/enc/mod.rs b/src/enc/mod.rs index 06a6200..ff1bb9f 100644 --- a/src/enc/mod.rs +++ b/src/enc/mod.rs @@ -80,7 +80,7 @@ impl ::rand_core::CryptoRng for &Random {} /// Secret, used for keys. /// Grants that on drop() we will zero out memory -#[derive(Zeroize, Clone)] +#[derive(Zeroize, Clone, PartialEq)] #[zeroize(drop)] pub struct Secret([u8; 32]); // Fake debug implementation to avoid leaking secrets