&sig)?;
let w = write_packet(self, &mut buf, struct_as_slice(&pkt),
PacketType::ServerHandshake)?;
+ increment_nonce(&mut self.local_key.nonce);
self.state = ConnectionState::ServerWaitAuthentication(std::time::SystemTime::now());
w
},
&sig)?;
let w = write_packet(self, &mut buf, struct_as_slice(&pkt),
PacketType::ClientAuthentication)?;
+ increment_nonce(&mut self.local_key.nonce);
self.state = ConnectionState::Encrypted;
w
},
signature: Some(sig),
secret_key: None,
};
+ let _ = self.remote_key.as_mut().map(|k| increment_nonce(&mut k.nonce));
self.state = ConnectionState::ClientSendAuthentication;
}
}
}
self.remote_auth.signature = Some(sig);
self.remote_auth.public_key = Some(pubkey);
+ let _ = self.remote_key.as_mut().map(|k| increment_nonce(&mut k.nonce));
self.state = ConnectionState::Encrypted;
}
}
//
// TODO
-// - Increment nonce on each encryption/decryption:
// - server certificate (TOFU)
// - consider all unexpected packet types to be errors
// - ensure that a reset on one end always sends a reset to the other
Ok(s)
}
+fn increment_nonce(nonce: &mut [u8]) -> bool {
+ let wrapped = nonce.iter_mut().rev().fold(1, |acc, x| {
+ let (val,carry) = x.overflowing_add(acc);
+ *x = val;
+ carry as u8
+ });
+ wrapped != 0
+}
+
/// Cast the data bytes in a NetworkPacket into a struct, and also return the
/// remaining unused bytes if the data is larger than the struct.
fn interpret_packet_extra<'a, T>(pkt: &'a NetworkPacket)
];
let _ = conn.set_authorized_keys(keys.iter().map(|x| x.as_slice())).unwrap();
}
-
}