namespace #4

Manually merged
luca.fulchir merged 3 commits from namespace into main 2023-06-28 17:07:28 +00:00
7 changed files with 312 additions and 282 deletions
Showing only changes of commit 5dff5c8c9a - Show all commits

View File

@ -0,0 +1,77 @@
//! Directory synchronized handshake
//! 1-RTT connection
//!
//! The simplest, fastest handshake supported by Fenrir
//! Downside: It does not offer protection from DDos,
//! no perfect forward secrecy
//!
//! To grant a form of perfect forward secrecy, the server should periodically
//! change the DNSSEC public/private keys
use crate::enc::{
sym::{NonceLen, TagLen},
Random,
};
pub mod req;
pub mod resp;
// TODO: merge with crate::enc::sym::Nonce
/// random nonce
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Nonce(pub(crate) [u8; 16]);
impl Nonce {
/// Create a new random Nonce
pub fn new(rnd: &Random) -> Self {
use ::core::mem::MaybeUninit;
let mut out: MaybeUninit<[u8; 16]>;
#[allow(unsafe_code)]
unsafe {
out = MaybeUninit::uninit();
let _ = rnd.fill(out.assume_init_mut());
Self(out.assume_init())
}
}
/// Length of the serialized Nonce
pub const fn len() -> usize {
16
}
}
impl From<&[u8; 16]> for Nonce {
fn from(raw: &[u8; 16]) -> Self {
Self(raw.clone())
}
}
/// Parsed handshake
#[derive(Debug, Clone, PartialEq)]
pub enum DirSync {
/// Directory synchronized handshake: client request
Req(req::Req),
/// Directory synchronized handshake: server response
Resp(resp::Resp),
}
impl DirSync {
/// actual length of the dirsync handshake data
pub fn len(&self, head_len: NonceLen, tag_len: TagLen) -> usize {
match self {
DirSync::Req(req) => req.len(),
DirSync::Resp(resp) => resp.len(head_len, tag_len),
}
}
/// Serialize into raw bytes
/// NOTE: assumes that there is exactly asa much buffer as needed
pub fn serialize(
&self,
head_len: NonceLen,
tag_len: TagLen,
out: &mut [u8],
) {
match self {
DirSync::Req(req) => req.serialize(head_len, tag_len, out),
DirSync::Resp(resp) => resp.serialize(head_len, tag_len, out),
}
}
}

View File

