Added opaque identity to output
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
28
src/noise.rs
28
src/noise.rs
@@ -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,
|
||||||
|
|||||||
29
src/peer.rs
29
src/peer.rs
@@ -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,19 +58,21 @@ impl Clone for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Peer {
|
impl <T>Peer<T> where T : Copy {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
idx : usize,
|
idx : usize,
|
||||||
pk : PublicKey, // public key of peer
|
identifier : T, // external identifier
|
||||||
ss : SharedSecret // precomputed DH(static, static)
|
pk : PublicKey, // public key of peer
|
||||||
|
ss : SharedSecret // precomputed DH(static, static)
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
idx : idx,
|
idx : idx,
|
||||||
state : Mutex::new(State::Reset),
|
identifier : identifier,
|
||||||
timestamp : Mutex::new(None),
|
state : Mutex::new(State::Reset),
|
||||||
pk : pk,
|
timestamp : Mutex::new(None),
|
||||||
ss : ss,
|
pk : pk,
|
||||||
psk : [0u8; 32]
|
ss : ss,
|
||||||
|
psk : [0u8; 32]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 : ×tamp::TAI64N
|
timestamp_new : ×tamp::TAI64N
|
||||||
) -> Result<(), HandshakeError> {
|
) -> Result<(), HandshakeError> {
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user