Correctly test for equality the DirSync::Req

Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
Luca Fulchir 2023-06-09 20:01:18 +02:00
parent a6fda8180d
commit 4df73b658a
Signed by: luca.fulchir
GPG Key ID: 8F6440603D13A78E
6 changed files with 41 additions and 20 deletions

View File

@ -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]);

View File

@ -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,

View File

@ -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,

View File

@ -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",
);
}

View File

@ -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

View File

@ -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