diff --git a/Cargo.lock b/Cargo.lock index 2ac9903c..948b200c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,25 +75,11 @@ dependencies = [ "aead 0.5.2", "aes 0.8.4", "cipher 0.4.4", - "ctr 0.9.2", - "ghash 0.5.1", + "ctr", + "ghash", "subtle", ] -[[package]] -name = "aes-gcm" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2b8006a0c83f52b62ba44a97b58bf76fe2f70a329e588f67f89691d93d498f" -dependencies = [ - "aead 0.6.1", - "aes 0.9.3", - "cipher 0.5.2", - "ctr 0.10.1", - "ctutils", - "ghash 0.6.0", -] - [[package]] name = "ahash" version = "0.8.12" @@ -1957,15 +1943,6 @@ dependencies = [ "cipher 0.4.4", ] -[[package]] -name = "ctr" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21" -dependencies = [ - "cipher 0.5.2", -] - [[package]] name = "ctutils" version = "0.4.2" @@ -2537,7 +2514,7 @@ dependencies = [ "atomic-shim", "atomic-write-file", "atomic_refcell", - "base64 0.23.1", + "base64 0.22.1", "bon", "boringtun-easytier", "bytecodec", @@ -2570,7 +2547,7 @@ dependencies = [ "hickory-proto", "hickory-resolver", "hickory-server", - "hkdf 0.13.0", + "hkdf", "http", "http-body-util", "humansize", @@ -2609,7 +2586,7 @@ dependencies = [ "serde_json", "serial_test", "service-manager", - "sha2 0.11.0", + "sha2 0.10.9", "shellexpand", "smoltcp", "socket2", @@ -2663,7 +2640,7 @@ dependencies = [ name = "easytier-core" version = "2.7.0" dependencies = [ - "aes-gcm 0.11.1", + "aes-gcm", "anyhow", "arc-swap", "ariadne", @@ -2671,22 +2648,22 @@ dependencies = [ "async-trait", "atomic-shim", "auto_impl", - "base64 0.23.1", + "base64 0.22.1", "bitflags 2.13.2", "bon", "bytecodec", "bytes", - "chacha20poly1305 0.11.0", + "chacha20poly1305 0.10.1", "chrono", "cidr", - "crossbeam", + "crossbeam-utils", "dashmap", "easytier-proto", "futures", "getrandom 0.2.17", "getrandom 0.3.4", "guarden", - "hmac 0.13.0", + "hmac 0.12.1", "http-body-util", "hyper", "hyper-util", @@ -2704,9 +2681,10 @@ dependencies = [ "rand 0.8.8", "ring", "rustls", + "rustls-pki-types", "serde", "serde_json", - "sha2 0.11.0", + "sha2 0.10.9", "smoltcp", "snow", "strum 0.28.0", @@ -2811,7 +2789,7 @@ dependencies = [ name = "easytier-ohos-features" version = "0.1.0" dependencies = [ - "base64 0.23.1", + "base64 0.22.1", "easytier", "flate2", "gethostname", @@ -2858,11 +2836,11 @@ dependencies = [ "anyhow", "async-trait", "auto_impl", - "base64 0.23.1", + "base64 0.22.1", "bytes", "chrono", "cidr", - "hmac 0.13.0", + "hmac 0.12.1", "indoc", "pbjson", "pbjson-build", @@ -2875,7 +2853,7 @@ dependencies = [ "reqwest 0.13.5", "serde", "serde_json", - "sha2 0.11.0", + "sha2 0.10.9", "thiserror 2.0.20", "tokio", "url", @@ -2924,7 +2902,7 @@ dependencies = [ "axum-embed", "axum-login", "axum-messages", - "base64 0.23.1", + "base64 0.22.1", "chrono", "cidr", "clap", @@ -2948,7 +2926,7 @@ dependencies = [ "sea-orm-migration", "serde", "serde_json", - "sha2 0.11.0", + "sha2 0.10.9", "sqlx", "subtle", "sys-locale", @@ -3025,7 +3003,7 @@ dependencies = [ "ff", "generic-array", "group", - "hkdf 0.12.4", + "hkdf", "pem-rfc7468", "pkcs8", "rand_core 0.6.4", @@ -3778,16 +3756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", - "polyval 0.6.2", -] - -[[package]] -name = "ghash" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" -dependencies = [ - "polyval 0.7.3", + "polyval", ] [[package]] @@ -4297,15 +4266,6 @@ dependencies = [ "hmac 0.12.1", ] -[[package]] -name = "hkdf" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" -dependencies = [ - "hmac 0.13.0", -] - [[package]] name = "hmac" version = "0.12.1" @@ -7001,17 +6961,6 @@ dependencies = [ "universal-hash 0.5.1", ] -[[package]] -name = "polyval" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0fa31d631f2b2cb2a544d0aa321ce847a94764d701ca2becc411138b93d49cd" -dependencies = [ - "cpubits", - "cpufeatures 0.3.1", - "universal-hash 0.6.1", -] - [[package]] name = "portable-atomic" version = "1.15.0" @@ -8979,12 +8928,9 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "599b506ccc4aff8cf7844bc42cf783009a434c1e26c964432560fb6d6ad02d82" dependencies = [ - "aes-gcm 0.10.3", - "blake2 0.10.6", "chacha20poly1305 0.10.1", "curve25519-dalek 4.1.3", "getrandom 0.3.4", - "ring", "rustc_version", "sha2 0.10.9", "subtle", @@ -9182,7 +9128,7 @@ dependencies = [ "futures-util", "generic-array", "hex", - "hkdf 0.12.4", + "hkdf", "hmac 0.12.1", "itoa", "log", @@ -9225,7 +9171,7 @@ dependencies = [ "futures-core", "futures-util", "hex", - "hkdf 0.12.4", + "hkdf", "hmac 0.12.1", "home", "itoa", diff --git a/Cargo.toml b/Cargo.toml index c56c03dd..55ed4580 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,8 @@ async-trait = "0.1.92" atomic-shim = "0.2.0" auto_impl = "1.3.0" axum = "0.8" -base64 = "0.23" +# Match pbjson 0.9's base64 dependency; upgrade together to avoid two codecs. +base64 = "0.22.1" bon = "3.10.1" bytecodec = "0.5.0" bytes = "1.12.1" @@ -37,6 +38,7 @@ chrono = "0.4.45" cidr = "0.3.2" clap = "4.6.7" crossbeam = "0.8.5" +crossbeam-utils = "0.8.23" dashmap = "6.2.1" easytier = { version = "2.7.0", path = "easytier", default-features = false } easytier-core = { version = "2.7.0", path = "easytier-core", default-features = false } @@ -44,10 +46,12 @@ easytier-ffi = { version = "0.1.0", path = "easytier-contrib/easytier-ffi", defa easytier-ohos-core = { version = "0.1.0", path = "easytier-contrib/easytier-ohrs/crates/easytier-ohos-core", default-features = false } easytier-ohos-features = { version = "0.1.0", path = "easytier-contrib/easytier-ohrs/crates/easytier-ohos-features", default-features = false } easytier-proto = { version = "2.7.0", path = "easytier-proto", default-features = false } -futures = "0.3" +futures = { version = "0.3", default-features = false } gethostname = "1.1" guarden = "0.3" -hmac = "0.13.0" +# Keep HMAC/SHA2 on digest 0.10, shared by stun_codec 0.4 and snow 0.10. +# Upgrade this crypto family together when those upstream constraints move. +hmac = "0.12.1" http-body-util = "0.1" hyper = { version = "1", default-features = false } hyper-util = { version = "0.1", default-features = false } @@ -71,7 +75,8 @@ sea-orm = "1.1.20" sea-orm-migration = "1.1.20" serde = "1.0.229" serde_json = "1.0" -sha2 = "0.11.0" +# See the HMAC constraint above; SHA2 must use the same digest generation. +sha2 = "0.10.9" smoltcp = { version = "0.14.0", default-features = false } sqlx = "0.8.6" strum = "0.28.0" diff --git a/easytier-contrib/easytier-ohrs/Cargo.toml b/easytier-contrib/easytier-ohrs/Cargo.toml index 342ba877..ec57793a 100644 --- a/easytier-contrib/easytier-ohrs/Cargo.toml +++ b/easytier-contrib/easytier-ohrs/Cargo.toml @@ -20,7 +20,7 @@ easytier-proto = { workspace = true, features = [ "core", "json-rpc", ] } -futures.workspace = true +futures = { workspace = true, features = ["default"] } napi-derive-ohos = "1.1" napi-ohos = { version = "1.1", default-features = false, features = [ "serde-json", diff --git a/easytier-core/Cargo.toml b/easytier-core/Cargo.toml index 19cf1705..fde05de2 100644 --- a/easytier-core/Cargo.toml +++ b/easytier-core/Cargo.toml @@ -30,11 +30,11 @@ bytecodec.workspace = true bytes.workspace = true chrono = { workspace = true, features = ["clock"] } cidr = { workspace = true, features = ["serde"] } -crossbeam.workspace = true +crossbeam-utils.workspace = true dashmap.workspace = true bon.workspace = true easytier-proto = { workspace = true, features = ["core"] } -futures.workspace = true +futures = { workspace = true, features = ["std", "async-await"] } guarden.workspace = true hmac.workspace = true http-body-util = { workspace = true, optional = true } @@ -58,6 +58,14 @@ serde = { workspace = true, features = ["derive"] } serde_json.workspace = true sha2.workspace = true smoltcp = { workspace = true, optional = true } +# All core Noise handshakes use 25519_ChaChaPoly_SHA256. Snow's std feature +# also enables unused ring and BLAKE2 dependencies, so use its alloc support. +snow = { version = "0.10.0", default-features = false, features = [ + "use-chacha20poly1305", + "use-sha2", + "use-curve25519", + "use-getrandom", +] } stun_codec.workspace = true thiserror.workspace = true tracing.workspace = true @@ -74,25 +82,25 @@ tokio-util = { workspace = true, features = ["io", "rt"] } tokio-rustls = { workspace = true, optional = true } url = { workspace = true, features = ["serde"] } wildmatch = "2.6.1" -uuid = { workspace = true, features = ["v4", "fast-rng", "serde"] } +uuid = { workspace = true, features = ["v4", "serde"] } webpki-roots = { version = "1.0", optional = true } x25519-dalek = { workspace = true, features = ["static_secrets"] } zerocopy = { workspace = true, features = ["derive", "simd"] } zstd = { version = "0.14", optional = true } -aes-gcm = { version = "0.11.1", optional = true } -chacha20poly1305 = { version = "0.11.0", optional = true } +# Match snow 0.10's AEAD generation to share aead, cipher and crypto-common. +# Upgrade together with snow rather than pulling in a second crypto stack. +aes-gcm = { version = "0.10.3", optional = true } +chacha20poly1305 = { version = "0.10.1", optional = true } openssl = { version = "0.10", optional = true, features = ["vendored"] } [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] getrandom-02 = { package = "getrandom", version = "0.2.17", features = ["js"] } getrandom-03 = { package = "getrandom", version = "0.3.4", features = ["wasm_js"] } -snow = { version = "0.10.0", default-features = false, features = ["default-resolver", "default-resolver-crypto"] } +ring = { version = "0.17", features = ["wasm32_unknown_unknown_js"], optional = true } +rustls-pki-types = { version = "1.15.1", features = ["web"], optional = true } uuid = { workspace = true, features = ["js"] } wasm-bindgen = "0.2" -[target.'cfg(not(all(target_arch = "wasm32", target_os = "unknown")))'.dependencies] -snow = "0.10.0" - [features] default = ["aes-gcm", "endpoint-discovery", "extended-services", "management", "tcp-hole-punch"] aes-gcm = ["dep:aes-gcm"] @@ -106,7 +114,9 @@ endpoint-discovery = [ "dep:http-body-util", "dep:hyper", "dep:hyper-util", + "dep:ring", "dep:rustls", + "dep:rustls-pki-types", "dep:tokio-rustls", "dep:webpki-roots", ] @@ -152,12 +162,17 @@ test-utils = [] tracing-log = ["tracing/log"] zstd = ["dep:zstd"] +[dev-dependencies] +futures = { workspace = true, features = ["executor"] } + [target.'cfg(not(target_os = "wasi"))'.dev-dependencies] tokio = { workspace = true, features = ["rt-multi-thread", "test-util"] } [package.metadata.cargo-machete] ignored = [ - # Enable browser entropy backends for transitive rand/snow dependencies. + # Enable browser entropy backends for transitive rand/snow/AEAD dependencies. "getrandom-02", "getrandom-03", + # Enable browser time for rustls certificate validation. + "rustls-pki-types", ] diff --git a/easytier-core/src/connectivity/hole_punch/udp/server.rs b/easytier-core/src/connectivity/hole_punch/udp/server.rs index 5da74fb8..082266ee 100644 --- a/easytier-core/src/connectivity/hole_punch/udp/server.rs +++ b/easytier-core/src/connectivity/hole_punch/udp/server.rs @@ -8,7 +8,7 @@ use std::{ }; use anyhow::Context; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use quanta::Instant; use rand::{Rng, seq::SliceRandom as _}; use tokio::{ diff --git a/easytier-core/src/gateway/dataplane/resource.rs b/easytier-core/src/gateway/dataplane/resource.rs index a06b9e95..7f8ca459 100644 --- a/easytier-core/src/gateway/dataplane/resource.rs +++ b/easytier-core/src/gateway/dataplane/resource.rs @@ -6,7 +6,7 @@ use std::{ sync::{Arc, Mutex}, }; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use tokio::sync::Notify; use tokio_util::sync::CancellationToken; diff --git a/easytier-core/src/gateway/port_forward.rs b/easytier-core/src/gateway/port_forward.rs index 00b10be3..eda8df7c 100644 --- a/easytier-core/src/gateway/port_forward.rs +++ b/easytier-core/src/gateway/port_forward.rs @@ -9,7 +9,7 @@ use std::{ time::Duration, }; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use dashmap::DashMap; use quanta::Instant; use tokio::{ diff --git a/easytier-core/src/gateway/proxy/tcp_proxy_engine.rs b/easytier-core/src/gateway/proxy/tcp_proxy_engine.rs index b4cd785d..298fe9e1 100644 --- a/easytier-core/src/gateway/proxy/tcp_proxy_engine.rs +++ b/easytier-core/src/gateway/proxy/tcp_proxy_engine.rs @@ -8,7 +8,7 @@ use std::{ }; use cidr::Ipv4Inet; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use dashmap::{DashMap, mapref::entry::Entry}; use smoltcp::wire::{IpAddress, IpProtocol, Ipv4Packet, TcpPacket}; diff --git a/easytier-core/src/peers/conn/peer.rs b/easytier-core/src/peers/conn/peer.rs index 7ab3435d..d60fd693 100644 --- a/easytier-core/src/peers/conn/peer.rs +++ b/easytier-core/src/peers/conn/peer.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use arc_swap::ArcSwapOption; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use dashmap::{DashMap, DashSet}; use parking_lot::{Mutex, RwLock}; diff --git a/easytier-core/src/peers/conn/peer_conn.rs b/easytier-core/src/peers/conn/peer_conn.rs index 072e8707..f03bc217 100644 --- a/easytier-core/src/peers/conn/peer_conn.rs +++ b/easytier-core/src/peers/conn/peer_conn.rs @@ -1,5 +1,5 @@ use arc_swap::ArcSwapOption; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use futures::{StreamExt, TryFutureExt}; use std::{ any::Any, diff --git a/easytier-core/src/peers/conn/peer_session.rs b/easytier-core/src/peers/conn/peer_session.rs index 2c822f75..cd8c57ca 100644 --- a/easytier-core/src/peers/conn/peer_session.rs +++ b/easytier-core/src/peers/conn/peer_session.rs @@ -5,7 +5,7 @@ use std::sync::{ use std::time::{Duration, Instant}; use anyhow::anyhow; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use dashmap::DashMap; use crate::peers::util::shrink_dashmap; diff --git a/easytier-core/src/peers/context.rs b/easytier-core/src/peers/context.rs index e1757af4..a259730e 100644 --- a/easytier-core/src/peers/context.rs +++ b/easytier-core/src/peers/context.rs @@ -16,7 +16,7 @@ use easytier_proto::{ common::{FlagsInConfig, PeerFeatureFlag, SecureModeConfig, StunInfo, TunnelInfo}, peer_rpc::{PeerGroupInfo, TrustedCredentialPubkeyProof}, }; -use hmac::{Hmac, KeyInit, Mac}; +use hmac::{Hmac, Mac}; use sha2::Sha256; pub use crate::config::{NetworkIdentity, NetworkSecretDigest}; diff --git a/easytier-core/src/peers/peer_center/instance.rs b/easytier-core/src/peers/peer_center/instance.rs index 2e8525d0..89293311 100644 --- a/easytier-core/src/peers/peer_center/instance.rs +++ b/easytier-core/src/peers/peer_center/instance.rs @@ -4,7 +4,7 @@ use std::{ time::{Duration, Instant}, }; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use futures::Future; use std::sync::RwLock; use tokio::sync::Mutex; diff --git a/easytier-core/src/peers/route/peer_ospf_route.rs b/easytier-core/src/peers/route/peer_ospf_route.rs index e3b669fa..9973c65e 100644 --- a/easytier-core/src/peers/route/peer_ospf_route.rs +++ b/easytier-core/src/peers/route/peer_ospf_route.rs @@ -12,7 +12,7 @@ use std::{ use arc_swap::ArcSwap; use atomic_shim::AtomicU64; use cidr::{IpCidr, Ipv4Cidr, Ipv6Cidr, Ipv6Inet}; -use crossbeam::atomic::AtomicCell; +use crossbeam_utils::atomic::AtomicCell; use dashmap::DashMap; use ordered_hash_map::OrderedHashMap; use parking_lot::{RwLock, lock_api::RwLockUpgradableReadGuard}; diff --git a/easytier-core/src/tunnel/encrypt/aes_gcm.rs b/easytier-core/src/tunnel/encrypt/aes_gcm.rs index 3297dc54..bf914ac1 100644 --- a/easytier-core/src/tunnel/encrypt/aes_gcm.rs +++ b/easytier-core/src/tunnel/encrypt/aes_gcm.rs @@ -1,4 +1,4 @@ -use aes_gcm::{AeadInOut, Aes128Gcm, Aes256Gcm, Key, KeyInit}; +use aes_gcm::{AeadInPlace, Aes128Gcm, Aes256Gcm, Key, KeyInit}; use rand::{RngCore, rngs::OsRng}; use zerocopy::{AsBytes, FromBytes}; @@ -54,16 +54,16 @@ impl Encryptor for AesGcmCipher { let tag = aes_tail.tag.into(); let rs = match &self.cipher { - AesGcmEnum::AES128GCM(aes_gcm) => aes_gcm.decrypt_inout_detached( + AesGcmEnum::AES128GCM(aes_gcm) => aes_gcm.decrypt_in_place_detached( &nonce, &[], - (&mut zc_packet.mut_payload()[..text_len]).into(), + &mut zc_packet.mut_payload()[..text_len], &tag, ), - AesGcmEnum::AES256GCM(aes_gcm) => aes_gcm.decrypt_inout_detached( + AesGcmEnum::AES256GCM(aes_gcm) => aes_gcm.decrypt_in_place_detached( &nonce, &[], - (&mut zc_packet.mut_payload()[..text_len]).into(), + &mut zc_packet.mut_payload()[..text_len], &tag, ), }; @@ -113,7 +113,7 @@ impl Encryptor for AesGcmCipher { nonce.into() }); ( - aes_gcm.encrypt_inout_detached(&nonce, &[], zc_packet.mut_payload().into()), + aes_gcm.encrypt_in_place_detached(&nonce, &[], zc_packet.mut_payload()), nonce, ) } @@ -124,7 +124,7 @@ impl Encryptor for AesGcmCipher { nonce.into() }); ( - aes_gcm.encrypt_inout_detached(&nonce, &[], zc_packet.mut_payload().into()), + aes_gcm.encrypt_in_place_detached(&nonce, &[], zc_packet.mut_payload()), nonce, ) } diff --git a/easytier-core/src/tunnel/encrypt/chacha20.rs b/easytier-core/src/tunnel/encrypt/chacha20.rs index 9da04ab8..6c50e717 100644 --- a/easytier-core/src/tunnel/encrypt/chacha20.rs +++ b/easytier-core/src/tunnel/encrypt/chacha20.rs @@ -1,4 +1,4 @@ -use chacha20poly1305::{AeadInOut, ChaCha20Poly1305, Key, KeyInit}; +use chacha20poly1305::{AeadInPlace, ChaCha20Poly1305, Key, KeyInit}; use rand::{RngCore, rngs::OsRng}; use zerocopy::{AsBytes, FromBytes}; @@ -42,12 +42,7 @@ impl Encryptor for ChaCha20Cipher { let tag = tail.tag.into(); self.cipher - .decrypt_inout_detached( - &nonce, - &[], - (&mut zc_packet.mut_payload()[..text_len]).into(), - &tag, - ) + .decrypt_in_place_detached(&nonce, &[], &mut zc_packet.mut_payload()[..text_len], &tag) .map_err(|_| Error::DecryptionFailed)?; let pm_header = zc_packet.mut_peer_manager_header().unwrap(); @@ -89,7 +84,7 @@ impl Encryptor for ChaCha20Cipher { let tag = self .cipher - .encrypt_inout_detached(&nonce, &[], zc_packet.mut_payload().into()) + .encrypt_in_place_detached(&nonce, &[], zc_packet.mut_payload()) .map_err(|_| Error::EncryptionFailed)?; let tail = StandardAeadTail { diff --git a/easytier-core/src/tunnel/secure_datagram.rs b/easytier-core/src/tunnel/secure_datagram.rs index ba20bb65..db118a07 100644 --- a/easytier-core/src/tunnel/secure_datagram.rs +++ b/easytier-core/src/tunnel/secure_datagram.rs @@ -8,7 +8,7 @@ use std::{ use anyhow::anyhow; use atomic_shim::AtomicU64; -use hmac::{Hmac, KeyInit as _, Mac as _}; +use hmac::{Hmac, Mac as _}; use rand::RngCore as _; use sha2::Sha256; use zerocopy::FromBytes; diff --git a/easytier-proto/src/peer_rpc.rs b/easytier-proto/src/peer_rpc.rs index 79252d48..93a8dae1 100644 --- a/easytier-proto/src/peer_rpc.rs +++ b/easytier-proto/src/peer_rpc.rs @@ -1,4 +1,4 @@ -use hmac::{Hmac, KeyInit, Mac}; +use hmac::{Hmac, Mac}; use prost::Message; use sha2::Sha256; #[cfg(feature = "api")] diff --git a/easytier-web/Cargo.toml b/easytier-web/Cargo.toml index f158ba47..048fe99c 100644 --- a/easytier-web/Cargo.toml +++ b/easytier-web/Cargo.toml @@ -16,7 +16,7 @@ tokio-util = { workspace = true, features = ["rt"] } dashmap.workspace = true url.workspace = true async-trait.workspace = true -futures.workspace = true +futures = { workspace = true, features = ["default"] } prost.workspace = true maxminddb = "0.32" diff --git a/easytier/Cargo.toml b/easytier/Cargo.toml index d04a3a3d..fa4e4c07 100644 --- a/easytier/Cargo.toml +++ b/easytier/Cargo.toml @@ -61,7 +61,7 @@ strum = { workspace = true, features = ["derive"] } gethostname.workspace = true -futures = { workspace = true, features = ["bilock", "unstable"] } +futures = { workspace = true, features = ["default", "bilock", "unstable"] } tokio = { workspace = true, features = [ "fs", @@ -178,7 +178,8 @@ network-interface = "2.0.5" # for wireguard boringtun = { package = "boringtun-easytier", version = "0.6.1", optional = true } -hkdf = { version = "0.13", optional = true } +# Share the workspace HMAC/SHA2 digest generation for WireGuard key derivation. +hkdf = { version = "0.12.4", optional = true } sha2 = { workspace = true, optional = true } # for cli diff --git a/easytier/src/vpn_portal/wireguard.rs b/easytier/src/vpn_portal/wireguard.rs index 768466a3..5fa52c1f 100644 --- a/easytier/src/vpn_portal/wireguard.rs +++ b/easytier/src/vpn_portal/wireguard.rs @@ -395,6 +395,15 @@ mod tests { fn named_wireguard_keys_are_stable_and_client_scoped() { let master = [7; 32]; let client = derive_named_key(&master, b"wireguard-client", "laptop").unwrap(); + // Pin the derived key across crypto dependency upgrades/downgrades. + // Independently calculated with RFC 5869 HKDF-SHA256. + assert_eq!( + client, + [ + 5, 98, 244, 32, 245, 111, 41, 24, 163, 149, 201, 218, 22, 228, 8, 224, 134, 16, + 173, 29, 62, 138, 202, 41, 172, 230, 189, 237, 207, 100, 51, 236, + ] + ); assert_eq!( client, derive_named_key(&master, b"wireguard-client", "laptop").unwrap()