Some more improvements

This commit is contained in:
Dennis Schwerdel 2020-10-29 00:09:40 +01:00
parent 47f872d5f4
commit 16da58b8df
5 changed files with 61 additions and 50 deletions

View File

@ -761,7 +761,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
info!("Ignoring invalid init message from peer {}", addr_nice(src)); info!("Ignoring invalid init message from peer {}", addr_nice(src));
} }
Err(e) => { Err(e) => {
error!("Error: {}", e); error!("{}", e);
} }
Ok(_) => {} Ok(_) => {}
} }
@ -770,7 +770,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
fn handle_device_event(&mut self, buffer: &mut MsgBuffer) { fn handle_device_event(&mut self, buffer: &mut MsgBuffer) {
try_fail!(self.device.read(buffer), "Failed to read from device: {}"); try_fail!(self.device.read(buffer), "Failed to read from device: {}");
if let Err(e) = self.handle_interface_data(buffer) { if let Err(e) = self.handle_interface_data(buffer) {
error!("Error: {}", e); error!("{}", e);
} }
} }
@ -805,7 +805,7 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
break break
} }
if let Err(e) = self.housekeep() { if let Err(e) = self.housekeep() {
error!("Error: {}", e) error!("{}", e)
} }
self.next_housekeep = TS::now() + 1 self.next_housekeep = TS::now() + 1
} }

View File

