diff --git a/Cargo.lock b/Cargo.lock index e5a0097..cd17228 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,18 +27,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if", - "cipher 0.3.0", - "cpufeatures", - "opaque-debug", -] - [[package]] name = "aes" version = "0.8.4" @@ -57,23 +45,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", - "aes 0.8.4", + "aes", "cipher 0.4.4", "ctr", "ghash", "subtle", ] -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher 0.2.5", - "opaque-debug", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -271,27 +249,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "cipher" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" -dependencies = [ - "generic-array", -] - [[package]] name = "cipher" version = "0.3.0" @@ -381,26 +344,6 @@ dependencies = [ "cipher 0.4.4", ] -[[package]] -name = "ctrlc" -version = "3.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" -dependencies = [ - "nix 0.28.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "ctrlc2" -version = "3.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b9bdf0b3623a4c37b654b319624bae363b94c4e27c22db8d48a61c6d74234f" -dependencies = [ - "nix 0.28.0", - "windows-sys 0.52.0", -] - [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -670,12 +613,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "ioctl-sys" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd11f3a29434026f5ff98c730b668ba74b1033637b8817940b54d040696133c" - [[package]] name = "ipnet" version = "2.9.0" @@ -731,7 +668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -882,18 +819,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nix" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "cfg_aliases 0.1.1", - "libc", -] - [[package]] name = "nix" version = "0.29.0" @@ -902,7 +827,7 @@ checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ "bitflags 2.6.0", "cfg-if", - "cfg_aliases 0.2.1", + "cfg_aliases", "libc", ] @@ -975,7 +900,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1278,9 +1203,7 @@ dependencies = [ name = "rustvpn" version = "0.1.2" dependencies = [ - "aes 0.7.5", "aes-gcm", - "aes-soft", "anyhow", "base64", "bincode", @@ -1288,8 +1211,6 @@ dependencies = [ "block-padding", "clap", "crossbeam-channel", - "ctrlc", - "ctrlc2", "env_logger", "futures", "generic-array", @@ -1304,7 +1225,6 @@ dependencies = [ "serde_yaml", "socket2 0.4.10", "tokio", - "tun", "tun2", "x25519-dalek", ] @@ -1517,19 +1437,6 @@ dependencies = [ "syn 2.0.72", ] -[[package]] -name = "tun" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0adb9992bbd5ca76f3847ed579ad4ee8defb2ec2eea918cceef17ccc66fa4fd4" -dependencies = [ - "ioctl-sys", - "libc", - "log", - "thiserror", - "wintun 0.3.2", -] - [[package]] name = "tun2" version = "2.0.5" @@ -1545,7 +1452,7 @@ dependencies = [ "nix 0.29.0", "thiserror", "windows-sys 0.52.0", - "wintun 0.5.0", + "wintun", ] [[package]] @@ -1643,32 +1550,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" -dependencies = [ - "windows-core", - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-core" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1677,22 +1565,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -1701,46 +1574,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1753,67 +1608,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "wintun" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29b83b0eca06dd125dbcd48a45327c708a6da8aada3d95a3f06db0ce4b17e0d4" -dependencies = [ - "c2rust-bitfields", - "libloading", - "log", - "thiserror", - "windows", -] - [[package]] name = "wintun" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 9420478..abcf1ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,16 +8,12 @@ edition = "2021" [dependencies] clap = "2.33" aes-gcm = "0.10.3" -aes-soft = "0.6" tokio = { version = "1", features = ["full", "signal"] } -tun = "0.6.1" serde = "1.0" serde_derive = "1.0.190" bincode = "1.3" rand = { version = "0.8.5", features = ["small_rng", "getrandom", "std_rng"] } anyhow = "1.0" -ctrlc = "3.1" -aes = "0.7" block-modes = "0.8" block-padding = "0.2" generic-array = "0.14" @@ -27,7 +23,6 @@ log = "0.4.20" futures = "0.3.30" tun2 = "2.0.5" packet = "0.1.4" -ctrlc2 = "3.5" crossbeam-channel = "0.5.13" pnet = "0.35.0" net-route = "0.4.4" diff --git a/src/client.rs b/src/client.rs index 9b9f00a..33dc282 100644 --- a/src/client.rs +++ b/src/client.rs @@ -10,6 +10,10 @@ use std::net::{ SocketAddr, Ipv4Addr }; use std::collections::HashMap; use std::process::Command; use tokio::io::AsyncReadExt; +use x25519_dalek::{PublicKey, SharedSecret, StaticSecret}; +use aes_gcm::{ + aead::{Aead, AeadCore, KeyInit, OsRng}, + Aes256Gcm, Key, Nonce}; use crate::{UDPVpnHandshake, UDPVpnPacket, VpnPacket, ClientConfiguration, UDPSerializable}; @@ -88,6 +92,8 @@ pub async fn client_mode(client_config: ClientConfiguration) { let (tx, rx) = unbounded::>(); let (dx, mx) = unbounded::>(); + let cipher_shared = Arc::new(Mutex::new(None)); + tokio::spawn(async move { while let Ok(bytes) = rx.recv() { info!("Write to tun {:?}", hex::encode(&bytes)); @@ -102,11 +108,49 @@ pub async fn client_mode(client_config: ClientConfiguration) { } }); + let priv_key = base64::decode(client_config.client.private_key).unwrap(); + + let cipher_shared_clone = cipher_shared.clone(); tokio::spawn(async move { let mut buf = vec![0; 4096]; + loop { if let Ok(l) = sock_rec.recv(&mut buf).await { - tx.send((&buf[..l]).to_vec()); + let mut s_cipher = cipher_shared_clone.lock().await; + match buf.first() { + Some(h) => { + match h { + 0 => { + let handshake = UDPVpnHandshake::deserialize(&(buf[..l].to_vec())); + let mut k = [0u8; 32]; + for (&x, p) in handshake.public_key.iter().zip(k.iter_mut()) { + *p = x; + } + let mut k1 = [0u8; 32]; + for (&x, p) in priv_key.iter().zip(k1.iter_mut()) { + *p = x; + } + *s_cipher = Some(StaticSecret::from(k1) + .diffie_hellman(&PublicKey::from(k))); + // Aes256Gcm::new(shared_secret.as_bytes().into()); + }, // handshake + 1 => { + let wrapped_packet = UDPVpnPacket::deserialize(&(buf[..l].to_vec())); + if s_cipher.is_some() { + let aes = Aes256Gcm::new(s_cipher.as_ref().unwrap().as_bytes().into()); + let nonce = Nonce::clone_from_slice(&wrapped_packet.nonce); + match aes.decrypt(&nonce, &wrapped_packet.data[..]) { + Ok(decrypted) => { tx.send(decrypted); }, + Err(error) => error!("Decryption error! {:?}", error) + } + } + }, // payload + _ => error!("Unexpected header value.") + } + }, + None => error!("There is no header.") + } + drop(s_cipher); } } }); @@ -115,12 +159,24 @@ pub async fn client_mode(client_config: ClientConfiguration) { let handshake = UDPVpnHandshake{ public_key: pkey, request_ip: client_config.client.address.parse::().unwrap() }; sock_snd.send(&handshake.serialize()).await.unwrap(); + let s_cipher = cipher_shared.clone(); loop { if let Ok(bytes) = mx.recv() { - let vpn_packet = UDPVpnPacket{ data: bytes }; - let serialized_data = vpn_packet.serialize(); - info!("Writing to sock: {:?}", serialized_data); - sock_snd.send(&serialized_data).await.unwrap(); + let mut s_c = s_cipher.lock().await; + + if s_c.is_some() { + let aes = Aes256Gcm::new(s_c.as_ref().unwrap().as_bytes().into()); + let nonce = Aes256Gcm::generate_nonce(&mut OsRng); + + let ciphered_data = aes.encrypt(&nonce, &bytes[..]); + + if let Ok(ciphered_d) = ciphered_data { + let vpn_packet = UDPVpnPacket{ data: ciphered_d, nonce: nonce.to_vec()}; + let serialized_data = vpn_packet.serialize(); + info!("Writing to sock: {:?}", serialized_data); + sock_snd.send(&serialized_data).await.unwrap(); + } + } } } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 05aac7c..4d8fc3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,6 @@ use std::process::Command; use clap::{App, Arg, ArgMatches}; use env_logger::Builder; use log::{error, info, warn, LevelFilter}; -use tun::platform::Device; use serde_derive::Serialize; use serde_derive::Deserialize; use std::str::FromStr; @@ -36,13 +35,20 @@ impl VpnPacket { } struct UDPVpnPacket { + nonce: Vec, // [u8; 64] data: Vec } impl UDPSerializable for UDPVpnPacket { fn serialize(&self) -> Vec { let h: &[u8] = &[1]; - [h, &self.data[..]].concat() + [h, &self.nonce, &self.data[..]].concat() + } +} + +impl UDPVpnPacket { + fn deserialize(data: &Vec) -> Self { + UDPVpnPacket { nonce: data[1..=64].to_vec(), data: data[65..].to_vec() } } } diff --git a/src/server.rs b/src/server.rs index 0263d9e..095b206 100644 --- a/src/server.rs +++ b/src/server.rs @@ -100,6 +100,10 @@ pub async fn server_mode(server_config: ServerConfiguration) { let shared_secret = StaticSecret::from(k1) .diffie_hellman(&PublicKey::from(k)); mp.insert(internal_ip, UDPeer { addr, shared_secret }); + + let handshake_response = UDPVpnHandshake{ public_key: server_config.interface.public_key.clone().into_bytes(), request_ip: handshake.request_ip }; + + sock_rec.send_to(&handshake_response.serialize(), addr); } else { info!("Bad handshake"); plp.iter().for_each(|c| info!("ip: {:?}; pkey: {:?}", c.ip, c.public_key));