1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
use x25519_dalek::PublicKey;
use x25519_dalek::StaticSecret;
use x25519_dalek::SharedSecret;
use std::sync::Mutex;
use std::sync::mpsc::channel;
use std::collections::HashMap;
pub struct Peer {
m : StateMutable,
sk : StaticSecret,
pk : PublicKey,
ss : SharedSecret,
psk : [u8; 32]
}
/* Mutable part of handshake state */
enum StateMutable {
Reset,
InitiationSent,
InitiationProcessed,
ReponseSent
}
/* Immutable part of the handshake state */
struct StateFixed {
}
struct StateMachine {
peers : Vec<Mutex<Peer>>, // peer index -> state
pkmap : HashMap<[u8; 32], usize>, // public key -> peer index
ids : Mutex<HashMap<u32, usize>> // receive ids -> peer index
}
struct Key {
key : [u8; 32],
id : u32
}
struct KeyPair {
confimed : bool, // has the key-pair been confirmed
send : Key, // key for outbound messages
recv : Key // key for inbound messages
}
struct Output (
Option<KeyPair>, // resulting key-pair of successful handshake
Option<u32> // id to be released
);
impl StateMachine {
/// Initialize a new handshake state machine
///
/// # Arguments
///
/// * `sk` - x25519 scalar representing the local private key
pub fn new(sk : StaticSecret) -> StateMachine {
StateMachine {
peers : vec![],
pkmap : HashMap::new(),
ids : Mutex::new(HashMap::new())
}
}
/// Add a new public key to the state machine
/// To remove public keys, you must create a new machine instance
///
/// # Arguments
///
/// * `pk` - The public key to add
///
/// # Returns
///
/// The call might fail if the public key corresponds to the secret key of the machine
pub fn add(&mut self, pk : PublicKey) -> Result<(), ()> {
// let ss = sk.diffie_hellman(&pk);
Err(())
}
/// Release an id back to the pool
///
/// # Arguments
///
/// * `id` - The (sender) id to release
pub fn release(&self, id : u32) {
self.ids.lock().unwrap().remove(&id);
}
/// Begin a new handshake
///
/// # Arguments
///
/// * `pk` - Public key of peer to initiate handshake for
pub fn begin(&self, pk : PublicKey) -> Result<Output, ()> {
match self.pkmap.get(pk.as_bytes()) {
None => Err(()),
Some(&idx) => {
let mut peer = self.peers.get(idx).unwrap().lock().unwrap();
Err(())
}
}
}
/// Process a handshake message.
///
/// # Arguments
///
/// * `msg` - Byte slice containing the message (untrusted input)
fn process(&self, msg : &[u8]) -> Result<Output, ()> {
// inspect type field
match msg.get(0) {
_ => Err(())
}
}
}
|