@ -210,6 +210,7 @@ impl CryptoCore {
} }
pub fn rotate_key(&mut self, key: LessSafeKey, id: u64, use_for_sending: bool) { pub fn rotate_key(&mut self, key: LessSafeKey, id: u64, use_for_sending: bool) {
debug!("Rotated key {} (use for sending: {})", id, use_for_sending);
let id = (id % 4) as usize; let id = (id % 4) as usize;
self.keys[id] = CryptoKey::new(&self.rand, key, self.nonce_half); self.keys[id] = CryptoKey::new(&self.rand, key, self.nonce_half);
if use_for_sending { if use_for_sending {

View File

@ -306,7 +306,7 @@ impl<P: Payload> PeerCrypto<P> {
self.init = None self.init = None
} }
if self.core.is_some() { if self.core.is_some() {
self.rotation = Some(RotationState::new(!is_initiator, buffer)?); self.rotation = Some(RotationState::new(!is_initiator, buffer));
} }
if !is_initiator { if !is_initiator {
if self.unencrypted { if self.unencrypted {
@ -397,7 +397,7 @@ impl<P: Payload> PeerCrypto<P> {
self.rotate_counter += 1; self.rotate_counter += 1;
if self.rotate_counter >= ROTATE_INTERVAL { if self.rotate_counter >= ROTATE_INTERVAL {
self.rotate_counter = 0; self.rotate_counter = 0;
if let Some(rot) = rotate.cycle(out)? { if let Some(rot) = rotate.cycle(out) {
let core = self.get_core()?; let core = self.get_core()?;
let algo = core.algorithm(); let algo = core.algorithm();
let key = LessSafeKey::new(UnboundKey::new(algo, &rot.key[..algo.key_len()]).unwrap()); let key = LessSafeKey::new(UnboundKey::new(algo, &rot.key[..algo.key_len()]).unwrap());

View File

@ -97,18 +97,19 @@ pub struct RotatedKey {
impl RotationState { impl RotationState {
#[allow(dead_code)] #[allow(dead_code)]
pub fn new(initiator: bool, out: &mut MsgBuffer) -> Result<Self, Error> { pub fn new(initiator: bool, out: &mut MsgBuffer) -> Self {
if initiator { if initiator {
let (private_key, public_key) = Self::create_key(); let (private_key, public_key) = Self::create_key();
Self::send(&RotationMessage { message_id: 1, confirm: None, propose: public_key }, out)?; Self::send(&RotationMessage { message_id: 1, confirm: None, propose: public_key }, out);
Ok(Self { confirmed: None, pending: None, proposed: Some(private_key), message_id: 1, timeout: false }) Self { confirmed: None, pending: None, proposed: Some(private_key), message_id: 1, timeout: false }
} else { } else {
Ok(Self { confirmed: None, pending: None, proposed: None, message_id: 0, timeout: false }) Self { confirmed: None, pending: None, proposed: None, message_id: 0, timeout: false }
} }
} }
fn send(msg: &RotationMessage, out: &mut MsgBuffer) -> Result<(), Error> { fn send(msg: &RotationMessage, out: &mut MsgBuffer) {
assert!(out.is_empty()); assert!(out.is_empty());
debug!("Rotation sending message with id {}", msg.message_id);
let len; let len;
{ {
let mut cursor = Cursor::new(out.buffer()); let mut cursor = Cursor::new(out.buffer());
@ -116,7 +117,6 @@ impl RotationState {
len = cursor.position() as usize; len = cursor.position() as usize;
} }
out.set_length(len); out.set_length(len);
Ok(())
} }
fn create_key() -> (EcdhPrivateKey, EcdhPublicKey) { fn create_key() -> (EcdhPrivateKey, EcdhPublicKey) {
@ -152,6 +152,7 @@ impl RotationState {
if msg.message_id <= self.message_id { if msg.message_id <= self.message_id {
return None return None
} }
debug!("Received rotation message with id {}", msg.message_id);
self.timeout = false; self.timeout = false;
// Create key from proposal and store reply as pending // Create key from proposal and store reply as pending
let (private_key, public_key) = Self::create_key(); let (private_key, public_key) = Self::create_key();
@ -168,7 +169,7 @@ impl RotationState {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn cycle(&mut self, out: &mut MsgBuffer) -> Result<Option<RotatedKey>, Error> { pub fn cycle(&mut self, out: &mut MsgBuffer) -> Option<RotatedKey> {
if let Some(ref private_key) = self.proposed { if let Some(ref private_key) = self.proposed {
// Still a proposed key that has not been confirmed, proposal must have been lost // Still a proposed key that has not been confirmed, proposal must have been lost
if self.timeout { if self.timeout {
@ -178,10 +179,10 @@ impl RotationState {
Self::send( Self::send(
&RotationMessage { confirm: Some(confirmed_key.clone()), propose: proposed_key, message_id }, &RotationMessage { confirm: Some(confirmed_key.clone()), propose: proposed_key, message_id },
out out
)?; );
} else { } else {
// First message has been lost // First message has been lost
Self::send(&RotationMessage { confirm: None, propose: proposed_key, message_id: 1 }, out)?; Self::send(&RotationMessage { confirm: None, propose: proposed_key, message_id: 1 }, out);
} }
} else { } else {
self.timeout = true; self.timeout = true;
@ -195,14 +196,14 @@ impl RotationState {
let (private_key, propose_key) = Self::create_key(); let (private_key, propose_key) = Self::create_key();
self.proposed = Some(private_key); self.proposed = Some(private_key);
self.confirmed = Some((confirm_key.clone(), message_id)); self.confirmed = Some((confirm_key.clone(), message_id));
Self::send(&RotationMessage { confirm: Some(confirm_key), propose: propose_key, message_id }, out)?; Self::send(&RotationMessage { confirm: Some(confirm_key), propose: propose_key, message_id }, out);
return Ok(Some(RotatedKey { key, id: message_id, use_for_sending: false })) return Some(RotatedKey { key, id: message_id, use_for_sending: false })
} else { } else {
// Nothing pending nor proposed, still waiting to receive message 1 // Nothing pending nor proposed, still waiting to receive message 1
// Do nothing, peer will retry // Do nothing, peer will retry
} }
} }
Ok(None) None
} }
} }
@ -250,8 +251,8 @@ mod tests {
let mut out2 = MsgBuffer::new(8); let mut out2 = MsgBuffer::new(8);
// Initialization // Initialization
let mut node1 = RotationState::new(true, &mut out1).unwrap(); let mut node1 = RotationState::new(true, &mut out1);
let mut node2 = RotationState::new(false, &mut out2).unwrap(); let mut node2 = RotationState::new(false, &mut out2);
assert!(!out1.is_empty()); assert!(!out1.is_empty());
let msg1 = out1.msg().unwrap(); let msg1 = out1.msg().unwrap();
assert_eq!(msg1.message_id, 1); assert_eq!(msg1.message_id, 1);
@ -260,8 +261,8 @@ mod tests {
let key = node2.process_message(msg1); let key = node2.process_message(msg1);
assert!(key.is_none()); assert!(key.is_none());
// Cycle 1 // Cycle 1
let key1 = node1.cycle(&mut out1).unwrap(); let key1 = node1.cycle(&mut out1);
let key2 = node2.cycle(&mut out2).unwrap(); let key2 = node2.cycle(&mut out2);
assert!(key1.is_none()); assert!(key1.is_none());
assert!(out1.is_empty()); assert!(out1.is_empty());
assert!(key2.is_some()); assert!(key2.is_some());
@ -279,8 +280,8 @@ mod tests {
assert_eq!(key.id, 2); assert_eq!(key.id, 2);
assert_eq!(key.use_for_sending, true); assert_eq!(key.use_for_sending, true);
// Cycle 2 // Cycle 2
let key1 = node1.cycle(&mut out1).unwrap(); let key1 = node1.cycle(&mut out1);
let key2 = node2.cycle(&mut out2).unwrap(); let key2 = node2.cycle(&mut out2);
assert!(key1.is_some()); assert!(key1.is_some());
let key1 = key1.unwrap(); let key1 = key1.unwrap();
assert_eq!(key1.id, 3); assert_eq!(key1.id, 3);
@ -298,8 +299,8 @@ mod tests {
assert_eq!(key.id, 3); assert_eq!(key.id, 3);
assert_eq!(key.use_for_sending, true); assert_eq!(key.use_for_sending, true);
// Cycle 3 // Cycle 3
let key1 = node1.cycle(&mut out1).unwrap(); let key1 = node1.cycle(&mut out1);
let key2 = node2.cycle(&mut out2).unwrap(); let key2 = node2.cycle(&mut out2);
assert!(key1.is_none()); assert!(key1.is_none());
assert!(out1.is_empty()); assert!(out1.is_empty());
assert!(key2.is_some()); assert!(key2.is_some());
@ -323,30 +324,30 @@ mod tests {
let mut out1 = MsgBuffer::new(8); let mut out1 = MsgBuffer::new(8);
let mut out2 = MsgBuffer::new(8); let mut out2 = MsgBuffer::new(8);
let mut node1 = RotationState::new(true, &mut out1).unwrap(); let mut node1 = RotationState::new(true, &mut out1);
let mut node2 = RotationState::new(false, &mut out2).unwrap(); let mut node2 = RotationState::new(false, &mut out2);
let msg1 = out1.clone().msg().unwrap(); let msg1 = out1.clone().msg().unwrap();
let msg1_copy = out1.msg().unwrap(); let msg1_copy = out1.msg().unwrap();
node2.process_message(msg1); node2.process_message(msg1);
assert!(node2.process_message(msg1_copy).is_none()); assert!(node2.process_message(msg1_copy).is_none());
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
let msg2 = out2.clone().msg().unwrap(); let msg2 = out2.clone().msg().unwrap();
let msg2_copy = out2.msg().unwrap(); let msg2_copy = out2.msg().unwrap();
// Message 2 // Message 2
assert!(node1.process_message(msg2).is_some()); assert!(node1.process_message(msg2).is_some());
assert!(node1.process_message(msg2_copy).is_none()); assert!(node1.process_message(msg2_copy).is_none());
// Cycle 2 // Cycle 2
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
let msg1 = out1.clone().msg().unwrap(); let msg1 = out1.clone().msg().unwrap();
let msg1_copy = out1.msg().unwrap(); let msg1_copy = out1.msg().unwrap();
// Message 3 // Message 3
assert!(node2.process_message(msg1).is_some()); assert!(node2.process_message(msg1).is_some());
assert!(node2.process_message(msg1_copy).is_none()); assert!(node2.process_message(msg1_copy).is_none());
// Cycle 3 // Cycle 3
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
let msg2 = out2.clone().msg().unwrap(); let msg2 = out2.clone().msg().unwrap();
let msg2_copy = out2.msg().unwrap(); let msg2_copy = out2.msg().unwrap();
// Message 4 // Message 4
@ -359,22 +360,22 @@ mod tests {
let mut out1 = MsgBuffer::new(8); let mut out1 = MsgBuffer::new(8);
let mut out2 = MsgBuffer::new(8); let mut out2 = MsgBuffer::new(8);
let mut node1 = RotationState::new(true, &mut out1).unwrap(); let mut node1 = RotationState::new(true, &mut out1);
let mut node2 = RotationState::new(false, &mut out2).unwrap(); let mut node2 = RotationState::new(false, &mut out2);
let _msg1 = out1.msg().unwrap(); let _msg1 = out1.msg().unwrap();
// drop msg1 // drop msg1
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
assert!(out2.msg().is_none()); assert!(out2.msg().is_none());
// Cycle 2 // Cycle 2
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
let msg1 = out1.msg().unwrap(); let msg1 = out1.msg().unwrap();
// Message 3 // Message 3
assert!(node2.process_message(msg1).is_none()); assert!(node2.process_message(msg1).is_none());
// Cycle 3 // Cycle 3
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
let msg2 = out2.msg().unwrap(); let msg2 = out2.msg().unwrap();
// Message 4 // Message 4
assert!(node1.process_message(msg2).is_some()); assert!(node1.process_message(msg2).is_some());
@ -385,22 +386,22 @@ mod tests {
let mut out1 = MsgBuffer::new(8); let mut out1 = MsgBuffer::new(8);
let mut out2 = MsgBuffer::new(8); let mut out2 = MsgBuffer::new(8);
let mut node1 = RotationState::new(true, &mut out1).unwrap(); let mut node1 = RotationState::new(true, &mut out1);
let mut node2 = RotationState::new(false, &mut out2).unwrap(); let mut node2 = RotationState::new(false, &mut out2);
let msg1 = out1.msg().unwrap(); let msg1 = out1.msg().unwrap();
assert!(node1.process_message(msg1).is_none()); assert!(node1.process_message(msg1).is_none());
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
assert!(out2.msg().is_none()); assert!(out2.msg().is_none());
// Cycle 2 // Cycle 2
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
let msg1 = out1.msg().unwrap(); let msg1 = out1.msg().unwrap();
// Message 3 // Message 3
assert!(node2.process_message(msg1).is_none()); assert!(node2.process_message(msg1).is_none());
// Cycle 3 // Cycle 3
node1.cycle(&mut out1).unwrap(); node1.cycle(&mut out1);
node2.cycle(&mut out2).unwrap(); node2.cycle(&mut out2);
let msg2 = out2.msg().unwrap(); let msg2 = out2.msg().unwrap();
// Message 4 // Message 4
assert!(node1.process_message(msg2).is_some()); assert!(node1.process_message(msg2).is_some());

View File

@ -62,6 +62,11 @@ impl<TS: TimeSource> ClaimTable<TS> {
for claim in claims { for claim in claims {
self.claims.push(ClaimEntry { peer, claim, timeout: TS::now() + self.claim_timeout as Time }) self.claims.push(ClaimEntry { peer, claim, timeout: TS::now() + self.claim_timeout as Time })
} }
for entry in self.cache.values_mut() {
if entry.peer == peer {
entry.timeout = 0
}
}
self.housekeep() self.housekeep()
} }
@ -71,6 +76,11 @@ impl<TS: TimeSource> ClaimTable<TS> {
entry.timeout = 0 entry.timeout = 0
} }
} }
for entry in self.cache.values_mut() {
if entry.peer == peer {
entry.timeout = 0
}
}
self.housekeep() self.housekeep()
} }
@ -92,7 +102,6 @@ impl<TS: TimeSource> ClaimTable<TS> {
pub fn housekeep(&mut self) { pub fn housekeep(&mut self) {
let now = TS::now(); let now = TS::now();
// TODO: also remove cache when removing claims
self.cache.retain(|_, v| v.timeout >= now); self.cache.retain(|_, v| v.timeout >= now);
self.claims.retain(|e| e.timeout >= now); self.claims.retain(|e| e.timeout >= now);
} }