Checking of mac2 fields on initiation & response
In addition, moved the rng out. This will allow allocating one instance per worker, rather than every call.
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
use spin::RwLock;
|
use spin::RwLock;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::net::SocketAddr;
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use rand::rngs::OsRng;
|
|
||||||
|
|
||||||
use x25519_dalek::PublicKey;
|
use x25519_dalek::PublicKey;
|
||||||
use x25519_dalek::StaticSecret;
|
use x25519_dalek::StaticSecret;
|
||||||
@@ -159,15 +159,19 @@ where
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `pk` - Public key of peer to initiate handshake for
|
/// * `pk` - Public key of peer to initiate handshake for
|
||||||
pub fn begin(&self, pk: &PublicKey) -> Result<Vec<u8>, HandshakeError> {
|
pub fn begin<R: RngCore + CryptoRng>(
|
||||||
|
&self,
|
||||||
|
rng: &mut R,
|
||||||
|
pk: &PublicKey,
|
||||||
|
) -> Result<Vec<u8>, HandshakeError> {
|
||||||
match self.pk_map.get(pk.as_bytes()) {
|
match self.pk_map.get(pk.as_bytes()) {
|
||||||
None => Err(HandshakeError::UnknownPublicKey),
|
None => Err(HandshakeError::UnknownPublicKey),
|
||||||
Some(peer) => {
|
Some(peer) => {
|
||||||
let sender = self.allocate(peer);
|
let sender = self.allocate(rng, peer);
|
||||||
|
|
||||||
let mut msg = Initiation::default();
|
let mut msg = Initiation::default();
|
||||||
|
|
||||||
noise::create_initiation(self, peer, sender, &mut msg.noise)?;
|
noise::create_initiation(rng, self, peer, sender, &mut msg.noise)?;
|
||||||
|
|
||||||
// add macs to initation
|
// add macs to initation
|
||||||
|
|
||||||
@@ -185,30 +189,51 @@ where
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `msg` - Byte slice containing the message (untrusted input)
|
/// * `msg` - Byte slice containing the message (untrusted input)
|
||||||
pub fn process(&self, msg: &[u8]) -> Result<Output<T>, HandshakeError> {
|
pub fn process<R: RngCore + CryptoRng>(
|
||||||
|
&self,
|
||||||
|
rng: &mut R,
|
||||||
|
msg: &[u8], // message buffer
|
||||||
|
src: Option<&SocketAddr>, // optional source address, set when "under load"
|
||||||
|
) -> Result<Output<T>, HandshakeError> {
|
||||||
match msg.get(0) {
|
match msg.get(0) {
|
||||||
Some(&TYPE_INITIATION) => {
|
Some(&TYPE_INITIATION) => {
|
||||||
|
// parse message
|
||||||
let msg = Initiation::parse(msg)?;
|
let msg = Initiation::parse(msg)?;
|
||||||
|
|
||||||
// check mac1 field
|
// check mac1 field
|
||||||
self.macs.check_mac1(msg.noise.as_bytes(), &msg.macs)?;
|
self.macs.check_mac1(msg.noise.as_bytes(), &msg.macs)?;
|
||||||
|
|
||||||
// check ratelimiter
|
// check mac2 field
|
||||||
|
if let Some(src) = src {
|
||||||
|
if !self.macs.check_mac2(msg.noise.as_bytes(), src, &msg.macs) {
|
||||||
|
let mut reply = Default::default();
|
||||||
|
self.macs.create_cookie_reply(
|
||||||
|
rng,
|
||||||
|
msg.noise.f_sender.get(),
|
||||||
|
src,
|
||||||
|
&msg.macs,
|
||||||
|
&mut reply,
|
||||||
|
);
|
||||||
|
return Ok((None, Some(reply.as_bytes().to_owned()), None));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// consume the initiation
|
// consume the initiation
|
||||||
let (peer, st) = noise::consume_initiation(self, &msg.noise)?;
|
let (peer, st) = noise::consume_initiation(self, &msg.noise)?;
|
||||||
|
|
||||||
// allocate new index for response
|
// allocate new index for response
|
||||||
let sender = self.allocate(peer);
|
let sender = self.allocate(rng, peer);
|
||||||
|
|
||||||
// prepare memory for response, TODO: take slice for zero allocation
|
// prepare memory for response, TODO: take slice for zero allocation
|
||||||
let mut resp = Response::default();
|
let mut resp = Response::default();
|
||||||
|
|
||||||
// create response (release id on error)
|
// create response (release id on error)
|
||||||
let keys =
|
let keys = noise::create_response(rng, peer, sender, st, &mut resp.noise).map_err(
|
||||||
noise::create_response(peer, sender, st, &mut resp.noise).map_err(|e| {
|
|e| {
|
||||||
self.release(sender);
|
self.release(sender);
|
||||||
e
|
e
|
||||||
})?;
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
// add macs to response
|
// add macs to response
|
||||||
peer.macs
|
peer.macs
|
||||||
@@ -217,7 +242,7 @@ where
|
|||||||
|
|
||||||
// return unconfirmed keypair and the response as vector
|
// return unconfirmed keypair and the response as vector
|
||||||
Ok((
|
Ok((
|
||||||
peer.identifier,
|
Some(peer.identifier),
|
||||||
Some(resp.as_bytes().to_owned()),
|
Some(resp.as_bytes().to_owned()),
|
||||||
Some(keys),
|
Some(keys),
|
||||||
))
|
))
|
||||||
@@ -228,6 +253,22 @@ where
|
|||||||
// check mac1 field
|
// check mac1 field
|
||||||
self.macs.check_mac1(msg.noise.as_bytes(), &msg.macs)?;
|
self.macs.check_mac1(msg.noise.as_bytes(), &msg.macs)?;
|
||||||
|
|
||||||
|
// check mac2 field
|
||||||
|
if let Some(src) = src {
|
||||||
|
if !self.macs.check_mac2(msg.noise.as_bytes(), src, &msg.macs) {
|
||||||
|
let mut reply = Default::default();
|
||||||
|
self.macs.create_cookie_reply(
|
||||||
|
rng,
|
||||||
|
msg.noise.f_sender.get(),
|
||||||
|
src,
|
||||||
|
&msg.macs,
|
||||||
|
&mut reply,
|
||||||
|
);
|
||||||
|
return Ok((None, Some(reply.as_bytes().to_owned()), None));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// consume inner playload
|
||||||
noise::consume_response(self, &msg.noise)
|
noise::consume_response(self, &msg.noise)
|
||||||
}
|
}
|
||||||
Some(&TYPE_COOKIEREPLY) => {
|
Some(&TYPE_COOKIEREPLY) => {
|
||||||
@@ -239,8 +280,9 @@ where
|
|||||||
// validate cookie reply
|
// validate cookie reply
|
||||||
peer.macs.lock().process(&msg)?;
|
peer.macs.lock().process(&msg)?;
|
||||||
|
|
||||||
// this prompts no new message
|
// this prompts no new message and
|
||||||
Ok((peer.identifier, None, None))
|
// DOES NOT cryptographically verify the peer
|
||||||
|
Ok((None, None, None))
|
||||||
}
|
}
|
||||||
_ => Err(HandshakeError::InvalidMessageFormat),
|
_ => Err(HandshakeError::InvalidMessageFormat),
|
||||||
}
|
}
|
||||||
@@ -270,9 +312,7 @@ where
|
|||||||
// Internal function
|
// Internal function
|
||||||
//
|
//
|
||||||
// Allocated a new receiver identifier for the peer
|
// Allocated a new receiver identifier for the peer
|
||||||
fn allocate(&self, peer: &Peer<T>) -> u32 {
|
fn allocate<R: RngCore + CryptoRng>(&self, rng: &mut R, peer: &Peer<T>) -> u32 {
|
||||||
let mut rng = OsRng::new().unwrap();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let id = rng.gen();
|
let id = rng.gen();
|
||||||
|
|
||||||
@@ -296,6 +336,7 @@ mod tests {
|
|||||||
use super::super::messages::*;
|
use super::super::messages::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use hex;
|
use hex;
|
||||||
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn handshake() {
|
fn handshake() {
|
||||||
@@ -332,14 +373,14 @@ mod tests {
|
|||||||
|
|
||||||
// create initiation
|
// create initiation
|
||||||
|
|
||||||
let msg1 = dev1.begin(&pk2).unwrap();
|
let msg1 = dev1.begin(&mut rng, &pk2).unwrap();
|
||||||
|
|
||||||
println!("msg1 = {} : {} bytes", hex::encode(&msg1[..]), msg1.len());
|
println!("msg1 = {} : {} bytes", hex::encode(&msg1[..]), msg1.len());
|
||||||
println!("msg1 = {:?}", Initiation::parse(&msg1[..]).unwrap());
|
println!("msg1 = {:?}", Initiation::parse(&msg1[..]).unwrap());
|
||||||
|
|
||||||
// process initiation and create response
|
// process initiation and create response
|
||||||
|
|
||||||
let (_, msg2, ks_r) = dev2.process(&msg1).unwrap();
|
let (_, msg2, ks_r) = dev2.process(&mut rng, &msg1, None).unwrap();
|
||||||
|
|
||||||
let ks_r = ks_r.unwrap();
|
let ks_r = ks_r.unwrap();
|
||||||
let msg2 = msg2.unwrap();
|
let msg2 = msg2.unwrap();
|
||||||
@@ -351,7 +392,7 @@ mod tests {
|
|||||||
|
|
||||||
// process response and obtain confirmed key-pair
|
// process response and obtain confirmed key-pair
|
||||||
|
|
||||||
let (_, msg3, ks_i) = dev1.process(&msg2).unwrap();
|
let (_, msg3, ks_i) = dev1.process(&mut rng, &msg2, None).unwrap();
|
||||||
let ks_i = ks_i.unwrap();
|
let ks_i = ks_i.unwrap();
|
||||||
|
|
||||||
assert!(msg3.is_none(), "Returned message after response");
|
assert!(msg3.is_none(), "Returned message after response");
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
|
use rand::{CryptoRng, RngCore};
|
||||||
|
use spin::Mutex;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use rand::CryptoRng;
|
|
||||||
use rand::RngCore;
|
|
||||||
|
|
||||||
use spin::Mutex;
|
|
||||||
|
|
||||||
use blake2::Blake2s;
|
use blake2::Blake2s;
|
||||||
|
use sodiumoxide::crypto::aead::xchacha20poly1305_ietf;
|
||||||
use subtle::ConstantTimeEq;
|
use subtle::ConstantTimeEq;
|
||||||
use x25519_dalek::PublicKey;
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
use sodiumoxide::crypto::aead::xchacha20poly1305_ietf;
|
use std::net::SocketAddr;
|
||||||
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
use super::messages::{CookieReply, MacsFooter};
|
use super::messages::{CookieReply, MacsFooter};
|
||||||
use super::types::HandshakeError;
|
use super::types::HandshakeError;
|
||||||
@@ -100,6 +99,23 @@ pub struct Generator {
|
|||||||
cookie: Option<Cookie>,
|
cookie: Option<Cookie>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn addr_to_mac_bytes(addr: &SocketAddr) -> Vec<u8> {
|
||||||
|
match addr {
|
||||||
|
SocketAddr::V4(addr) => {
|
||||||
|
let mut res = Vec::with_capacity(4 + 2);
|
||||||
|
res.extend(&addr.ip().octets());
|
||||||
|
res.extend(&addr.port().to_le_bytes());
|
||||||
|
res
|
||||||
|
}
|
||||||
|
SocketAddr::V6(addr) => {
|
||||||
|
let mut res = Vec::with_capacity(16 + 2);
|
||||||
|
res.extend(&addr.ip().octets());
|
||||||
|
res.extend(&addr.port().to_le_bytes());
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Generator {
|
impl Generator {
|
||||||
/// Initalize a new mac field generator
|
/// Initalize a new mac field generator
|
||||||
///
|
///
|
||||||
@@ -193,12 +209,12 @@ impl Validator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tau(&self, src: &[u8]) -> Result<[u8; SIZE_COOKIE], HandshakeError> {
|
fn get_tau(&self, src: &[u8]) -> Option<[u8; SIZE_COOKIE]> {
|
||||||
let secret = self.secret.lock();
|
let secret = self.secret.lock();
|
||||||
if secret.birth.elapsed() < Duration::from_secs(SECS_COOKIE_UPDATE) {
|
if secret.birth.elapsed() < Duration::from_secs(SECS_COOKIE_UPDATE) {
|
||||||
Ok(MAC!(&secret.value, src))
|
Some(MAC!(&secret.value, src))
|
||||||
} else {
|
} else {
|
||||||
Err(HandshakeError::InvalidMac2)
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,25 +235,26 @@ impl Validator {
|
|||||||
MAC!(&secret.value, src)
|
MAC!(&secret.value, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_cookie_reply<T>(
|
pub fn create_cookie_reply<T>(
|
||||||
&self,
|
&self,
|
||||||
rng: &mut T,
|
rng: &mut T,
|
||||||
receiver: u32, // receiver id of incoming message
|
receiver: u32, // receiver id of incoming message
|
||||||
src: &[u8], // source address of incoming message
|
src: &SocketAddr, // source address of incoming message
|
||||||
macs: &MacsFooter, // footer of incoming message
|
macs: &MacsFooter, // footer of incoming message
|
||||||
msg: &mut CookieReply, // resulting cookie reply
|
msg: &mut CookieReply, // resulting cookie reply
|
||||||
) where
|
) where
|
||||||
T: RngCore + CryptoRng,
|
T: RngCore + CryptoRng,
|
||||||
{
|
{
|
||||||
|
let src = addr_to_mac_bytes(src);
|
||||||
msg.f_receiver.set(receiver);
|
msg.f_receiver.set(receiver);
|
||||||
rng.fill_bytes(&mut msg.f_nonce);
|
rng.fill_bytes(&mut msg.f_nonce);
|
||||||
XSEAL!(
|
XSEAL!(
|
||||||
&self.cookie_key, // key
|
&self.cookie_key, // key
|
||||||
&msg.f_nonce, // nonce
|
&msg.f_nonce, // nonce
|
||||||
&macs.f_mac1, // ad
|
&macs.f_mac1, // ad
|
||||||
&self.get_set_tau(rng, src), // pt
|
&self.get_set_tau(rng, &src), // pt
|
||||||
&mut msg.f_cookie, // ct
|
&mut msg.f_cookie, // ct
|
||||||
&mut msg.f_cookie_tag // tag
|
&mut msg.f_cookie_tag // tagf
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,25 +273,11 @@ impl Validator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check the mac2 field against the inner message
|
pub fn check_mac2(&self, inner: &[u8], src: &SocketAddr, macs: &MacsFooter) -> bool {
|
||||||
///
|
let src = addr_to_mac_bytes(src);
|
||||||
/// # Arguments
|
match self.get_tau(&src) {
|
||||||
///
|
Some(tau) => MAC!(&tau, inner, macs.f_mac1).ct_eq(&macs.f_mac2).into(),
|
||||||
/// - inner: The inner message covered by the mac1 field
|
None => false,
|
||||||
/// - src: Source address
|
|
||||||
/// - macs: The mac footer
|
|
||||||
pub fn check_mac2(
|
|
||||||
&self,
|
|
||||||
inner: &[u8],
|
|
||||||
src: &[u8],
|
|
||||||
macs: &MacsFooter,
|
|
||||||
) -> Result<(), HandshakeError> {
|
|
||||||
let tau = self.get_tau(src)?;
|
|
||||||
let valid_mac2: bool = MAC!(&tau, inner, macs.f_mac1).ct_eq(&macs.f_mac2).into();
|
|
||||||
if !valid_mac2 {
|
|
||||||
Err(HandshakeError::InvalidMac2)
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,10 +298,11 @@ mod tests {
|
|||||||
|
|
||||||
proptest! {
|
proptest! {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_reply(inner1 : Vec<u8>, inner2 : Vec<u8>, src: Vec<u8>, receiver : u32) {
|
fn test_cookie_reply(inner1 : Vec<u8>, inner2 : Vec<u8>, receiver : u32) {
|
||||||
let mut msg = CookieReply::default();
|
let mut msg = CookieReply::default();
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng::new().expect("failed to create rng");
|
||||||
let mut macs = MacsFooter::default();
|
let mut macs = MacsFooter::default();
|
||||||
|
let src = "127.0.0.1:8080".parse().unwrap();
|
||||||
let (validator, mut generator) = new_validator_generator();
|
let (validator, mut generator) = new_validator_generator();
|
||||||
|
|
||||||
// generate mac1 for first message
|
// generate mac1 for first message
|
||||||
@@ -308,10 +312,8 @@ mod tests {
|
|||||||
|
|
||||||
// check validity of mac1
|
// check validity of mac1
|
||||||
validator.check_mac1(&inner1[..], &macs).expect("mac1 of inner1 did not validate");
|
validator.check_mac1(&inner1[..], &macs).expect("mac1 of inner1 did not validate");
|
||||||
|
assert_eq!(validator.check_mac2(&inner1[..], &src, &macs), false, "mac2 of inner2 did not validate");
|
||||||
// generate cookie reply in response
|
validator.create_cookie_reply(&mut rng, receiver, &src, &macs, &mut msg);
|
||||||
validator.create_cookie_reply(&mut rng, receiver, &src[..], &macs, &mut msg);
|
|
||||||
assert_eq!(msg.f_receiver.get(), receiver);
|
|
||||||
|
|
||||||
// consume cookie reply
|
// consume cookie reply
|
||||||
generator.process(&msg).expect("failed to process CookieReply");
|
generator.process(&msg).expect("failed to process CookieReply");
|
||||||
@@ -323,7 +325,7 @@ mod tests {
|
|||||||
|
|
||||||
// check validity of mac1 and mac2
|
// check validity of mac1 and mac2
|
||||||
validator.check_mac1(&inner2[..], &macs).expect("mac1 of inner2 did not validate");
|
validator.check_mac1(&inner2[..], &macs).expect("mac1 of inner2 did not validate");
|
||||||
validator.check_mac2(&inner2[..], &src[..], &macs).expect("mac2 of inner2 did not validate");
|
assert!(validator.check_mac2(&inner2[..], &src, &macs), "mac2 of inner2 did not validate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use hmac::Hmac;
|
|||||||
use sodiumoxide::crypto::aead::chacha20poly1305;
|
use sodiumoxide::crypto::aead::chacha20poly1305;
|
||||||
|
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
|
use rand::{CryptoRng, RngCore};
|
||||||
|
|
||||||
use generic_array::typenum::*;
|
use generic_array::typenum::*;
|
||||||
use generic_array::GenericArray;
|
use generic_array::GenericArray;
|
||||||
@@ -165,14 +166,13 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_initiation<T: Copy>(
|
pub fn create_initiation<T: Copy, R: RngCore + CryptoRng>(
|
||||||
|
rng: &mut R,
|
||||||
device: &Device<T>,
|
device: &Device<T>,
|
||||||
peer: &Peer<T>,
|
peer: &Peer<T>,
|
||||||
sender: u32,
|
sender: u32,
|
||||||
msg: &mut NoiseInitiation,
|
msg: &mut NoiseInitiation,
|
||||||
) -> Result<(), HandshakeError> {
|
) -> Result<(), HandshakeError> {
|
||||||
let mut rng = OsRng::new().unwrap();
|
|
||||||
|
|
||||||
// initialize state
|
// initialize state
|
||||||
|
|
||||||
let ck = INITIAL_CK;
|
let ck = INITIAL_CK;
|
||||||
@@ -183,7 +183,7 @@ pub fn create_initiation<T: Copy>(
|
|||||||
|
|
||||||
// (E_priv, E_pub) := DH-Generate()
|
// (E_priv, E_pub) := DH-Generate()
|
||||||
|
|
||||||
let eph_sk = StaticSecret::new(&mut rng);
|
let eph_sk = StaticSecret::new(rng);
|
||||||
let eph_pk = PublicKey::from(&eph_sk);
|
let eph_pk = PublicKey::from(&eph_sk);
|
||||||
|
|
||||||
// C := Kdf(C, E_pub)
|
// C := Kdf(C, E_pub)
|
||||||
@@ -316,20 +316,23 @@ pub fn consume_initiation<'a, T: Copy>(
|
|||||||
Ok((peer, (msg.f_sender.get(), eph_r_pk, hs, ck)))
|
Ok((peer, (msg.f_sender.get(), eph_r_pk, hs, ck)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_response<T: Copy>(
|
pub fn create_response<T: Copy, R: RngCore + CryptoRng>(
|
||||||
|
rng: &mut R,
|
||||||
peer: &Peer<T>,
|
peer: &Peer<T>,
|
||||||
sender: u32, // sending identifier
|
sender: u32, // sending identifier
|
||||||
state: TemporaryState, // state from "consume_initiation"
|
state: TemporaryState, // state from "consume_initiation"
|
||||||
msg: &mut NoiseResponse, // resulting response
|
msg: &mut NoiseResponse, // resulting response
|
||||||
) -> Result<KeyPair, HandshakeError> {
|
) -> Result<KeyPair, HandshakeError> {
|
||||||
|
|
||||||
|
// unpack state
|
||||||
|
|
||||||
let (receiver, eph_r_pk, hs, ck) = state;
|
let (receiver, eph_r_pk, hs, ck) = state;
|
||||||
let mut rng = OsRng::new().unwrap();
|
|
||||||
msg.f_sender.set(sender);
|
msg.f_sender.set(sender);
|
||||||
msg.f_receiver.set(receiver);
|
msg.f_receiver.set(receiver);
|
||||||
|
|
||||||
// (E_priv, E_pub) := DH-Generate()
|
// (E_priv, E_pub) := DH-Generate()
|
||||||
|
|
||||||
let eph_sk = StaticSecret::new(&mut rng);
|
let eph_sk = StaticSecret::new(rng);
|
||||||
let eph_pk = PublicKey::from(&eph_sk);
|
let eph_pk = PublicKey::from(&eph_sk);
|
||||||
|
|
||||||
// C := Kdf1(C, E_pub)
|
// C := Kdf1(C, E_pub)
|
||||||
@@ -454,8 +457,8 @@ pub fn consume_response<T: Copy>(
|
|||||||
// return confirmed key-pair
|
// return confirmed key-pair
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
peer.identifier,
|
Some(peer.identifier), // proves overship of the public key (e.g. for updating the endpoint)
|
||||||
None,
|
None, // no response message
|
||||||
Some(KeyPair {
|
Some(KeyPair {
|
||||||
confirmed: true,
|
confirmed: true,
|
||||||
send: Key {
|
send: Key {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
|||||||
|
|
||||||
pub type TAI64N = [u8; 12];
|
pub type TAI64N = [u8; 12];
|
||||||
|
|
||||||
const TAI64_EPOCH: u64 = 0x4000000000000000;
|
const TAI64_EPOCH: u64 = 0x400000000000000a;
|
||||||
|
|
||||||
pub const ZERO: TAI64N = [0u8; 12];
|
pub const ZERO: TAI64N = [0u8; 12];
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ pub enum HandshakeError {
|
|||||||
OldTimestamp,
|
OldTimestamp,
|
||||||
InvalidState,
|
InvalidState,
|
||||||
InvalidMac1,
|
InvalidMac1,
|
||||||
InvalidMac2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for HandshakeError {
|
impl fmt::Display for HandshakeError {
|
||||||
@@ -58,7 +57,6 @@ impl fmt::Display for HandshakeError {
|
|||||||
HandshakeError::OldTimestamp => write!(f, "Timestamp is less/equal to the newest"),
|
HandshakeError::OldTimestamp => write!(f, "Timestamp is less/equal to the newest"),
|
||||||
HandshakeError::InvalidState => write!(f, "Message does not apply to handshake state"),
|
HandshakeError::InvalidState => write!(f, "Message does not apply to handshake state"),
|
||||||
HandshakeError::InvalidMac1 => write!(f, "Message has invalid mac1 field"),
|
HandshakeError::InvalidMac1 => write!(f, "Message has invalid mac1 field"),
|
||||||
HandshakeError::InvalidMac2 => write!(f, "Message has invalid mac2 field"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,8 +72,7 @@ impl Error for HandshakeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type Output<T> = (
|
pub type Output<T> = (
|
||||||
T, // external identifier associated with peer
|
Option<T>, // external identifier associated with peer
|
||||||
// (e.g. a reference or vector index)
|
|
||||||
Option<Vec<u8>>, // message to send
|
Option<Vec<u8>>, // message to send
|
||||||
Option<KeyPair>, // resulting key-pair of successful handshake
|
Option<KeyPair>, // resulting key-pair of successful handshake
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user