Added opaque identity to output

This commit is contained in:
Mathias Hall-Andersen
2019-07-25 18:23:30 +02:00
parent d2c4ad17fe
commit 409ba51750
4 changed files with 49 additions and 39 deletions

View File

@@ -12,10 +12,10 @@ use crate::messages;
use crate::types::*; use crate::types::*;
use crate::peer::Peer; use crate::peer::Peer;
pub struct Device { pub struct Device<T> {
pub sk : StaticSecret, // static secret key pub sk : StaticSecret, // static secret key
pub pk : PublicKey, // static public key pub pk : PublicKey, // static public key
peers : Vec<Peer>, // peer index -> state peers : Vec<Peer<T>>, // peer index -> state
pk_map : HashMap<[u8; 32], usize>, // public key -> peer index 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
} }
@@ -23,13 +23,13 @@ pub struct Device {
/* A mutable reference to the device needs to be held during configuration. /* A mutable reference to the device needs to be held during configuration.
* Wrapping the device in a RwLock enables peer config after "configuration time" * Wrapping the device in a RwLock enables peer config after "configuration time"
*/ */
impl Device { impl <T>Device<T> where T : Copy {
/// Initialize a new handshake state machine /// Initialize a new handshake state machine
/// ///
/// # Arguments /// # Arguments
/// ///
/// * `sk` - x25519 scalar representing the local private key /// * `sk` - x25519 scalar representing the local private key
pub fn new(sk : StaticSecret) -> Device { pub fn new(sk : StaticSecret) -> Device<T> {
Device { Device {
pk : PublicKey::from(&sk), pk : PublicKey::from(&sk),
sk : sk, sk : sk,
@@ -45,7 +45,8 @@ impl Device {
/// # Arguments /// # Arguments
/// ///
/// * `pk` - The public key to add /// * `pk` - The public key to add
pub fn add(&mut self, pk : PublicKey) -> Result<(), ConfigError> { /// * `identifier` - Associated identifier which can be used to distinguish the peers
pub fn add(&mut self, pk : PublicKey, identifier : T) -> Result<(), ConfigError> {
// check that the pk is not added twice // check that the pk is not added twice
if let Some(_) = self.pk_map.get(pk.as_bytes()) { if let Some(_) = self.pk_map.get(pk.as_bytes()) {
@@ -66,7 +67,7 @@ impl Device {
// map : new index -> peer // map : new index -> peer
self.peers.push(Peer::new( self.peers.push(Peer::new(
idx, pk, self.sk.diffie_hellman(&pk) idx, identifier, pk, self.sk.diffie_hellman(&pk)
)); ));
Ok(()) Ok(())
@@ -128,7 +129,7 @@ impl Device {
/// # 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, HandshakeError> { pub fn process(&self, msg : &[u8]) -> Result<Output<T>, HandshakeError> {
match msg.get(0) { match msg.get(0) {
Some(&messages::TYPE_INITIATION) => { Some(&messages::TYPE_INITIATION) => {
// consume the initiation // consume the initiation
@@ -152,7 +153,7 @@ impl Device {
// Internal function // Internal function
// //
// Return the peer associated with the public key // Return the peer associated with the public key
pub(crate) fn lookup_pk(&self, pk : &PublicKey) -> Result<&Peer, HandshakeError> { pub(crate) fn lookup_pk(&self, pk : &PublicKey) -> Result<&Peer<T>, HandshakeError> {
match self.pk_map.get(pk.as_bytes()) { match self.pk_map.get(pk.as_bytes()) {
Some(&idx) => Ok(&self.peers[idx]), Some(&idx) => Ok(&self.peers[idx]),
_ => Err(HandshakeError::UnknownPublicKey) _ => Err(HandshakeError::UnknownPublicKey)
@@ -162,7 +163,7 @@ impl Device {
// Internal function // Internal function
// //
// Return the peer currently associated with the receiver identifier // Return the peer currently associated with the receiver identifier
pub(crate) fn lookup_id(&self, id : u32) -> Result<&Peer, HandshakeError> { pub(crate) fn lookup_id(&self, id : u32) -> Result<&Peer<T>, HandshakeError> {
match self.id_map.read().get(&id) { match self.id_map.read().get(&id) {
Some(&idx) => Ok(&self.peers[idx]), Some(&idx) => Ok(&self.peers[idx]),
_ => Err(HandshakeError::UnknownReceiverId) _ => Err(HandshakeError::UnknownReceiverId)
@@ -217,8 +218,8 @@ mod tests {
let mut dev1 = Device::new(sk1); let mut dev1 = Device::new(sk1);
let mut dev2 = Device::new(sk2); let mut dev2 = Device::new(sk2);
dev1.add(pk2).unwrap(); dev1.add(pk2, 1337).unwrap();
dev2.add(pk1).unwrap(); dev2.add(pk1, 2600).unwrap();
// do a few handshakes // do a few handshakes
@@ -235,7 +236,7 @@ mod tests {
// process initiation and create response // process initiation and create response
let (msg2, ks_r) = dev2.process(&msg1).unwrap(); let (_, msg2, ks_r) = dev2.process(&msg1).unwrap();
let ks_r = ks_r.unwrap(); let ks_r = ks_r.unwrap();
let msg2 = msg2.unwrap(); let msg2 = msg2.unwrap();
@@ -247,7 +248,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(&msg2).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");

View File

@@ -184,11 +184,11 @@ mod tests {
} }
} }
pub fn create_initiation( pub fn create_initiation<T>(
device : &Device, device : &Device<T>,
peer : &Peer, peer : &Peer<T>,
sender : u32 sender : u32
) -> Result<Vec<u8>, HandshakeError> { ) -> Result<Vec<u8>, HandshakeError> where T : Copy {
let mut rng = OsRng::new().unwrap(); let mut rng = OsRng::new().unwrap();
let mut msg : Initiation = Default::default(); let mut msg : Initiation = Default::default();
@@ -263,10 +263,10 @@ pub fn create_initiation(
Ok(Initiation::into(msg)) Ok(Initiation::into(msg))
} }
pub fn consume_initiation<'a>( pub fn consume_initiation<'a, T>(
device : &'a Device, device : &'a Device<T>,
msg : &[u8] msg : &[u8]
) -> Result<(&'a Peer, TemporaryState), HandshakeError> { ) -> Result<(&'a Peer<T>, TemporaryState), HandshakeError> where T : Copy {
// parse message // parse message
@@ -341,11 +341,11 @@ pub fn consume_initiation<'a>(
Ok((peer, (msg.f_sender, eph_r_pk, hs, ck))) Ok((peer, (msg.f_sender, eph_r_pk, hs, ck)))
} }
pub fn create_response( pub fn create_response<T>(
peer : &Peer, peer : &Peer<T>,
sender : u32, // sending identifier sender : u32, // sending identifier
state : TemporaryState // state from "consume_initiation" state : TemporaryState // state from "consume_initiation"
) -> Result<Output, HandshakeError> { ) -> Result<Output<T>, HandshakeError> where T : Copy {
let mut rng = OsRng::new().unwrap(); let mut rng = OsRng::new().unwrap();
let mut msg : Response = Default::default(); let mut msg : Response = Default::default();
@@ -417,6 +417,7 @@ pub fn create_response(
// return response and unconfirmed key-pair // return response and unconfirmed key-pair
Ok(( Ok((
peer.identifier,
Some(Response::into(msg)), Some(Response::into(msg)),
Some(KeyPair{ Some(KeyPair{
confirmed : false, confirmed : false,
@@ -432,10 +433,10 @@ pub fn create_response(
)) ))
} }
pub fn consume_response( pub fn consume_response<T>(
device : &Device, device : &Device<T>,
msg : &[u8] msg : &[u8]
) -> Result<Output, HandshakeError> { ) -> Result<Output<T>, HandshakeError> where T : Copy {
// parse message // parse message
@@ -497,6 +498,7 @@ pub fn consume_response(
// return response and unconfirmed key-pair // return response and unconfirmed key-pair
Ok(( Ok((
peer.identifier,
None, None,
Some(KeyPair{ Some(KeyPair{
confirmed : true, confirmed : true,

View File

@@ -16,7 +16,10 @@ use crate::device::Device;
* This type is only for internal use and not exposed. * This type is only for internal use and not exposed.
*/ */
pub struct Peer { pub struct Peer<T> {
// external identifier
pub(crate) identifier : T,
// internal identifier // internal identifier
pub(crate) idx : usize, pub(crate) idx : usize,
@@ -55,14 +58,16 @@ impl Clone for State {
} }
} }
impl Peer { impl <T>Peer<T> where T : Copy {
pub fn new( pub fn new(
idx : usize, idx : usize,
identifier : T, // external identifier
pk : PublicKey, // public key of peer pk : PublicKey, // public key of peer
ss : SharedSecret // precomputed DH(static, static) ss : SharedSecret // precomputed DH(static, static)
) -> Self { ) -> Self {
Self { Self {
idx : idx, idx : idx,
identifier : identifier,
state : Mutex::new(State::Reset), state : Mutex::new(State::Reset),
timestamp : Mutex::new(None), timestamp : Mutex::new(None),
pk : pk, pk : pk,
@@ -97,7 +102,7 @@ impl Peer {
/// * ts_new - The associated timestamp /// * ts_new - The associated timestamp
pub fn check_timestamp( pub fn check_timestamp(
&self, &self,
device : &Device, device : &Device<T>,
timestamp_new : &timestamp::TAI64N timestamp_new : &timestamp::TAI64N
) -> Result<(), HandshakeError> { ) -> Result<(), HandshakeError> {

View File

@@ -91,7 +91,9 @@ pub struct KeyPair {
pub recv : Key // key for inbound messages pub recv : Key // key for inbound messages
} }
pub type Output = ( pub type Output<T> = (
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
); );