diff options
| -rw-r--r-- | Cargo.lock | 280 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | talpid-relay-config-client/Cargo.toml | 20 | ||||
| -rw-r--r-- | talpid-relay-config-client/build.rs | 5 | ||||
| -rw-r--r-- | talpid-relay-config-client/proto/feature.proto | 36 | ||||
| -rw-r--r-- | talpid-relay-config-client/src/lib.rs | 75 | ||||
| -rw-r--r-- | talpid-relay-config-client/src/main.rs | 19 | ||||
| -rw-r--r-- | talpid-types/src/net/wireguard.rs | 9 |
8 files changed, 429 insertions, 16 deletions
diff --git a/Cargo.lock b/Cargo.lock index 7d2f5f5582..f108dba034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,6 +81,15 @@ dependencies = [ ] [[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] name = "anyhow" version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -175,6 +184,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] +name = "bindgen" +version = "0.59.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap 2.34.0", + "env_logger 0.9.0", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -211,6 +243,15 @@ dependencies = [ ] [[package]] +name = "build-deps" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f14468960818ce4f3e3553c32d524446687884f8e7af5d3e252331d8a87e43" +dependencies = [ + "glob", +] + +[[package]] name = "bumpalo" version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -253,6 +294,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -313,6 +363,32 @@ dependencies = [ ] [[package]] +name = "clang-sys" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] name = "clap" version = "3.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -325,7 +401,7 @@ dependencies = [ "os_str_bytes", "strsim 0.10.0", "termcolor", - "textwrap", + "textwrap 0.14.2", ] [[package]] @@ -334,7 +410,16 @@ version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "678db4c39c013cc68b54d372bce2efc58e30a0337c497c9032fd196802df3bc3" dependencies = [ - "clap", + "clap 3.0.14", +] + +[[package]] +name = "cmake" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089" +dependencies = [ + "cc", ] [[package]] @@ -420,6 +505,16 @@ dependencies = [ ] [[package]] +name = "cstr_core" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644828c273c063ab0d39486ba42a5d1f3a499d35529c759e763a9c6cb8a0fb08" +dependencies = [ + "cty", + "memchr", +] + +[[package]] name = "ctr" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -439,6 +534,12 @@ dependencies = [ ] [[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] name = "curve25519-dalek" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1020,6 +1121,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" [[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] name = "h2" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1443,6 +1550,16 @@ dependencies = [ ] [[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if 1.0.0", + "winapi 0.3.9", +] + +[[package]] name = "linked-hash-map" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1543,6 +1660,12 @@ dependencies = [ ] [[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] name = "miniz_oxide" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1673,7 +1796,7 @@ version = "2022.2.0" dependencies = [ "base64", "chrono", - "clap", + "clap 3.0.14", "clap_complete", "env_logger 0.8.4", "err-derive", @@ -1697,7 +1820,7 @@ dependencies = [ "android_logger", "cfg-if 1.0.0", "chrono", - "clap", + "clap 3.0.14", "ctrlc", "dirs-next", "duct", @@ -1779,8 +1902,8 @@ dependencies = [ "mullvad-types", "nix 0.23.1", "parity-tokio-ipc", - "prost", - "prost-types", + "prost 0.8.0", + "prost-types 0.8.0", "talpid-types", "tokio", "tonic", @@ -1801,7 +1924,7 @@ dependencies = [ name = "mullvad-problem-report" version = "2022.2.0" dependencies = [ - "clap", + "clap 3.0.14", "dirs-next", "duct", "env_logger 0.8.4", @@ -1845,7 +1968,7 @@ dependencies = [ name = "mullvad-setup" version = "2022.2.0" dependencies = [ - "clap", + "clap 3.0.14", "env_logger 0.8.4", "err-derive", "lazy_static", @@ -2024,6 +2147,16 @@ dependencies = [ ] [[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] name = "notify" version = "4.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2124,6 +2257,29 @@ dependencies = [ ] [[package]] +name = "oqs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9534d1e8a22731bcd9fb97be6f6597503dcc4d86fd72e8a9deec214481884cc6" +dependencies = [ + "cstr_core", + "libc", + "oqs-sys", +] + +[[package]] +name = "oqs-sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "667693ecaa5afb140d88242bced5f259c9c2e2f477418f13b47834d784ed2b12" +dependencies = [ + "bindgen", + "build-deps", + "cmake", + "libc", +] + +[[package]] name = "os_pipe" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2233,6 +2389,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" [[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2468,7 +2630,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de5e2533f59d08fcf364fd374ebda0692a70bd6d7e66ef97f306f45c6c5d8020" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.8.0", +] + +[[package]] +name = "prost" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" +dependencies = [ + "bytes", + "prost-derive 0.9.0", ] [[package]] @@ -2483,8 +2655,8 @@ dependencies = [ "log", "multimap", "petgraph", - "prost", - "prost-types", + "prost 0.8.0", + "prost-types 0.8.0", "tempfile", "which", ] @@ -2503,13 +2675,36 @@ dependencies = [ ] [[package]] +name = "prost-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "prost-types" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "603bbd6394701d13f3f25aada59c7de9d35a6a5887cfc156181234a44002771b" dependencies = [ "bytes", - "prost", + "prost 0.8.0", +] + +[[package]] +name = "prost-types" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" +dependencies = [ + "bytes", + "prost 0.9.0", ] [[package]] @@ -2755,6 +2950,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] name = "rustc_version" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3092,6 +3293,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] name = "signal-hook-registry" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3164,6 +3371,12 @@ dependencies = [ [[package]] name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" @@ -3267,7 +3480,7 @@ dependencies = [ "parity-tokio-ipc", "parking_lot 0.11.2", "pfctl", - "prost", + "prost 0.8.0", "quickcheck", "quickcheck_macros", "rand 0.7.3", @@ -3321,7 +3534,7 @@ dependencies = [ "log", "openvpn-plugin", "parity-tokio-ipc", - "prost", + "prost 0.8.0", "talpid-types", "tokio", "tonic", @@ -3341,6 +3554,20 @@ dependencies = [ ] [[package]] +name = "talpid-relay-config-client" +version = "0.1.0" +dependencies = [ + "oqs", + "prost 0.8.0", + "prost-types 0.9.0", + "talpid-types", + "tokio", + "tonic", + "tonic-build", + "tower", +] + +[[package]] name = "talpid-time" version = "0.1.0" dependencies = [ @@ -3386,6 +3613,15 @@ dependencies = [ [[package]] name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" @@ -3566,8 +3802,8 @@ dependencies = [ "hyper-timeout", "percent-encoding", "pin-project", - "prost", - "prost-derive", + "prost 0.8.0", + "prost-derive 0.8.0", "tokio", "tokio-stream", "tokio-util", @@ -3849,6 +4085,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3908,6 +4150,12 @@ dependencies = [ ] [[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] name = "version_check" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 75bbc7d0ae..e4ab3c68fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "talpid-core", "talpid-dbus", "talpid-platform-metadata", + "talpid-relay-config-client", "talpid-time", "mullvad-management-interface", "tunnel-obfuscation", diff --git a/talpid-relay-config-client/Cargo.toml b/talpid-relay-config-client/Cargo.toml new file mode 100644 index 0000000000..a7107da2fd --- /dev/null +++ b/talpid-relay-config-client/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "talpid-relay-config-client" +version = "0.1.0" +authors = ["Mullvad VPN"] +description = "Uses relays to set up PQ-safe peers, etc." +license = "GPL-3.0" +edition = "2021" +publish = false + +[dependencies] +talpid-types = { path = "../talpid-types" } +tonic = "0.5" +prost = "0.8" +prost-types = "0.9" +tower = "0.4" +tokio = "1" +oqs = { version = "0.7.0", default-features = false, features = ["kems"] } + +[build-dependencies] +tonic-build = { version = "0.5", default-features = false, features = ["transport", "prost"] }
\ No newline at end of file diff --git a/talpid-relay-config-client/build.rs b/talpid-relay-config-client/build.rs new file mode 100644 index 0000000000..ae7775eb0a --- /dev/null +++ b/talpid-relay-config-client/build.rs @@ -0,0 +1,5 @@ +fn main() { + const PROTO_FILE: &str = "proto/feature.proto"; + tonic_build::compile_protos(PROTO_FILE).unwrap(); + println!("cargo:rerun-if-changed={}", PROTO_FILE); +} diff --git a/talpid-relay-config-client/proto/feature.proto b/talpid-relay-config-client/proto/feature.proto new file mode 100644 index 0000000000..0f1486f7fc --- /dev/null +++ b/talpid-relay-config-client/proto/feature.proto @@ -0,0 +1,36 @@ +// +// If you need to (re)generate the gRPC code, see prerequisites +// +// https://grpc.io/docs/languages/go/quickstart/ +// +// and then run +// +// protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative feature.proto +// +// from this directory. +// + +syntax = "proto3"; + +option go_package = "github.com/mullvad/wg-manager/server/feature"; + +package feature; + +service PostQuantumSecure { + rpc PskExchange(PskRequest) returns (PskResponse) {} +} + +message PskRequest { + bytes wg_pubkey = 1; + bytes wg_psk_pubkey = 2; + OqsPubkey oqs_pubkey = 3; +} + +message OqsPubkey { + string algorithm_name = 1; + bytes key_data = 2; +} + +message PskResponse { + bytes ciphertext = 1; +} diff --git a/talpid-relay-config-client/src/lib.rs b/talpid-relay-config-client/src/lib.rs new file mode 100644 index 0000000000..f8da97db83 --- /dev/null +++ b/talpid-relay-config-client/src/lib.rs @@ -0,0 +1,75 @@ +use std::net::IpAddr; + +use oqs::kem::{Algorithm, Kem}; +use talpid_types::net::wireguard::{PresharedKey, PrivateKey, PublicKey}; +use tonic::transport::{Channel, Endpoint, Uri}; + +mod types { + tonic::include_proto!("feature"); +} + +type RelayConfigService = types::post_quantum_secure_client::PostQuantumSecureClient<Channel>; + +const CONFIG_SERVICE_PORT: u16 = 1337; +const ALGORITHM: Algorithm = Algorithm::ClassicMcEliece8192128f; + +#[derive(Debug)] +pub enum Error { + GrpcTransportError(tonic::transport::Error), + GrpcError(tonic::Status), + OqsError(oqs::Error), + InvalidCiphertext, +} + +// TODO: consider binding to the tunnel interface here, on non-windows platforms +pub async fn push_pq_key( + service_address: IpAddr, + current_pubkey: PublicKey, +) -> Result<(PrivateKey, PresharedKey), Error> { + let oqs_key = PrivateKey::new_from_random(); + + let kem = Kem::new(ALGORITHM).map_err(Error::OqsError)?; + let (pubkey, secret) = kem.keypair().map_err(Error::OqsError)?; + + let mut client = new_client(service_address).await?; + let response = client + .psk_exchange(types::PskRequest { + wg_pubkey: current_pubkey.as_bytes().to_vec(), + wg_psk_pubkey: oqs_key.public_key().as_bytes().to_vec(), + oqs_pubkey: Some(types::OqsPubkey { + algorithm_name: algorithm_to_string(&ALGORITHM), + key_data: pubkey.into_vec(), + }), + }) + .await + .map_err(Error::GrpcError)?; + + let ciphertext = response.into_inner().ciphertext; + let ciphertext = kem + .ciphertext_from_bytes(&ciphertext) + .ok_or(Error::InvalidCiphertext)?; + let psk = kem + .decapsulate(&secret, ciphertext) + .map(|key| PresharedKey::from(<[u8; 32]>::try_from(key.as_ref()).unwrap())) + .map_err(Error::OqsError)?; + Ok((oqs_key, psk)) +} + +fn algorithm_to_string(algorithm: &Algorithm) -> String { + match algorithm { + Algorithm::ClassicMcEliece8192128f => "Classic-McEliece-8192128f".to_string(), + _ => unimplemented!(), + } +} + +async fn new_client(addr: IpAddr) -> Result<RelayConfigService, Error> { + let channel = Endpoint::from_shared(format!("tcp://{addr}:{CONFIG_SERVICE_PORT}")) + .expect("Failed to construct URI") + .connect_with_connector(tower::service_fn(move |_: Uri| { + tokio::net::TcpStream::connect((addr, CONFIG_SERVICE_PORT)) + })) + .await + .map_err(Error::GrpcTransportError)?; + + Ok(RelayConfigService::new(channel)) +} diff --git a/talpid-relay-config-client/src/main.rs b/talpid-relay-config-client/src/main.rs new file mode 100644 index 0000000000..46d18bbbc5 --- /dev/null +++ b/talpid-relay-config-client/src/main.rs @@ -0,0 +1,19 @@ +use std::net::{Ipv4Addr, IpAddr}; + +use talpid_types::net::wireguard::PrivateKey; + + +#[tokio::main] +async fn main() { + let current_private_key = PrivateKey::new_from_random(); + + let (private_key, psk) = talpid_relay_config_client::push_pq_key( + IpAddr::V4(Ipv4Addr::new(10, 64, 0, 1)), + current_private_key.public_key(), + ) + .await + .unwrap(); + + println!("private key: {:?}", private_key); + println!("psk: {:?}", psk); +} diff --git a/talpid-types/src/net/wireguard.rs b/talpid-types/src/net/wireguard.rs index 199ff3bd29..56ecc6bb42 100644 --- a/talpid-types/src/net/wireguard.rs +++ b/talpid-types/src/net/wireguard.rs @@ -253,6 +253,15 @@ impl fmt::Display for PublicKey { } } +#[derive(Debug, Clone)] +pub struct PresharedKey([u8; 32]); + +impl From<[u8; 32]> for PresharedKey { + fn from(key: [u8; 32]) -> PresharedKey { + PresharedKey(key) + } +} + fn serialize_key<S>(key: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, |
