elaeis4/quicktap/src/noise/handshake/mod.rs
2022-12-15 10:55:22 -05:00

86 lines
No EOL
2.8 KiB
Rust

//! `Noise_IKpsk2` handshake, specifically the way WireGuard defines it
use std::fmt::{Debug, Formatter};
use tai64::Tai64N;
use x25519_dalek::{EphemeralSecret, PublicKey, StaticSecret};
use crate::qcrypto::timestamp;
pub mod initiator;
pub mod response;
#[cfg(test)]
pub mod tests;
/// The Blake2s hash of the construction
pub const HANDSHAKE_INITIATOR_CHAIN_KEY: [u8; 32] = [
96, 226, 109, 174, 243, 39, 239, 192, 46, 195, 53, 226, 160, 37, 210, 208, 22, 235, 66, 6, 248,
114, 119, 245, 45, 56, 209, 152, 139, 120, 205, 54,
];
/// The hashed chaining key
pub const HANDSHAKE_INITIATOR_CHAIN_KEY_HASH: [u8; 32] = [
34, 17, 179, 97, 8, 26, 197, 102, 105, 18, 67, 219, 69, 138, 213, 50, 45, 156, 108, 102, 34,
147, 232, 183, 14, 225, 156, 101, 186, 7, 158, 243,
];
/// Represents a cookie we got from the other peer
#[derive(Debug)]
pub struct Cookie {
time: Tai64N,
cookie: [u8; 16]
}
/// Represents the internal handshake state. This does not really need to be messed with by outside users
#[allow(missing_docs)]
#[allow(clippy::module_name_repetitions)]
pub struct HandshakeState {
pub h: [u8; 32],
pub ck: [u8; 32],
pub e_pub_i: PublicKey,
pub s_pub_i: PublicKey,
pub s_pub_r: PublicKey,
pub e_priv_me: EphemeralSecret,
pub s_priv_me: StaticSecret,
pub s_pub_them: PublicKey,
pub i_i: u32,
pub i_r: u32,
pub cookies: Vec<Cookie>
}
impl HandshakeState {
/// Determines if the state variables of this `HandshakeState` are the same as another
#[allow(clippy::suspicious_operation_groupings)]
pub fn is_eq(&self, other: &HandshakeState) -> bool {
self.h == other.h && self.ck == other.ck && self.e_pub_i == other.e_pub_i && self.s_pub_i == other.s_pub_i && self.s_pub_r == other.s_pub_r && self.i_i == other.i_i && self.i_r == other.i_r
}
}
impl Debug for HandshakeState {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("HandshakeState")
.field("h", &self.h)
.field("ck", &self.ck)
.field("e_pub_i", &self.e_pub_i)
.field("s_pub_i", &self.s_pub_i)
.field("s_pub_r", &self.s_pub_r)
.field("e_priv_me", &"<redacted>")
.field("s_priv_me", &"<redacted>")
.field("s_pub_them", &self.s_pub_them)
.field("i_i", &self.i_i)
.field("i_r", &self.i_r)
.field("cookies", &self.cookies).finish()
}
}
/// Determines if a cookie MAC needs to be added to the packet being sent
pub fn needs_cookie(session: &HandshakeState) -> bool {
if !session.cookies.is_empty() {
let past_cookie_timeout = session.cookies[session.cookies.len()-1].time.duration_since(&timestamp()).map_or(true, |t| t.as_secs() >= 120);
if !past_cookie_timeout {
return true;
}
}
false
}