@ -1,85 +1,22 @@
//! Directory synchronized handshake //! Directory synchronized handshake, Request parsing
//! 1-RTT connection
//!
//! The simplest, fastest handshake supported by Fenrir
//! Downside: It does not offer protection from DDos,
//! no perfect forward secrecy
//!
//! To grant a form of perfect forward secrecy, the server should periodically
//! change the DNSSEC public/private keys
use super::Error;
use crate::{ use crate::{
auth, auth,
connection::{handshake, ProtocolVersion, ID}, connection::{
handshake::{
self,
dirsync::{DirSync, Nonce},
Error,
},
ProtocolVersion, ID,
},
enc::{ enc::{
asym::{ExchangePubKey, KeyExchangeKind, KeyID}, asym::{ExchangePubKey, KeyExchangeKind, KeyID},
hkdf, hkdf,
sym::{self, NonceLen, TagLen}, sym::{self, NonceLen, TagLen},
Random, Secret,
}, },
}; };
// TODO: merge with crate::enc::sym::Nonce
/// random nonce
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Nonce(pub(crate) [u8; 16]);
impl Nonce {
/// Create a new random Nonce
pub fn new(rnd: &Random) -> Self {
use ::core::mem::MaybeUninit;
let mut out: MaybeUninit<[u8; 16]>;
#[allow(unsafe_code)]
unsafe {
out = MaybeUninit::uninit();
let _ = rnd.fill(out.assume_init_mut());
Self(out.assume_init())
}
}
/// Length of the serialized Nonce
pub const fn len() -> usize {
16
}
}
impl From<&[u8; 16]> for Nonce {
fn from(raw: &[u8; 16]) -> Self {
Self(raw.clone())
}
}
/// Parsed handshake
#[derive(Debug, Clone, PartialEq)]
pub enum DirSync {
/// Directory synchronized handshake: client request
Req(Req),
/// Directory synchronized handshake: server response
Resp(Resp),
}
impl DirSync {
/// actual length of the dirsync handshake data
pub fn len(&self, head_len: NonceLen, tag_len: TagLen) -> usize {
match self {
DirSync::Req(req) => req.len(),
DirSync::Resp(resp) => resp.len(head_len, tag_len),
}
}
/// Serialize into raw bytes
/// NOTE: assumes that there is exactly asa much buffer as needed
pub fn serialize(
&self,
head_len: NonceLen,
tag_len: TagLen,
out: &mut [u8],
) {
match self {
DirSync::Req(req) => req.serialize(head_len, tag_len, out),
DirSync::Resp(resp) => resp.serialize(head_len, tag_len, out),
}
}
}
/// Client request of a directory synchronized handshake /// Client request of a directory synchronized handshake
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct Req { pub struct Req {
@ -94,7 +31,7 @@ pub struct Req {
/// Client ephemeral public key used for key exchanges /// Client ephemeral public key used for key exchanges
pub exchange_key: ExchangePubKey, pub exchange_key: ExchangePubKey,
/// encrypted data /// encrypted data
pub data: ReqState, pub data: State,
// SECURITY: TODO: Add padding to min: 1200 bytes // SECURITY: TODO: Add padding to min: 1200 bytes
// to avoid amplification attaks // to avoid amplification attaks
// also: 1200 < 1280 to allow better vpn compatibility // also: 1200 < 1280 to allow better vpn compatibility
@ -119,8 +56,8 @@ impl Req {
tag_len: TagLen, tag_len: TagLen,
) -> usize { ) -> usize {
match &self.data { match &self.data {
ReqState::ClearText(data) => data.len() + head_len.0 + tag_len.0, State::ClearText(data) => data.len() + head_len.0 + tag_len.0,
ReqState::CipherText(length) => *length, State::CipherText(length) => *length,
} }
} }
/// actual length of the directory synchronized request /// actual length of the directory synchronized request
@ -150,7 +87,7 @@ impl Req {
let written_next = 5 + key_len; let written_next = 5 + key_len;
self.exchange_key.serialize_into(&mut out[5..written_next]); self.exchange_key.serialize_into(&mut out[5..written_next]);
let written = written_next; let written = written_next;
if let ReqState::ClearText(data) = &self.data { if let State::ClearText(data) = &self.data {
let from = written + head_len.0; let from = written + head_len.0;
let to = out.len() - tag_len.0; let to = out.len() - tag_len.0;
data.serialize(&mut out[from..to]); data.serialize(&mut out[from..to]);
@ -190,7 +127,7 @@ impl handshake::Parsing for Req {
Ok(exchange_key) => exchange_key, Ok(exchange_key) => exchange_key,
Err(e) => return Err(e.into()), Err(e) => return Err(e.into()),
}; };
let data = ReqState::CipherText(raw.len() - (CURR_SIZE + len)); let data = State::CipherText(raw.len() - (CURR_SIZE + len));
Ok(handshake::Data::DirSync(DirSync::Req(Self { Ok(handshake::Data::DirSync(DirSync::Req(Self {
key_id, key_id,
exchange, exchange,
@ -204,18 +141,18 @@ impl handshake::Parsing for Req {
/// Quick way to avoid mixing cipher and clear text /// Quick way to avoid mixing cipher and clear text
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum ReqState { pub enum State {
/// Data is still encrytped, we only keep the length /// Data is still encrytped, we only keep the length
CipherText(usize), CipherText(usize),
/// Client data, decrypted and parsed /// Client data, decrypted and parsed
ClearText(ReqData), ClearText(Data),
} }
impl ReqState { impl State {
/// The length of the data /// The length of the data
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
match self { match self {
ReqState::CipherText(len) => *len, State::CipherText(len) => *len,
ReqState::ClearText(data) => data.len(), State::ClearText(data) => data.len(),
} }
} }
/// parse the cleartext /// parse the cleartext
@ -224,19 +161,19 @@ impl ReqState {
raw: &[u8], raw: &[u8],
) -> Result<(), Error> { ) -> Result<(), Error> {
let clear = match self { let clear = match self {
ReqState::CipherText(len) => { State::CipherText(len) => {
assert!( assert!(
*len > raw.len(), *len > raw.len(),
"DirSync::ReqState::CipherText length mismatch" "DirSync::State::CipherText length mismatch"
); );
match ReqData::deserialize(raw) { match Data::deserialize(raw) {
Ok(clear) => clear, Ok(clear) => clear,
Err(e) => return Err(e), Err(e) => return Err(e),
} }
} }
_ => return Err(Error::Parsing), _ => return Err(Error::Parsing),
}; };
*self = ReqState::ClearText(clear); *self = State::ClearText(clear);
Ok(()) Ok(())
} }
} }
@ -321,7 +258,7 @@ impl AuthInfo {
/// Decrypted request data /// Decrypted request data
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct ReqData { pub struct Data {
/// Random nonce, the client can use this to track multiple key exchanges /// Random nonce, the client can use this to track multiple key exchanges
pub nonce: Nonce, pub nonce: Nonce,
/// Client key id so the client can use and rotate keys /// Client key id so the client can use and rotate keys
@ -331,7 +268,7 @@ pub struct ReqData {
/// Authentication data /// Authentication data
pub auth: AuthInfo, pub auth: AuthInfo,
} }
impl ReqData { impl Data {
/// actual length of the request data /// actual length of the request data
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
Nonce::len() + KeyID::len() + ID::len() + self.auth.len() Nonce::len() + KeyID::len() + ID::len() + self.auth.len()
@ -383,177 +320,3 @@ impl ReqData {
}) })
} }
} }
/// Quick way to avoid mixing cipher and clear text
#[derive(Debug, Clone, PartialEq)]
pub enum RespState {
/// Server data, still in ciphertext
CipherText(usize),
/// Parsed, cleartext server data
ClearText(RespData),
}
impl RespState {
/// The length of the data
pub fn len(&self) -> usize {
match self {
RespState::CipherText(len) => *len,
RespState::ClearText(_) => RespData::len(),
}
}
/// parse the cleartext
pub fn deserialize_as_cleartext(
&mut self,
raw: &[u8],
) -> Result<(), Error> {
let clear = match self {
RespState::CipherText(len) => {
assert!(
*len > raw.len(),
"DirSync::RespState::CipherText length mismatch"
);
match RespData::deserialize(raw) {
Ok(clear) => clear,
Err(e) => return Err(e),
}
}
_ => return Err(Error::Parsing),
};
*self = RespState::ClearText(clear);
Ok(())
}
/// Serialize the still cleartext data
pub fn serialize(&self, out: &mut [u8]) {
if let RespState::ClearText(clear) = &self {
clear.serialize(out);
}
}
}
/// Server response in a directory synchronized handshake
#[derive(Debug, Clone, PartialEq)]
pub struct Resp {
/// Tells the client with which key the exchange was done
pub client_key_id: KeyID,
/// actual response data, might be encrypted
pub data: RespState,
}
impl handshake::Parsing for Resp {
fn deserialize(raw: &[u8]) -> Result<handshake::Data, Error> {
const MIN_PKT_LEN: usize = 68;
if raw.len() < MIN_PKT_LEN {
return Err(Error::NotEnoughData);
}
let client_key_id: KeyID =
KeyID(u16::from_le_bytes(raw[0..KeyID::len()].try_into().unwrap()));
Ok(handshake::Data::DirSync(DirSync::Resp(Self {
client_key_id,
data: RespState::CipherText(raw[KeyID::len()..].len()),
})))
}
}
impl Resp {
/// return the offset of the encrypted data
/// NOTE: starts from the beginning of the fenrir packet
pub fn encrypted_offset(&self) -> usize {
ProtocolVersion::len() + handshake::ID::len() + KeyID::len()
}
/// return the total length of the cleartext data
pub fn encrypted_length(
&self,
head_len: NonceLen,
tag_len: TagLen,
) -> usize {
match &self.data {
RespState::ClearText(_data) => {
RespData::len() + head_len.0 + tag_len.0
}
RespState::CipherText(len) => *len,
}
}
/// Total length of the response handshake
pub fn len(&self, head_len: NonceLen, tag_len: TagLen) -> usize {
KeyID::len() + head_len.0 + self.data.len() + tag_len.0
}
/// Serialize into raw bytes
/// NOTE: assumes that there is exactly as much buffer as needed
pub fn serialize(
&self,
head_len: NonceLen,
_tag_len: TagLen,
out: &mut [u8],
) {
out[0..KeyID::len()]
.copy_from_slice(&self.client_key_id.0.to_le_bytes());
let start_data = KeyID::len() + head_len.0;
let end_data = start_data + self.data.len();
self.data.serialize(&mut out[start_data..end_data]);
}
}
/// Decrypted response data
#[derive(Debug, Clone, PartialEq)]
pub struct RespData {
/// Client nonce, copied from the request
pub client_nonce: Nonce,
/// Server Connection ID
pub id: ID,
/// Service Connection ID
pub service_connection_id: ID,
/// Service encryption key
pub service_key: Secret,
}
impl RespData {
/// Return the expected length for buffer allocation
pub fn len() -> usize {
Nonce::len() + ID::len() + ID::len() + Secret::len()
}
/// Serialize the data into a buffer
/// NOTE: assumes that there is exactly asa much buffer as needed
pub fn serialize(&self, out: &mut [u8]) {
let mut start = 0;
let mut end = Nonce::len();
out[start..end].copy_from_slice(&self.client_nonce.0);
start = end;
end = end + ID::len();
self.id.serialize(&mut out[start..end]);
start = end;
end = end + ID::len();
self.service_connection_id.serialize(&mut out[start..end]);
start = end;
end = end + Secret::len();
out[start..end].copy_from_slice(self.service_key.as_ref());
}
/// Parse the cleartext raw data
pub fn deserialize(raw: &[u8]) -> Result<Self, Error> {
let raw_sized: &[u8; 16] = raw[..Nonce::len()].try_into().unwrap();
let client_nonce: Nonce = raw_sized.into();
let end = Nonce::len() + ID::len();
let id: ID =
u64::from_le_bytes(raw[Nonce::len()..end].try_into().unwrap())
.into();
if id.is_handshake() {
return Err(Error::Parsing);
}
let parsed = end;
let end = parsed + ID::len();
let service_connection_id: ID =
u64::from_le_bytes(raw[parsed..end].try_into().unwrap()).into();
if service_connection_id.is_handshake() {
return Err(Error::Parsing);
}
let parsed = end;
let end = parsed + Secret::len();
let raw_secret: &[u8; 32] = raw[parsed..end].try_into().unwrap();
let service_key = raw_secret.into();
Ok(Self {
client_nonce,
id,
service_connection_id,
service_key,
})
}
}

View File

@ -0,0 +1,189 @@
//! Directory synchronized handshake, Response parsing
use crate::{
connection::{
handshake::{
self,
dirsync::{DirSync, Nonce},
Error,
},
ProtocolVersion, ID,
},
enc::{
asym::KeyID,
sym::{NonceLen, TagLen},
Secret,
},
};
/// Server response in a directory synchronized handshake
#[derive(Debug, Clone, PartialEq)]
pub struct Resp {
/// Tells the client with which key the exchange was done
pub client_key_id: KeyID,
/// actual response data, might be encrypted
pub data: State,
}
impl handshake::Parsing for Resp {
fn deserialize(raw: &[u8]) -> Result<handshake::Data, Error> {
const MIN_PKT_LEN: usize = 68;
if raw.len() < MIN_PKT_LEN {
return Err(Error::NotEnoughData);
}
let client_key_id: KeyID =
KeyID(u16::from_le_bytes(raw[0..KeyID::len()].try_into().unwrap()));
Ok(handshake::Data::DirSync(DirSync::Resp(Self {
client_key_id,
data: State::CipherText(raw[KeyID::len()..].len()),
})))
}
}
impl Resp {
/// return the offset of the encrypted data
/// NOTE: starts from the beginning of the fenrir packet
pub fn encrypted_offset(&self) -> usize {
ProtocolVersion::len() + handshake::ID::len() + KeyID::len()
}
/// return the total length of the cleartext data
pub fn encrypted_length(
&self,
head_len: NonceLen,
tag_len: TagLen,
) -> usize {
match &self.data {
State::ClearText(_data) => Data::len() + head_len.0 + tag_len.0,
State::CipherText(len) => *len,
}
}
/// Total length of the response handshake
pub fn len(&self, head_len: NonceLen, tag_len: TagLen) -> usize {
KeyID::len() + head_len.0 + self.data.len() + tag_len.0
}
/// Serialize into raw bytes
/// NOTE: assumes that there is exactly as much buffer as needed
pub fn serialize(
&self,
head_len: NonceLen,
_tag_len: TagLen,
out: &mut [u8],
) {
out[0..KeyID::len()]
.copy_from_slice(&self.client_key_id.0.to_le_bytes());
let start_data = KeyID::len() + head_len.0;
let end_data = start_data + self.data.len();
self.data.serialize(&mut out[start_data..end_data]);
}
}
/// Quick way to avoid mixing cipher and clear text
#[derive(Debug, Clone, PartialEq)]
pub enum State {
/// Server data, still in ciphertext
CipherText(usize),
/// Parsed, cleartext server data
ClearText(Data),
}
impl State {
/// The length of the data
pub fn len(&self) -> usize {
match self {
State::CipherText(len) => *len,
State::ClearText(_) => Data::len(),
}
}
/// parse the cleartext
pub fn deserialize_as_cleartext(
&mut self,
raw: &[u8],
) -> Result<(), Error> {
let clear = match self {
State::CipherText(len) => {
assert!(
*len > raw.len(),
"DirSync::State::CipherText length mismatch"
);
match Data::deserialize(raw) {
Ok(clear) => clear,
Err(e) => return Err(e),
}
}
_ => return Err(Error::Parsing),
};
*self = State::ClearText(clear);
Ok(())
}
/// Serialize the still cleartext data
pub fn serialize(&self, out: &mut [u8]) {
if let State::ClearText(clear) = &self {
clear.serialize(out);
}
}
}
/// Decrypted response data
#[derive(Debug, Clone, PartialEq)]
pub struct Data {
/// Client nonce, copied from the request
pub client_nonce: Nonce,
/// Server Connection ID
pub id: ID,
/// Service Connection ID
pub service_connection_id: ID,
/// Service encryption key
pub service_key: Secret,
}
impl Data {
/// Return the expected length for buffer allocation
pub fn len() -> usize {
Nonce::len() + ID::len() + ID::len() + Secret::len()
}
/// Serialize the data into a buffer
/// NOTE: assumes that there is exactly asa much buffer as needed
pub fn serialize(&self, out: &mut [u8]) {
let mut start = 0;
let mut end = Nonce::len();
out[start..end].copy_from_slice(&self.client_nonce.0);
start = end;
end = end + ID::len();
self.id.serialize(&mut out[start..end]);
start = end;
end = end + ID::len();
self.service_connection_id.serialize(&mut out[start..end]);
start = end;
end = end + Secret::len();
out[start..end].copy_from_slice(self.service_key.as_ref());
}
/// Parse the cleartext raw data
pub fn deserialize(raw: &[u8]) -> Result<Self, Error> {
let raw_sized: &[u8; 16] = raw[..Nonce::len()].try_into().unwrap();
let client_nonce: Nonce = raw_sized.into();
let end = Nonce::len() + ID::len();
let id: ID =
u64::from_le_bytes(raw[Nonce::len()..end].try_into().unwrap())
.into();
if id.is_handshake() {
return Err(Error::Parsing);
}
let parsed = end;
let end = parsed + ID::len();
let service_connection_id: ID =
u64::from_le_bytes(raw[parsed..end].try_into().unwrap()).into();
if service_connection_id.is_handshake() {
return Err(Error::Parsing);
}
let parsed = end;
let end = parsed + Secret::len();
let raw_secret: &[u8; 32] = raw[parsed..end].try_into().unwrap();
let service_key = raw_secret.into();
Ok(Self {
client_nonce,
id,
service_connection_id,
service_key,
})
}
}

View File

@ -166,9 +166,11 @@ impl Handshake {
None => return Err(Error::Parsing), None => return Err(Error::Parsing),
}; };
let data = match handshake_kind { let data = match handshake_kind {
HandshakeKind::DirSyncReq => dirsync::Req::deserialize(&raw[2..])?, HandshakeKind::DirSyncReq => {
dirsync::req::Req::deserialize(&raw[2..])?
}
HandshakeKind::DirSyncResp => { HandshakeKind::DirSyncResp => {
dirsync::Resp::deserialize(&raw[2..])? dirsync::resp::Resp::deserialize(&raw[2..])?
} }
}; };
Ok(Self { Ok(Self {

View File

@ -22,11 +22,11 @@ fn test_handshake_dirsync_req() {
} }
}; };
let data = dirsync::ReqState::ClearText(dirsync::ReqData { let data = dirsync::req::State::ClearText(dirsync::req::Data {
nonce: dirsync::Nonce::new(&rand), nonce: dirsync::Nonce::new(&rand),
client_key_id: KeyID(2424), client_key_id: KeyID(2424),
id: ID::ID(::core::num::NonZeroU64::new(424242).unwrap()), id: ID::ID(::core::num::NonZeroU64::new(424242).unwrap()),
auth: dirsync::AuthInfo { auth: dirsync::req::AuthInfo {
user: auth::UserID::new(&rand), user: auth::UserID::new(&rand),
token: auth::Token::new_anonymous(&rand), token: auth::Token::new_anonymous(&rand),
service_id: auth::SERVICEID_AUTH, service_id: auth::SERVICEID_AUTH,
@ -35,7 +35,7 @@ fn test_handshake_dirsync_req() {
}); });
let h_req = Handshake::new(handshake::Data::DirSync( let h_req = Handshake::new(handshake::Data::DirSync(
dirsync::DirSync::Req(dirsync::Req { dirsync::DirSync::Req(dirsync::req::Req {
key_id: KeyID(4224), key_id: KeyID(4224),
exchange: enc::asym::KeyExchangeKind::X25519DiffieHellman, exchange: enc::asym::KeyExchangeKind::X25519DiffieHellman,
hkdf: enc::hkdf::Kind::Sha3, hkdf: enc::hkdf::Kind::Sha3,
@ -81,7 +81,7 @@ fn test_handshake_dirsync_reqsp() {
let service_key = enc::Secret::new_rand(&rand); let service_key = enc::Secret::new_rand(&rand);
let data = dirsync::RespState::ClearText(dirsync::RespData { let data = dirsync::resp::State::ClearText(dirsync::resp::Data {
client_nonce: dirsync::Nonce::new(&rand), client_nonce: dirsync::Nonce::new(&rand),
id: ID::ID(::core::num::NonZeroU64::new(424242).unwrap()), id: ID::ID(::core::num::NonZeroU64::new(424242).unwrap()),
service_connection_id: ID::ID( service_connection_id: ID::ID(
@ -91,7 +91,7 @@ fn test_handshake_dirsync_reqsp() {
}); });
let h_resp = Handshake::new(handshake::Data::DirSync( let h_resp = Handshake::new(handshake::Data::DirSync(
dirsync::DirSync::Resp(dirsync::Resp { dirsync::DirSync::Resp(dirsync::resp::Resp {
client_key_id: KeyID(4444), client_key_id: KeyID(4444),
data, data,
}), }),

View File

@ -53,7 +53,7 @@ fn test_encrypt_decrypt() {
let service_key = enc::Secret::new_rand(&rand); let service_key = enc::Secret::new_rand(&rand);
let data = dirsync::RespState::ClearText(dirsync::RespData { let data = dirsync::resp::State::ClearText(dirsync::resp::Data {
client_nonce: dirsync::Nonce::new(&rand), client_nonce: dirsync::Nonce::new(&rand),
id: ID::ID(::core::num::NonZeroU64::new(424242).unwrap()), id: ID::ID(::core::num::NonZeroU64::new(424242).unwrap()),
service_connection_id: ID::ID( service_connection_id: ID::ID(
@ -62,7 +62,7 @@ fn test_encrypt_decrypt() {
service_key, service_key,
}); });
let resp = dirsync::Resp { let resp = dirsync::resp::Resp {
client_key_id: KeyID(4444), client_key_id: KeyID(4444),
data, data,
}; };

View File

@ -326,25 +326,25 @@ impl Worker {
}; };
// build request // build request
let auth_info = dirsync::AuthInfo { let auth_info = dirsync::req::AuthInfo {
user: UserID::new_anonymous(), user: UserID::new_anonymous(),
token: Token::new_anonymous(&self.rand), token: Token::new_anonymous(&self.rand),
service_id: conn_info.service_id, service_id: conn_info.service_id,
domain: conn_info.domain, domain: conn_info.domain,
}; };
let req_data = dirsync::ReqData { let req_data = dirsync::req::Data {
nonce: dirsync::Nonce::new(&self.rand), nonce: dirsync::Nonce::new(&self.rand),
client_key_id, client_key_id,
id: auth_recv_id.0, //FIXME: is zero id: auth_recv_id.0, //FIXME: is zero
auth: auth_info, auth: auth_info,
}; };
let req = dirsync::Req { let req = dirsync::req::Req {
key_id: key.0, key_id: key.0,
exchange, exchange,
hkdf: hkdf_selected, hkdf: hkdf_selected,
cipher: cipher_selected, cipher: cipher_selected,
exchange_key: pub_key, exchange_key: pub_key,
data: dirsync::ReqState::ClearText(req_data), data: dirsync::req::State::ClearText(req_data),
}; };
let encrypt_start = let encrypt_start =
connection::ID::len() + req.encrypted_offset(); connection::ID::len() + req.encrypted_offset();
@ -459,9 +459,8 @@ impl Worker {
::tracing::error!("AuthInfo on non DS::Req"); ::tracing::error!("AuthInfo on non DS::Req");
return; return;
} }
use dirsync::ReqState;
let req_data = match req.data { let req_data = match req.data {
ReqState::ClearText(req_data) => req_data, dirsync::req::State::ClearText(req_data) => req_data,
_ => { _ => {
::tracing::error!("AuthNeeded: expected ClearText"); ::tracing::error!("AuthNeeded: expected ClearText");
assert!(false, "AuthNeeded: unreachable"); assert!(false, "AuthNeeded: unreachable");
@ -527,7 +526,7 @@ impl Worker {
let auth_id_recv = self.connections.reserve_first(); let auth_id_recv = self.connections.reserve_first();
auth_conn.id_recv = auth_id_recv; auth_conn.id_recv = auth_id_recv;
let resp_data = dirsync::RespData { let resp_data = dirsync::resp::Data {
client_nonce: req_data.nonce, client_nonce: req_data.nonce,
id: auth_conn.id_recv.0, id: auth_conn.id_recv.0,
service_connection_id: srv_conn_id, service_connection_id: srv_conn_id,
@ -537,10 +536,9 @@ impl Worker {
// no aad for now // no aad for now
let aad = AAD(&mut []); let aad = AAD(&mut []);
use dirsync::RespState; let resp = dirsync::resp::Resp {
let resp = dirsync::Resp {
client_key_id: req_data.client_key_id, client_key_id: req_data.client_key_id,
data: RespState::ClearText(resp_data), data: dirsync::resp::State::ClearText(resp_data),
}; };
let encrypt_from = let encrypt_from =
connection::ID::len() + resp.encrypted_offset(); connection::ID::len() + resp.encrypted_offset();
@ -579,7 +577,8 @@ impl Worker {
} }
// track connection // track connection
let resp_data; let resp_data;
if let dirsync::RespState::ClearText(r_data) = ds_resp.data if let dirsync::resp::State::ClearText(r_data) =
ds_resp.data
{ {
resp_data = r_data; resp_data = r_data;
} else { } else {