Encoding / decoding of messages
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
**/*.rs.bk
|
||||||
209
Cargo.lock
generated
Normal file
209
Cargo.lock
generated
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clear_on_drop"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "curve25519-dalek"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-cprng"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gcc"
|
||||||
|
version = "0.3.55"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.3.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rdrand"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.1.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-crypto"
|
||||||
|
version = "0.2.36"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-serialize"
|
||||||
|
version = "0.3.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.1.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wg-handshake"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"x25519-dalek 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x25519-dalek"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
|
||||||
|
"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2"
|
||||||
|
"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
|
||||||
|
"checksum curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f8a6fc0376eb52dc18af94915cc04dfdf8353746c0e8c550ae683a0815e5c1"
|
||||||
|
"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
|
||||||
|
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||||
|
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
|
||||||
|
"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1"
|
||||||
|
"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
|
||||||
|
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||||
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
|
"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
|
||||||
|
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||||
|
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
|
||||||
|
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||||
|
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||||
|
"checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926"
|
||||||
|
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||||
|
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||||
|
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||||
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
"checksum x25519-dalek 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4aca1ba6bec2719576bd20dfe5b24d9359552e616d10bff257e50cd85f745d17"
|
||||||
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "wg-handshake"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Mathias Hall-Andersen <mathias@hall-andersen.dk>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rust-crypto = "0.2.36"
|
||||||
|
|
||||||
|
[dependencies.x25519-dalek]
|
||||||
|
version = "^0.5"
|
||||||
11
src/lib.rs
Normal file
11
src/lib.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
mod messages;
|
||||||
|
mod machine;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
54
src/machine.rs
Normal file
54
src/machine.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
use x25519_dalek::PublicKey;
|
||||||
|
use x25519_dalek::StaticSecret;
|
||||||
|
use x25519_dalek::SharedSecret;
|
||||||
|
|
||||||
|
/* Mutable part of handshake state */
|
||||||
|
enum StateMutable {
|
||||||
|
Reset,
|
||||||
|
InitiationSent,
|
||||||
|
InitiationProcessed,
|
||||||
|
ReponseSent
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Immutable part of the handshake state */
|
||||||
|
struct StateFixed {
|
||||||
|
sk : StaticSecret,
|
||||||
|
pk : PublicKey,
|
||||||
|
ss : SharedSecret
|
||||||
|
}
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
m : StateMutable,
|
||||||
|
f : StateFixed,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KeyPair {
|
||||||
|
send : [u8; 32],
|
||||||
|
recv : [u8; 32]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
/* Initialize a new handshake state machine
|
||||||
|
*/
|
||||||
|
fn new(sk : StaticSecret, pk : PublicKey) -> State {
|
||||||
|
let ss = sk.diffie_hellman(&pk);
|
||||||
|
State {
|
||||||
|
m : StateMutable::Reset,
|
||||||
|
f : StateFixed{sk, pk, ss}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Begin a new handshake, returns the initial handshake message
|
||||||
|
*/
|
||||||
|
fn begin(&self) -> Vec<u8> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process a handshake message.
|
||||||
|
*
|
||||||
|
* Result is either a new state (and optionally a new key pair) or an error
|
||||||
|
*/
|
||||||
|
fn process(&self, msg : &[u8]) -> Result<(State, Option<KeyPair>), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
111
src/messages.rs
Normal file
111
src/messages.rs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
use std::mem;
|
||||||
|
|
||||||
|
const SIZE_TAG : usize = 16;
|
||||||
|
const SIZE_X25519_POINT : usize = 32;
|
||||||
|
const SIZE_TIMESTAMP : usize = 12;
|
||||||
|
|
||||||
|
pub const SIZE_MESSAGE_INITIATE : usize = 116;
|
||||||
|
pub const SIZE_MESSAGE_RESPONSE : usize = 116;
|
||||||
|
|
||||||
|
pub const TYPE_INITIATE : u8 = 1;
|
||||||
|
pub const TYPE_RESPONSE : u8 = 2;
|
||||||
|
|
||||||
|
/* Wireguard handshake initiation message
|
||||||
|
* initator -> responder
|
||||||
|
*/
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct MessageInitiate {
|
||||||
|
f_type : u32,
|
||||||
|
f_sender : u32,
|
||||||
|
f_ephemeral : [u8; SIZE_X25519_POINT],
|
||||||
|
f_static : [u8; SIZE_X25519_POINT + SIZE_TAG],
|
||||||
|
f_timestamp : [u8; SIZE_TIMESTAMP + SIZE_TAG],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&[u8]> for MessageInitiate {
|
||||||
|
fn from(b: &[u8]) -> Self {
|
||||||
|
// create owned copy
|
||||||
|
let mut owned = [0u8; mem::size_of::<Self>()];
|
||||||
|
let mut msg : Self;
|
||||||
|
owned.copy_from_slice(b);
|
||||||
|
|
||||||
|
// cast to MessageInitiate
|
||||||
|
unsafe {
|
||||||
|
msg = mem::transmute::<[u8; mem::size_of::<Self>()], Self>(owned);
|
||||||
|
};
|
||||||
|
|
||||||
|
// correct endianness
|
||||||
|
msg.f_type = msg.f_type.to_le();
|
||||||
|
msg.f_sender = msg.f_sender.to_le();
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Vec<u8>> for MessageInitiate {
|
||||||
|
fn into(self) -> Vec<u8> {
|
||||||
|
// correct endianness
|
||||||
|
let mut msg = self;
|
||||||
|
msg.f_type = msg.f_type.to_le();
|
||||||
|
msg.f_sender = msg.f_sender.to_le();
|
||||||
|
|
||||||
|
// cast to array
|
||||||
|
let array : [u8; mem::size_of::<Self>()];
|
||||||
|
unsafe {
|
||||||
|
array = mem::transmute::<Self, [u8; mem::size_of::<Self>()]>(msg)
|
||||||
|
};
|
||||||
|
|
||||||
|
array.to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wireguard handshake responder message
|
||||||
|
* responder -> initator
|
||||||
|
*/
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct MessageResponse {
|
||||||
|
f_type : u32,
|
||||||
|
f_sender : u32,
|
||||||
|
f_receiver : u32,
|
||||||
|
f_ephemeral : [u8; SIZE_X25519_POINT],
|
||||||
|
f_empty : [u8; SIZE_TAG],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&[u8]> for MessageResponse {
|
||||||
|
fn from(b: &[u8]) -> Self {
|
||||||
|
// create owned copy
|
||||||
|
let mut owned = [0u8; mem::size_of::<Self>()];
|
||||||
|
let mut msg : Self;
|
||||||
|
owned.copy_from_slice(b);
|
||||||
|
|
||||||
|
// cast to MessageInitiate
|
||||||
|
unsafe {
|
||||||
|
msg = mem::transmute::<[u8; mem::size_of::<Self>()], Self>(owned);
|
||||||
|
};
|
||||||
|
|
||||||
|
// correct endianness
|
||||||
|
msg.f_type = msg.f_type.to_le();
|
||||||
|
msg.f_sender = msg.f_sender.to_le();
|
||||||
|
msg.f_receiver = msg.f_receiver.to_le();
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Vec<u8>> for MessageResponse {
|
||||||
|
fn into(self) -> Vec<u8> {
|
||||||
|
// correct endianness
|
||||||
|
let mut msg = self;
|
||||||
|
msg.f_type = msg.f_type.to_le();
|
||||||
|
msg.f_sender = msg.f_sender.to_le();
|
||||||
|
msg.f_receiver = msg.f_receiver.to_le();
|
||||||
|
|
||||||
|
// cast to array
|
||||||
|
let array : [u8; mem::size_of::<Self>()];
|
||||||
|
unsafe {
|
||||||
|
array = mem::transmute::<Self, [u8; mem::size_of::<Self>()]>(msg)
|
||||||
|
};
|
||||||
|
|
||||||
|
array.to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user