summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-02-07 09:31:54 +0100
committerDavid Lönnhager <david.l@mullvad.net>2020-02-07 09:31:54 +0100
commita6c3608e710503ac29cf51f721f1dc4e8c7e2724 (patch)
tree5e9358332ff6af88e3eb05ff3c512a24328b522d
parentdb8ea63ffaa671df27dc404b75a9ee92fda0312c (diff)
parent1839efc29694a0dd32fcf07753cec71603cfc455 (diff)
downloadmullvadvpn-a6c3608e710503ac29cf51f721f1dc4e8c7e2724.tar.xz
mullvadvpn-a6c3608e710503ac29cf51f721f1dc4e8c7e2724.zip
Merge branch 'x25519-update'
-rw-r--r--Cargo.lock44
-rw-r--r--mullvad-daemon/src/wireguard.rs21
-rw-r--r--talpid-core/src/tunnel/wireguard/config.rs2
-rw-r--r--talpid-types/Cargo.toml2
-rw-r--r--talpid-types/src/net/wireguard.rs92
5 files changed, 93 insertions, 68 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8e6b03aa4e..a77b00b0d2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -232,14 +232,6 @@ dependencies = [
]
[[package]]
-name = "clear_on_drop"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -337,14 +329,14 @@ dependencies = [
[[package]]
name = "curve25519-dalek"
-version = "1.2.3"
+version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (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.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2522,7 +2514,7 @@ dependencies = [
"jnix 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
- "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x25519-dalek 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3132,18 +3124,32 @@ dependencies = [
[[package]]
name = "x25519-dalek"
-version = "0.5.2"
+version = "0.6.0"
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.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "zeroize"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[metadata]
"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
@@ -3177,7 +3183,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
-"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03"
"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
@@ -3189,7 +3194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f"
-"checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d"
+"checksum curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839"
"checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6"
"checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c"
"checksum darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1"
@@ -3465,5 +3470,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
"checksum winres 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ff4fb510bbfe5b8992ff15f77a2e6fe6cf062878f0eda00c0f44963a807ca5dc"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-"checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538"
+"checksum x25519-dalek 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217"
"checksum zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
+"checksum zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2"
diff --git a/mullvad-daemon/src/wireguard.rs b/mullvad-daemon/src/wireguard.rs
index 7bd98cee52..1cad231548 100644
--- a/mullvad-daemon/src/wireguard.rs
+++ b/mullvad-daemon/src/wireguard.rs
@@ -1,7 +1,7 @@
use crate::{account_history::AccountHistory, InternalDaemonEvent};
use chrono::offset::Utc;
use futures::{
- future::{Executor, IntoFuture},
+ future::Executor,
sync::{mpsc::UnboundedSender, oneshot},
Async, Future, Poll,
};
@@ -30,11 +30,8 @@ const AUTOMATIC_ROTATION_RETRY_DELAY: Duration = Duration::from_secs(5);
/// A short interval is used in case the computer is ever suspended.
const KEY_CHECK_INTERVAL: Duration = Duration::from_secs(60);
-
#[derive(err_derive::Error, Debug)]
pub enum Error {
- #[error(display = "Failed to generate private key")]
- GenerationError(#[error(source)] rand::Error),
#[error(display = "Failed to spawn future")]
ExectuionError,
#[error(display = "Unexpected RPC error")]
@@ -123,7 +120,7 @@ impl KeyManager {
/// Generate a new private key
pub fn generate_key_sync(&mut self, account: AccountToken) -> Result<WireguardData> {
self.reset();
- let private_key = PrivateKey::new_from_random().map_err(Error::GenerationError)?;
+ let private_key = PrivateKey::new_from_random();
self.run_future_sync(self.push_future_generator(account, private_key)())
.map_err(Self::map_rpc_error)
@@ -149,7 +146,7 @@ impl KeyManager {
old_key: PublicKey,
) -> Result<WireguardData> {
self.reset();
- let new_key = PrivateKey::new_from_random().map_err(Error::GenerationError)?;
+ let new_key = PrivateKey::new_from_random();
self.run_future_sync(Self::replace_key_rpc(
self.http_handle.clone(),
account,
@@ -163,7 +160,7 @@ impl KeyManager {
/// Generate a new private key asyncronously. The new keys will be sent to the daemon channel.
pub fn generate_key_async(&mut self, account: AccountToken) -> Result<()> {
self.reset();
- let private_key = PrivateKey::new_from_random().map_err(Error::GenerationError)?;
+ let private_key = PrivateKey::new_from_random();
let future_generator = self.push_future_generator(account.clone(), private_key);
let retry_strategy = ExponentialBackoff::from_millis(300)
@@ -321,13 +318,9 @@ impl KeyManager {
.and_then(move |_| {
log::info!("Replacing WireGuard key");
- let private_key = PrivateKey::new_from_random()
- .map_err(Error::GenerationError)
- .into_future();
- private_key.and_then(move |private_key| {
- Self::replace_key_rpc(http_handle, account_token, public_key, private_key)
- .map_err(Self::map_rpc_error)
- })
+ let private_key = PrivateKey::new_from_random();
+ Self::replace_key_rpc(http_handle, account_token, public_key, private_key)
+ .map_err(Self::map_rpc_error)
})
.then(move |rpc_result| {
match rpc_result {
diff --git a/talpid-core/src/tunnel/wireguard/config.rs b/talpid-core/src/tunnel/wireguard/config.rs
index 76107a2a63..e433483a55 100644
--- a/talpid-core/src/tunnel/wireguard/config.rs
+++ b/talpid-core/src/tunnel/wireguard/config.rs
@@ -95,7 +95,7 @@ impl Config {
// the order of insertion matters, public key entry denotes a new peer entry
let mut wg_conf = WgConfigBuffer::new();
wg_conf
- .add("private_key", self.tunnel.private_key.as_bytes().as_ref())
+ .add("private_key", self.tunnel.private_key.to_bytes().as_ref())
.add("listen_port", "0");
wg_conf.add("replace_peers", "true");
diff --git a/talpid-types/Cargo.toml b/talpid-types/Cargo.toml
index 5e9354847c..a75af01062 100644
--- a/talpid-types/Cargo.toml
+++ b/talpid-types/Cargo.toml
@@ -11,7 +11,7 @@ publish = false
serde = { version = "1.0", features = ["derive"] }
ipnetwork = "0.15"
base64 = "0.10"
-x25519-dalek = { version = "0.5", features = [ "std", "u64_backend" ], default-features = false }
+x25519-dalek = { version = "0.6", features = [ "std", "u64_backend" ], default-features = false }
rand = "0.7"
err-derive = "0.2.1"
diff --git a/talpid-types/src/net/wireguard.rs b/talpid-types/src/net/wireguard.rs
index 805d1884ba..767687dd6b 100644
--- a/talpid-types/src/net/wireguard.rs
+++ b/talpid-types/src/net/wireguard.rs
@@ -1,9 +1,10 @@
use crate::net::{Endpoint, GenericTunnelOptions, TransportProtocol};
use ipnetwork::IpNetwork;
-use rand::{rngs::OsRng, RngCore};
+use rand::rngs::OsRng;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::{
- fmt,
+ cmp, fmt,
+ hash::{Hash, Hasher},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
};
@@ -56,41 +57,48 @@ pub struct TunnelOptions {
}
/// Wireguard x25519 private key
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PrivateKey([u8; 32]);
+#[derive(Clone)]
+pub struct PrivateKey(x25519_dalek::StaticSecret);
impl PrivateKey {
/// Get private key as bytes
- pub fn as_bytes(&self) -> &[u8; 32] {
- &self.0
- }
-
- /// Normalizing a private key as per the specification - https://cr.yp.to/ecdh.html
- fn normalize_key(bytes: &mut [u8; 32]) {
- bytes[0] &= 248;
- bytes[31] &= 127;
- bytes[31] |= 64;
+ pub fn to_bytes(&self) -> [u8; 32] {
+ self.0.to_bytes()
}
- pub fn new_from_random() -> Result<Self, rand::Error> {
- let mut bytes = [0u8; 32];
- OsRng.fill_bytes(&mut bytes);
- Ok(Self::from(bytes))
+ pub fn new_from_random() -> Self {
+ PrivateKey(x25519_dalek::StaticSecret::new(&mut OsRng))
}
/// Generate public key from private key
pub fn public_key(&self) -> PublicKey {
- PublicKey::from(x25519_dalek::x25519(
- self.0,
- x25519_dalek::X25519_BASEPOINT_BYTES,
- ))
+ PublicKey::from(&self.0)
}
}
impl From<[u8; 32]> for PrivateKey {
- fn from(mut private_key: [u8; 32]) -> PrivateKey {
- Self::normalize_key(&mut private_key);
- PrivateKey(private_key)
+ fn from(bytes: [u8; 32]) -> Self {
+ Self(x25519_dalek::StaticSecret::from(bytes))
+ }
+}
+
+impl cmp::PartialEq for PrivateKey {
+ fn eq(&self, other: &PrivateKey) -> bool {
+ self.0.to_bytes() == other.0.to_bytes()
+ }
+}
+
+impl cmp::Eq for PrivateKey {}
+
+impl fmt::Debug for PrivateKey {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", &self)
+ }
+}
+
+impl fmt::Display for PrivateKey {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", &base64::encode(&(self.0).to_bytes()))
}
}
@@ -99,11 +107,10 @@ impl Serialize for PrivateKey {
where
S: Serializer,
{
- serialize_key(&self.0, serializer)
+ serialize_key(&self.0.to_bytes(), serializer)
}
}
-
impl<'de> Deserialize<'de> for PrivateKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -114,20 +121,26 @@ impl<'de> Deserialize<'de> for PrivateKey {
}
/// Wireguard x25519 public key
-#[derive(Clone, PartialEq, Eq, Hash)]
-pub struct PublicKey([u8; 32]);
+#[derive(Clone)]
+pub struct PublicKey(x25519_dalek::PublicKey);
impl PublicKey {
/// Get the public key as bytes
pub fn as_bytes(&self) -> &[u8; 32] {
- &self.0
+ self.0.as_bytes()
}
}
+impl<'a> From<&'a x25519_dalek::StaticSecret> for PublicKey {
+ fn from(private_key: &'a x25519_dalek::StaticSecret) -> PublicKey {
+ PublicKey(x25519_dalek::PublicKey::from(private_key))
+ }
+}
+
impl From<[u8; 32]> for PublicKey {
fn from(public_key: [u8; 32]) -> PublicKey {
- PublicKey(public_key)
+ PublicKey(x25519_dalek::PublicKey::from(public_key))
}
}
@@ -136,11 +149,10 @@ impl Serialize for PublicKey {
where
S: Serializer,
{
- serialize_key(&self.0, serializer)
+ serialize_key(&self.0.as_bytes(), serializer)
}
}
-
impl<'de> Deserialize<'de> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -150,6 +162,20 @@ impl<'de> Deserialize<'de> for PublicKey {
}
}
+impl Hash for PublicKey {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.0.as_bytes().hash(state);
+ }
+}
+
+impl cmp::PartialEq for PublicKey {
+ fn eq(&self, other: &PublicKey) -> bool {
+ self.0.as_bytes() == other.0.as_bytes()
+ }
+}
+
+impl cmp::Eq for PublicKey {}
+
impl fmt::Debug for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", &self)
@@ -158,7 +184,7 @@ impl fmt::Debug for PublicKey {
impl fmt::Display for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", &base64::encode(&self.0))
+ write!(f, "{}", &base64::encode(self.0.as_bytes()))
}
}