Formatting

This commit is contained in:
Mathias Hall-Andersen
2019-07-25 22:04:35 +02:00
parent 27f8fd8e34
commit 43b56dfb58
7 changed files with 328 additions and 383 deletions

View File

@@ -7,23 +7,26 @@ use rand::rngs::OsRng;
use x25519_dalek::PublicKey;
use x25519_dalek::StaticSecret;
use crate::noise;
use crate::messages;
use crate::types::*;
use crate::noise;
use crate::peer::Peer;
use crate::types::*;
pub struct Device<T> {
pub sk: StaticSecret, // static secret key
pub pk: PublicKey, // static public key
peers: Vec<Peer<T>>, // peer index -> state
pk_map: HashMap<[u8; 32], usize>, // public key -> peer index
id_map : RwLock<HashMap<u32, usize>> // receive ids -> peer index
id_map: RwLock<HashMap<u32, usize>>, // receive ids -> peer index
}
/* A mutable reference to the device needs to be held during configuration.
* Wrapping the device in a RwLock enables peer config after "configuration time"
*/
impl <T>Device<T> where T : Copy {
impl<T> Device<T>
where
T: Copy,
{
/// Initialize a new handshake state machine
///
/// # Arguments
@@ -35,7 +38,7 @@ impl <T>Device<T> where T : Copy {
sk: sk,
peers: vec![],
pk_map: HashMap::new(),
id_map : RwLock::new(HashMap::new())
id_map: RwLock::new(HashMap::new()),
}
}
@@ -56,7 +59,9 @@ impl <T>Device<T> where T : Copy {
// check that the pk is not that of the device
if *self.pk.as_bytes() == *pk.as_bytes() {
return Err(ConfigError::new("Public key corresponds to secret key of interface"));
return Err(ConfigError::new(
"Public key corresponds to secret key of interface",
));
}
// map : pk -> new index
@@ -66,9 +71,8 @@ impl <T>Device<T> where T : Copy {
// map : new index -> peer
self.peers.push(Peer::new(
idx, identifier, pk, self.sk.diffie_hellman(&pk)
));
self.peers
.push(Peer::new(idx, identifier, pk, self.sk.diffie_hellman(&pk)));
Ok(())
}
@@ -92,8 +96,8 @@ impl <T>Device<T> where T : Copy {
None => [0u8; 32],
};
Ok(())
},
_ => Err(ConfigError::new("No such public key"))
}
_ => Err(ConfigError::new("No such public key")),
}
}
@@ -143,10 +147,9 @@ impl <T>Device<T> where T : Copy {
self.release(sender);
e
})
},
Some(&messages::TYPE_RESPONSE) =>
noise::consume_response(self, msg),
_ => Err(HandshakeError::InvalidMessageFormat)
}
Some(&messages::TYPE_RESPONSE) => noise::consume_response(self, msg),
_ => Err(HandshakeError::InvalidMessageFormat),
}
}
@@ -156,7 +159,7 @@ impl <T>Device<T> where T : Copy {
pub(crate) fn lookup_pk(&self, pk: &PublicKey) -> Result<&Peer<T>, HandshakeError> {
match self.pk_map.get(pk.as_bytes()) {
Some(&idx) => Ok(&self.peers[idx]),
_ => Err(HandshakeError::UnknownPublicKey)
_ => Err(HandshakeError::UnknownPublicKey),
}
}
@@ -166,7 +169,7 @@ impl <T>Device<T> where T : Copy {
pub(crate) fn lookup_id(&self, id: u32) -> Result<&Peer<T>, HandshakeError> {
match self.id_map.read().get(&id) {
Some(&idx) => Ok(&self.peers[idx]),
_ => Err(HandshakeError::UnknownReceiverId)
_ => Err(HandshakeError::UnknownReceiverId),
}
}
@@ -181,7 +184,7 @@ impl <T>Device<T> where T : Copy {
// check membership with read lock
if self.id_map.read().contains_key(&id) {
continue
continue;
}
// take write lock and add index
@@ -196,8 +199,8 @@ impl <T>Device<T> where T : Copy {
#[cfg(test)]
mod tests {
use hex;
use super::*;
use hex;
use messages::*;
use std::convert::TryFrom;
@@ -224,7 +227,6 @@ mod tests {
// do a few handshakes
for i in 0..10 {
println!("handshake : {}", i);
// create initiation

View File

@@ -1,9 +1,9 @@
mod types;
mod noise;
mod messages;
mod peer;
mod device;
mod messages;
mod noise;
mod peer;
mod timestamp;
mod types;
// publicly exposed interface

View File

@@ -1,8 +1,8 @@
use hex;
use std::mem;
use std::fmt;
use std::convert::TryFrom;
use crate::types::*;
use hex;
use std::convert::TryFrom;
use std::fmt;
use std::mem;
const SIZE_TAG: usize = 16;
const SIZE_X25519_POINT: usize = 32;
@@ -30,11 +30,9 @@ pub struct Initiation {
}
impl TryFrom<&[u8]> for Initiation {
type Error = HandshakeError;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
// check length of slice matches message
if value.len() != mem::size_of::<Self>() {
@@ -77,9 +75,7 @@ impl Into<Vec<u8>> for Initiation {
// cast to array
let array: [u8; mem::size_of::<Self>()];
unsafe {
array = mem::transmute::<Self, [u8; mem::size_of::<Self>()]>(msg)
};
unsafe { array = mem::transmute::<Self, [u8; mem::size_of::<Self>()]>(msg) };
array.to_vec()
}
@@ -94,7 +90,7 @@ impl Default for Initiation {
f_static: [0u8; SIZE_X25519_POINT],
f_static_tag: [0u8; SIZE_TAG],
f_timestamp: [0u8; SIZE_TIMESTAMP],
f_timestamp_tag : [0u8; SIZE_TAG]
f_timestamp_tag: [0u8; SIZE_TAG],
}
}
}
@@ -117,13 +113,13 @@ impl fmt::Debug for Initiation {
#[cfg(test)]
impl PartialEq for Initiation {
fn eq(&self, other: &Self) -> bool {
self.f_type == other.f_type &&
self.f_sender == other.f_sender &&
self.f_ephemeral[..] == other.f_ephemeral[..] &&
self.f_static[..] == other.f_static[..] &&
self.f_static_tag[..] == other.f_static_tag[..] &&
self.f_timestamp[..] == other.f_timestamp &&
self.f_timestamp_tag[..] == other.f_timestamp_tag
self.f_type == other.f_type
&& self.f_sender == other.f_sender
&& self.f_ephemeral[..] == other.f_ephemeral[..]
&& self.f_static[..] == other.f_static[..]
&& self.f_static_tag[..] == other.f_static_tag[..]
&& self.f_timestamp[..] == other.f_timestamp
&& self.f_timestamp_tag[..] == other.f_timestamp_tag
}
}
@@ -141,11 +137,9 @@ pub struct Response {
}
impl TryFrom<&[u8]> for Response {
type Error = HandshakeError;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
// check length of slice matches message
if value.len() != mem::size_of::<Self>() {
@@ -190,9 +184,7 @@ impl Into<Vec<u8>> for Response {
// cast to array
let array: [u8; mem::size_of::<Self>()];
unsafe {
array = mem::transmute::<Self, [u8; mem::size_of::<Self>()]>(msg)
};
unsafe { array = mem::transmute::<Self, [u8; mem::size_of::<Self>()]>(msg) };
array.to_vec()
}
@@ -205,7 +197,7 @@ impl Default for Response {
f_sender: 0,
f_receiver: 0,
f_ephemeral: [0u8; SIZE_X25519_POINT],
f_empty_tag : [0u8; SIZE_TAG]
f_empty_tag: [0u8; SIZE_TAG],
}
}
}
@@ -226,11 +218,11 @@ impl fmt::Debug for Response {
#[cfg(test)]
impl PartialEq for Response {
fn eq(&self, other: &Self) -> bool {
self.f_type == other.f_type &&
self.f_sender == other.f_sender &&
self.f_receiver == other.f_receiver &&
self.f_ephemeral == other.f_ephemeral &&
self.f_empty_tag == other.f_empty_tag
self.f_type == other.f_type
&& self.f_sender == other.f_sender
&& self.f_receiver == other.f_receiver
&& self.f_ephemeral == other.f_ephemeral
&& self.f_empty_tag == other.f_empty_tag
}
}
@@ -245,14 +237,13 @@ mod tests {
msg.f_sender = 146252;
msg.f_receiver = 554442;
msg.f_ephemeral = [
0xc1, 0x66, 0x0a, 0x0c, 0xdc, 0x0f, 0x6c, 0x51,
0x0f, 0xc2, 0xcc, 0x51, 0x52, 0x0c, 0xde, 0x1e,
0xf7, 0xf1, 0xca, 0x90, 0x86, 0x72, 0xad, 0x67,
0xea, 0x89, 0x45, 0x44, 0x13, 0x56, 0x52, 0x1f
0xc1, 0x66, 0x0a, 0x0c, 0xdc, 0x0f, 0x6c, 0x51, 0x0f, 0xc2, 0xcc, 0x51, 0x52, 0x0c,
0xde, 0x1e, 0xf7, 0xf1, 0xca, 0x90, 0x86, 0x72, 0xad, 0x67, 0xea, 0x89, 0x45, 0x44,
0x13, 0x56, 0x52, 0x1f,
];
msg.f_empty_tag = [
0x60, 0x0e, 0x1e, 0x95, 0x41, 0x6b, 0x52, 0x05,
0xa2, 0x09, 0xe1, 0xbf, 0x40, 0x05, 0x2f, 0xde
0x60, 0x0e, 0x1e, 0x95, 0x41, 0x6b, 0x52, 0x05, 0xa2, 0x09, 0xe1, 0xbf, 0x40, 0x05,
0x2f, 0xde,
];
let buf: Vec<u8> = msg.into();
@@ -266,28 +257,25 @@ mod tests {
msg.f_sender = 575757;
msg.f_ephemeral = [
0xc1, 0x66, 0x0a, 0x0c, 0xdc, 0x0f, 0x6c, 0x51,
0x0f, 0xc2, 0xcc, 0x51, 0x52, 0x0c, 0xde, 0x1e,
0xf7, 0xf1, 0xca, 0x90, 0x86, 0x72, 0xad, 0x67,
0xea, 0x89, 0x45, 0x44, 0x13, 0x56, 0x52, 0x1f
0xc1, 0x66, 0x0a, 0x0c, 0xdc, 0x0f, 0x6c, 0x51, 0x0f, 0xc2, 0xcc, 0x51, 0x52, 0x0c,
0xde, 0x1e, 0xf7, 0xf1, 0xca, 0x90, 0x86, 0x72, 0xad, 0x67, 0xea, 0x89, 0x45, 0x44,
0x13, 0x56, 0x52, 0x1f,
];
msg.f_static = [
0xdc, 0x33, 0x90, 0x15, 0x8f, 0x82, 0x3e, 0x06,
0x44, 0xa0, 0xde, 0x4c, 0x15, 0x6c, 0x5d, 0xa4,
0x65, 0x99, 0xf6, 0x6c, 0xa1, 0x14, 0x77, 0xf9,
0xeb, 0x6a, 0xec, 0xc3, 0x3c, 0xda, 0x47, 0xe1
0xdc, 0x33, 0x90, 0x15, 0x8f, 0x82, 0x3e, 0x06, 0x44, 0xa0, 0xde, 0x4c, 0x15, 0x6c,
0x5d, 0xa4, 0x65, 0x99, 0xf6, 0x6c, 0xa1, 0x14, 0x77, 0xf9, 0xeb, 0x6a, 0xec, 0xc3,
0x3c, 0xda, 0x47, 0xe1,
];
msg.f_static_tag = [
0x45, 0xac, 0x8d, 0x43, 0xea, 0x1b, 0x2f, 0x02,
0x45, 0x5d, 0x86, 0x37, 0xee, 0x83, 0x6b, 0x42
0x45, 0xac, 0x8d, 0x43, 0xea, 0x1b, 0x2f, 0x02, 0x45, 0x5d, 0x86, 0x37, 0xee, 0x83,
0x6b, 0x42,
];
msg.f_timestamp = [
0x4f, 0x1c, 0x60, 0xec, 0x0e, 0xf6, 0x36, 0xf0,
0x78, 0x28, 0x57, 0x42
0x4f, 0x1c, 0x60, 0xec, 0x0e, 0xf6, 0x36, 0xf0, 0x78, 0x28, 0x57, 0x42,
];
msg.f_timestamp_tag = [
0x60, 0x0e, 0x1e, 0x95, 0x41, 0x6b, 0x52, 0x05,
0xa2, 0x09, 0xe1, 0xbf, 0x40, 0x05, 0x2f, 0xde
0x60, 0x0e, 0x1e, 0x95, 0x41, 0x6b, 0x52, 0x05, 0xa2, 0x09, 0xe1, 0xbf, 0x40, 0x05,
0x2f, 0xde,
];
let buf: Vec<u8> = msg.into();

View File

@@ -5,23 +5,23 @@ use x25519_dalek::PublicKey;
use x25519_dalek::StaticSecret;
// HASH & MAC
use hmac::{Mac, Hmac};
use blake2::{Blake2s, Digest};
use blake2::Blake2s;
use hmac::Hmac;
// AEAD
use crypto::aead::{AeadDecryptor, AeadEncryptor};
use crypto::chacha20poly1305::ChaCha20Poly1305;
use crypto::aead::{AeadEncryptor,AeadDecryptor};
use rand::rngs::OsRng;
use generic_array::typenum::*;
use generic_array::GenericArray;
use crate::types::*;
use crate::peer::{State, Peer};
use crate::device::Device;
use crate::messages::{Initiation, Response};
use crate::peer::{Peer, State};
use crate::timestamp;
use crate::types::*;
// HMAC hasher (generic construction)
@@ -37,130 +37,83 @@ const SIZE_NONCE : usize = 8;
// C := Hash(Construction)
const INITIAL_CK: [u8; SIZE_CK] = [
0x60, 0xe2, 0x6d, 0xae, 0xf3, 0x27, 0xef, 0xc0,
0x2e, 0xc3, 0x35, 0xe2, 0xa0, 0x25, 0xd2, 0xd0,
0x16, 0xeb, 0x42, 0x06, 0xf8, 0x72, 0x77, 0xf5,
0x2d, 0x38, 0xd1, 0x98, 0x8b, 0x78, 0xcd, 0x36
0x60, 0xe2, 0x6d, 0xae, 0xf3, 0x27, 0xef, 0xc0, 0x2e, 0xc3, 0x35, 0xe2, 0xa0, 0x25, 0xd2, 0xd0,
0x16, 0xeb, 0x42, 0x06, 0xf8, 0x72, 0x77, 0xf5, 0x2d, 0x38, 0xd1, 0x98, 0x8b, 0x78, 0xcd, 0x36,
];
// H := Hash(C || Identifier)
const INITIAL_HS: [u8; SIZE_HS] = [
0x22, 0x11, 0xb3, 0x61, 0x08, 0x1a, 0xc5, 0x66,
0x69, 0x12, 0x43, 0xdb, 0x45, 0x8a, 0xd5, 0x32,
0x2d, 0x9c, 0x6c, 0x66, 0x22, 0x93, 0xe8, 0xb7,
0x0e, 0xe1, 0x9c, 0x65, 0xba, 0x07, 0x9e, 0xf3
0x22, 0x11, 0xb3, 0x61, 0x08, 0x1a, 0xc5, 0x66, 0x69, 0x12, 0x43, 0xdb, 0x45, 0x8a, 0xd5, 0x32,
0x2d, 0x9c, 0x6c, 0x66, 0x22, 0x93, 0xe8, 0xb7, 0x0e, 0xe1, 0x9c, 0x65, 0xba, 0x07, 0x9e, 0xf3,
];
const ZERO_NONCE : [u8; SIZE_NONCE] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
];
const ZERO_NONCE: [u8; SIZE_NONCE] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
macro_rules! HASH {
($input1:expr) => {
{
let mut hsh = <Blake2s as Digest>::new();
Digest::input(&mut hsh, $input1);
Digest::result(hsh)
}
};
($input1:expr, $input2:expr) => {
{
let mut hsh = <Blake2s as Digest>::new();
Digest::input(&mut hsh, $input1);
Digest::input(&mut hsh, $input2);
Digest::result(hsh)
}
};
($input1:expr, $input2:expr, $input3:expr) => {
{
let mut hsh = <Blake2s as Digest>::new();
Digest::input(&mut hsh, $input1);
Digest::input(&mut hsh, $input2);
Digest::input(&mut hsh, $input3);
Digest::result(hsh)
}
};
( $($input:expr),* ) => {{
use blake2::Digest;
let mut hsh = Blake2s::new();
$(
hsh.input($input);
)*
hsh.result()
}};
}
macro_rules! HMAC {
($key:expr, $input1:expr) => {
{
// let mut mac = HMACBlake2s::new($key);
($key:expr, $($input:expr),*) => {{
use hmac::Mac;
let mut mac = HMACBlake2s::new_varkey($key).unwrap();
mac.input($input1);
$(
mac.input($input);
)*
mac.result().code()
}
};
($key:expr, $input1:expr, $input2:expr) => {
{
let mut mac = HMACBlake2s::new_varkey($key).unwrap();
mac.input($input1);
mac.input($input2);
mac.result().code()
}
};
}};
}
macro_rules! KDF1 {
($ck:expr, $input:expr) => {
{
($ck:expr, $input:expr) => {{
let t0 = HMAC!($ck, $input);
let t1 = HMAC!(&t0, &[0x1]);
t1
}
}
}};
}
macro_rules! KDF2 {
($ck:expr, $input:expr) => {
{
($ck:expr, $input:expr) => {{
let t0 = HMAC!($ck, $input);
let t1 = HMAC!(&t0, &[0x1]);
let t2 = HMAC!(&t0, &t1, &[0x2]);
(t1, t2)
}
}
}};
}
macro_rules! KDF3 {
($ck:expr, $input:expr) => {
{
($ck:expr, $input:expr) => {{
let t0 = HMAC!($ck, $input);
let t1 = HMAC!(&t0, &[0x1]);
let t2 = HMAC!(&t0, &t1, &[0x2]);
let t3 = HMAC!(&t0, &t2, &[0x3]);
(t1, t2, t3)
}
}
}};
}
macro_rules! SEAL {
($key:expr, $aead:expr, $pt:expr, $ct:expr, $tag:expr) => {
{
($key:expr, $aead:expr, $pt:expr, $ct:expr, $tag:expr) => {{
let mut aead = ChaCha20Poly1305::new($key, &ZERO_NONCE, $aead);
aead.encrypt(
$pt,
$ct,
$tag
);
}
}
aead.encrypt($pt, $ct, $tag);
}};
}
macro_rules! OPEN {
($key:expr, $aead:expr, $pt:expr, $ct:expr, $tag:expr) => {
{
($key:expr, $aead:expr, $pt:expr, $ct:expr, $tag:expr) => {{
let mut aead = ChaCha20Poly1305::new($key, &ZERO_NONCE, $aead);
if !aead.decrypt($ct, $pt, $tag) {
Err(HandshakeError::DecryptionFailure)
} else {
Ok(())
}
}
}
}};
}
#[cfg(test)]
@@ -177,19 +130,15 @@ mod tests {
#[test]
fn precomputed_hash() {
assert_eq!(
INITIAL_HS[..],
HASH!(INITIAL_CK, IDENTIFIER)[..]
);
assert_eq!(INITIAL_HS[..], HASH!(INITIAL_CK, IDENTIFIER)[..]);
}
}
pub fn create_initiation<T: Copy>(
device: &Device<T>,
peer: &Peer<T>,
sender : u32
sender: u32,
) -> Result<Vec<u8>, HandshakeError> {
let mut rng = OsRng::new().unwrap();
let mut msg: Initiation = Default::default();
@@ -256,7 +205,12 @@ pub fn create_initiation<T : Copy>(
// update state of peer
peer.set_state(State::InitiationSent{hs, ck, eph_sk, sender});
peer.set_state(State::InitiationSent {
hs,
ck,
eph_sk,
sender,
});
// return message as vector
@@ -265,9 +219,8 @@ pub fn create_initiation<T : Copy>(
pub fn consume_initiation<'a, T: Copy>(
device: &'a Device<T>,
msg : &[u8]
msg: &[u8],
) -> Result<(&'a Peer<T>, TemporaryState), HandshakeError> {
// parse message
let msg = Initiation::try_from(msg)?;
@@ -289,10 +242,7 @@ pub fn consume_initiation<'a, T : Copy>(
// (C, k) := Kdf2(C, DH(E_priv, S_pub))
let eph_r_pk = PublicKey::from(msg.f_ephemeral);
let (ck, key) = KDF2!(
&ck,
device.sk.diffie_hellman(&eph_r_pk).as_bytes()
);
let (ck, key) = KDF2!(&ck, device.sk.diffie_hellman(&eph_r_pk).as_bytes());
// msg.static := Aead(k, 0, S_pub, H)
@@ -344,9 +294,8 @@ pub fn consume_initiation<'a, T : Copy>(
pub fn create_response<T: Copy>(
peer: &Peer<T>,
sender: u32, // sending identifier
state : TemporaryState // state from "consume_initiation"
state: TemporaryState, // state from "consume_initiation"
) -> Result<Output<T>, HandshakeError> {
let mut rng = OsRng::new().unwrap();
let mut msg: Response = Default::default();
@@ -417,18 +366,20 @@ pub fn create_response<T : Copy>(
confirmed: false,
send: Key {
id: sender,
key : key_send.into()
key: key_send.into(),
},
recv: Key {
id: receiver,
key : key_recv.into()
}
})
key: key_recv.into(),
},
}),
))
}
pub fn consume_response<T : Copy>(device : &Device<T>, msg : &[u8]) -> Result<Output<T>, HandshakeError> {
pub fn consume_response<T: Copy>(
device: &Device<T>,
msg: &[u8],
) -> Result<Output<T>, HandshakeError> {
// parse message
let msg = Response::try_from(msg)?;
@@ -438,7 +389,12 @@ pub fn consume_response<T : Copy>(device : &Device<T>, msg : &[u8]) -> Result<Ou
let peer = device.lookup_id(msg.f_receiver)?;
let (hs, ck, sender, eph_sk) = match peer.get_state() {
State::Reset => Err(HandshakeError::InvalidState),
State::InitiationSent{hs, ck, sender, eph_sk} => Ok((hs, ck, sender, eph_sk))
State::InitiationSent {
hs,
ck,
sender,
eph_sk,
} => Ok((hs, ck, sender, eph_sk)),
}?;
// C := Kdf1(C, E_pub)
@@ -489,12 +445,12 @@ pub fn consume_response<T : Copy>(device : &Device<T>, msg : &[u8]) -> Result<Ou
confirmed: true,
send: Key {
id: sender,
key : key_send.into()
key: key_send.into(),
},
recv: Key {
id: msg.f_sender,
key : key_recv.into()
}
})
key: key_recv.into(),
},
}),
))
}

View File

@@ -4,12 +4,12 @@ use generic_array::typenum::U32;
use generic_array::GenericArray;
use x25519_dalek::PublicKey;
use x25519_dalek::StaticSecret;
use x25519_dalek::SharedSecret;
use x25519_dalek::StaticSecret;
use crate::types::*;
use crate::timestamp;
use crate::device::Device;
use crate::timestamp;
use crate::types::*;
/* Represents the recomputation and state of a peer.
*
@@ -30,7 +30,7 @@ pub struct Peer<T> {
// constant state
pub(crate) pk: PublicKey, // public key of peer
pub(crate) ss: SharedSecret, // precomputed DH(static, static)
pub(crate) psk : Psk // psk of peer
pub(crate) psk: Psk, // psk of peer
}
pub enum State {
@@ -39,7 +39,7 @@ pub enum State {
sender: u32, // assigned sender id
eph_sk: StaticSecret,
hs: GenericArray<u8, U32>,
ck : GenericArray<u8, U32>
ck: GenericArray<u8, U32>,
},
}
@@ -47,23 +47,30 @@ impl Clone for State {
fn clone(&self) -> State {
match self {
State::Reset => State::Reset,
State::InitiationSent{sender, eph_sk, hs, ck} =>
State::InitiationSent {
sender,
eph_sk,
hs,
ck,
} => State::InitiationSent {
sender: *sender,
eph_sk: StaticSecret::from(eph_sk.to_bytes()),
hs: *hs,
ck : *ck
}
ck: *ck,
},
}
}
}
impl <T>Peer<T> where T : Copy {
impl<T> Peer<T>
where
T: Copy,
{
pub fn new(
idx: usize,
identifier: T, // external identifier
pk: PublicKey, // public key of peer
ss : SharedSecret // precomputed DH(static, static)
ss: SharedSecret, // precomputed DH(static, static)
) -> Self {
Self {
idx: idx,
@@ -72,7 +79,7 @@ impl <T>Peer<T> where T : Copy {
timestamp: Mutex::new(None),
pk: pk,
ss: ss,
psk : [0u8; 32]
psk: [0u8; 32],
}
}
@@ -87,10 +94,7 @@ impl <T>Peer<T> where T : Copy {
///
/// # Arguments
///
pub fn set_state(
&self,
state_new : State
) {
pub fn set_state(&self, state_new: State) {
*self.state.lock() = state_new;
}
@@ -103,28 +107,27 @@ impl <T>Peer<T> where T : Copy {
pub fn check_timestamp(
&self,
device: &Device<T>,
timestamp_new : &timestamp::TAI64N
timestamp_new: &timestamp::TAI64N,
) -> Result<(), HandshakeError> {
let mut state = self.state.lock();
let mut timestamp = self.timestamp.lock();
let update = match *timestamp {
None => true,
Some(timestamp_old) => if timestamp::compare(&timestamp_old, &timestamp_new) {
Some(timestamp_old) => {
if timestamp::compare(&timestamp_old, &timestamp_new) {
true
} else {
false
}
}
};
if update {
// release existing identifier
match *state {
State::InitiationSent{sender, ..} => {
device.release(sender)
},
_ => ()
State::InitiationSent { sender, .. } => device.release(sender),
_ => (),
}
// reset state and update timestamp

View File

@@ -1,5 +1,5 @@
use std::fmt;
use std::error::Error;
use std::fmt;
// config error
@@ -37,24 +37,20 @@ pub enum HandshakeError {
UnknownReceiverId,
InvalidMessageFormat,
OldTimestamp,
InvalidState
InvalidState,
}
impl fmt::Display for HandshakeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
HandshakeError::DecryptionFailure =>
write!(f, "Failed to AEAD:OPEN"),
HandshakeError::UnknownPublicKey =>
write!(f, "Unknown public key"),
HandshakeError::UnknownReceiverId =>
write!(f, "Receiver id not allocated to any handshake"),
HandshakeError::InvalidMessageFormat =>
write!(f, "Invalid handshake message format"),
HandshakeError::OldTimestamp =>
write!(f, "Timestamp is less/equal to the newest"),
HandshakeError::InvalidState =>
write!(f, "Message does not apply to handshake state")
HandshakeError::DecryptionFailure => write!(f, "Failed to AEAD:OPEN"),
HandshakeError::UnknownPublicKey => write!(f, "Unknown public key"),
HandshakeError::UnknownReceiverId => {
write!(f, "Receiver id not allocated to any handshake")
}
HandshakeError::InvalidMessageFormat => write!(f, "Invalid handshake message format"),
HandshakeError::OldTimestamp => write!(f, "Timestamp is less/equal to the newest"),
HandshakeError::InvalidState => write!(f, "Message does not apply to handshake state"),
}
}
}
@@ -74,7 +70,7 @@ impl Error for HandshakeError {
#[derive(Debug)]
pub struct Key {
pub key: [u8; 32],
pub id : u32
pub id: u32,
}
#[cfg(test)]
@@ -88,14 +84,14 @@ impl PartialEq for Key {
pub struct KeyPair {
pub confirmed: bool, // has the key-pair been confirmed?
pub send: Key, // key for outbound messages
pub recv : Key // key for inbound messages
pub recv: Key, // key for inbound messages
}
pub type Output<T> = (
T, // external identifier associated with peer
// (e.g. a reference or vector index)
Option<Vec<u8>>, // message to send
Option<KeyPair> // resulting key-pair of successful handshake
Option<KeyPair>, // resulting key-pair of successful handshake
);
// preshared key