From 12e1f314a5bee38c600b4a46c401077388580000 Mon Sep 17 00:00:00 2001 From: dev0 Date: Mon, 1 Jan 2024 02:53:58 +1100 Subject: [PATCH 1/5] use aes crate and get rid of boring fork --- .cargo/config | 1 - .gitmodules | 3 - Cargo.lock | 32 ++++-- clash_lib/Cargo.toml | 13 ++- clash_lib/src/common/crypto.rs | 150 ++------------------------- clash_lib/src/proxy/transport/tls.rs | 73 ++++++------- deps/boringssl/src | 1 - 7 files changed, 75 insertions(+), 198 deletions(-) delete mode 160000 deps/boringssl/src diff --git a/.cargo/config b/.cargo/config index 619aac0cb..3420c1fc8 100644 --- a/.cargo/config +++ b/.cargo/config @@ -3,7 +3,6 @@ target-dir = "target" rustflags = ["--cfg", "tokio_unstable"] [env] -BORING_BSSL_SOURCE_PATH = { value = "deps/boringssl/src", relative = true} RUST_LOG = { value = "clash=trace" } [target.aarch64-unknown-linux-gnu] diff --git a/.gitmodules b/.gitmodules index 79c0945d5..e69de29bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "deps/boringssl/src"] - path = deps/boringssl/src - url = https://github.com/google/boringssl.git diff --git a/Cargo.lock b/Cargo.lock index 653446a95..7e8c7d0bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -517,8 +517,9 @@ dependencies = [ [[package]] name = "boring" -version = "4.1.0" -source = "git+https://github.com/Watfaq/boring.git?rev=58d5e7c66b537989bde45d20ce54aff11de1bcea#58d5e7c66b537989bde45d20ce54aff11de1bcea" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fed6dc629997e8c3c4d1dbd59cf748512b9b0e0fbc509cf9b0e2edca9d24d1a" dependencies = [ "bitflags 2.4.1", "boring-sys", @@ -529,8 +530,9 @@ dependencies = [ [[package]] name = "boring-sys" -version = "4.1.0" -source = "git+https://github.com/Watfaq/boring.git?rev=58d5e7c66b537989bde45d20ce54aff11de1bcea#58d5e7c66b537989bde45d20ce54aff11de1bcea" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91102749c3c99028f344c3bce1dc54b1aac49d52d03c60c75996f81ebdeaa41c" dependencies = [ "bindgen 0.68.1", "cmake", @@ -651,6 +653,15 @@ dependencies = [ "nom", ] +[[package]] +name = "cfb-mode" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" +dependencies = [ + "cipher", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -819,6 +830,7 @@ dependencies = [ name = "clash_lib" version = "0.1.12" dependencies = [ + "aes", "aes-gcm", "anyhow", "async-recursion", @@ -832,6 +844,7 @@ dependencies = [ "brotli", "byteorder", "bytes", + "cfb-mode", "chacha20poly1305", "chrono", "console-subscriber", @@ -885,7 +898,6 @@ dependencies = [ "thiserror", "tokio", "tokio-boring", - "tokio-rustls", "tokio-test", "tokio-tungstenite 0.21.0", "tokio-util", @@ -2069,8 +2081,9 @@ dependencies = [ [[package]] name = "hyper-boring" -version = "4.1.0" -source = "git+https://github.com/Watfaq/boring.git?rev=58d5e7c66b537989bde45d20ce54aff11de1bcea#58d5e7c66b537989bde45d20ce54aff11de1bcea" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b32387184f6bf1cfd826f1185cbe6b5e35eff4360725863beb101aa01406e5d" dependencies = [ "antidote", "boring", @@ -3967,8 +3980,9 @@ dependencies = [ [[package]] name = "tokio-boring" -version = "4.1.0" -source = "git+https://github.com/Watfaq/boring.git?rev=58d5e7c66b537989bde45d20ce54aff11de1bcea#58d5e7c66b537989bde45d20ce54aff11de1bcea" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806b3972e90cd4633771ba91ec25f312a97192010fe4470061700f289524ae57" dependencies = [ "boring", "boring-sys", diff --git a/clash_lib/Cargo.toml b/clash_lib/Cargo.toml index b4845b929..26395a87c 100644 --- a/clash_lib/Cargo.toml +++ b/clash_lib/Cargo.toml @@ -12,7 +12,6 @@ bench = ["criterion"] [dependencies] tokio = { version = "1", features = ["full"] } tokio-util = { version = "0.7", features = ["net", "codec", "io", "compat"] } -tokio-rustls = "0.24" thiserror = "1.0" async-trait = "0.1" anyhow = "1.0" @@ -35,10 +34,11 @@ foreign-types-shared = "0.3.1" network-interface = "1.1.1" base64 = "0.21" uuid = { version = "1.6.1", features = ["v4", "fast-rng", "macro-diagnostics", "serde"] } -boring = { git = "https://github.com/Watfaq/boring.git", rev = "58d5e7c66b537989bde45d20ce54aff11de1bcea" } -boring-sys = { git = "https://github.com/Watfaq/boring.git", rev = "58d5e7c66b537989bde45d20ce54aff11de1bcea" } -hyper-boring = { git = "https://github.com/Watfaq/boring.git", rev = "58d5e7c66b537989bde45d20ce54aff11de1bcea" } -tokio-boring = { git = "https://github.com/Watfaq/boring.git", rev = "58d5e7c66b537989bde45d20ce54aff11de1bcea" } +boring = "4.2.0" +boring-sys = "4.2.0" +hyper-boring = "4.2.0" +tokio-boring = "4.2.0" + ip_network_table-deps-treebitmap = "0.5.0" once_cell = "1.18.0" @@ -54,7 +54,9 @@ hmac = "0.12.1" sha2 = "0.10.8" md-5 = "0.10.5" chacha20poly1305 = "0.10" +aes = "0.8.3" aes-gcm = "0.10" +cfb-mode = "0.8.2" filetime = "0.2" axum = { version = "0.7", features = ["ws"] } tower-http = { version = "0.5.0", features = ["fs", "trace", "cors"] } @@ -78,6 +80,7 @@ hickory-server = { version = "0.24", features = ["dns-over-rustls", "dns-over-ht hickory-proto = { version = "0.24", features = ["dns-over-rustls", "dns-over-https-rustls"]} # DoH +# ideally we should make a CryptoProvider with boringssl and get rid of rings rustls = { version = "0.21", features=["dangerous_configuration"] } rustls-pemfile = "1.0.4" webpki-roots = "0.25" diff --git a/clash_lib/src/common/crypto.rs b/clash_lib/src/common/crypto.rs index 6ab2535b7..3fffe089b 100644 --- a/clash_lib/src/common/crypto.rs +++ b/clash_lib/src/common/crypto.rs @@ -2,153 +2,25 @@ use std::ffi::CStr; use crate::Error; +use aes::cipher::{AsyncStreamCipher, KeyIvInit}; use aes_gcm::aes::cipher::Unsigned; use aes_gcm::{AeadInPlace, KeyInit}; pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Result<()> { - unsafe { - data.reserve(boring_sys::EVP_MAX_BLOCK_LENGTH as _); - let ctx = boring_sys::EVP_CIPHER_CTX_new(); - let rv = boring_sys::EVP_EncryptInit_ex( - ctx, - match key.len() { - 16 => boring_sys::EVP_aes_128_cfb(), - 24 => boring_sys::EVP_aes_192_cfb(), - 32 => boring_sys::EVP_aes_256_cfb(), - _ => anyhow::bail!("invalid key length"), - }, - std::ptr::null_mut(), - key.as_ptr(), - iv.as_ptr(), - ); - - if rv != 1 { - boring_sys::EVP_CIPHER_CTX_free(ctx); - return Err(Error::Crypto( - CStr::from_ptr( - boring_sys::ERR_reason_error_string(boring_sys::ERR_get_error()) as _, - ) - .to_str() - .expect("openssl error string is not utf8") - .to_owned(), - ) - .into()); - } - - let mut out_len = 0; - let rv = boring_sys::EVP_EncryptUpdate( - ctx, - data.as_mut_ptr(), - &mut out_len, - data.as_ptr(), - data.len() as _, - ); - - if rv != 1 { - boring_sys::EVP_CIPHER_CTX_free(ctx); - return Err(Error::Crypto( - CStr::from_ptr( - boring_sys::ERR_reason_error_string(boring_sys::ERR_get_error()) as _, - ) - .to_str() - .expect("openssl error string is not utf8") - .to_owned(), - ) - .into()); - } - - let rv = boring_sys::EVP_EncryptFinal_ex( - ctx, - data.as_mut_ptr().offset(out_len as _), - &mut out_len, - ); - boring_sys::EVP_CIPHER_CTX_free(ctx); - - return if rv != 1 { - Err(Error::Crypto( - CStr::from_ptr( - boring_sys::ERR_reason_error_string(boring_sys::ERR_get_error()) as _, - ) - .to_str() - .expect("openssl error string is not utf8") - .to_owned(), - ) - .into()) - } else { - Ok(()) - }; + match key.len() { + 16 => Ok(cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data)), + 24 => Ok(cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data)), + 32 => Ok(cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data)), + _ => anyhow::bail!("invalid key length"), } } pub fn aes_cfb_decrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Result<()> { - unsafe { - let ctx = boring_sys::EVP_CIPHER_CTX_new(); - let rv = boring_sys::EVP_DecryptInit_ex( - ctx, - match key.len() { - 16 => boring_sys::EVP_aes_128_cfb(), - 24 => boring_sys::EVP_aes_192_cfb(), - 32 => boring_sys::EVP_aes_256_cfb(), - _ => anyhow::bail!("invalid key length"), - }, - std::ptr::null_mut(), - key.as_ptr(), - iv.as_ptr(), - ); - - if rv != 1 { - return Err(Error::Crypto( - CStr::from_ptr( - boring_sys::ERR_reason_error_string(boring_sys::ERR_get_error()) as _, - ) - .to_str() - .expect("openssl error string is not utf8") - .to_owned(), - ) - .into()); - } - - let mut out_len = 0; - let rv = boring_sys::EVP_DecryptUpdate( - ctx, - data.as_mut_ptr(), - &mut out_len, - data.as_ptr(), - data.len() as _, - ); - - if rv != 1 { - return Err(Error::Crypto( - CStr::from_ptr( - boring_sys::ERR_reason_error_string(boring_sys::ERR_get_error()) as _, - ) - .to_str() - .expect("openssl error string is not utf8") - .to_owned(), - ) - .into()); - } - - let rv = boring_sys::EVP_DecryptFinal_ex( - ctx, - data.as_mut_ptr().offset(out_len as _), - &mut out_len, - ); - boring_sys::EVP_CIPHER_CTX_free(ctx); - - return if rv != 1 { - Err(Error::Crypto( - CStr::from_ptr( - boring_sys::ERR_reason_error_string(boring_sys::ERR_get_error()) as _, - ) - .to_str() - .expect("openssl error string is not utf8") - .to_owned(), - ) - .into()) - } else { - Ok(()) - }; + match key.len() { + 16 => Ok(cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data)), + 24 => Ok(cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data)), + 32 => Ok(cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data)), + _ => anyhow::bail!("invalid key length"), } } diff --git a/clash_lib/src/proxy/transport/tls.rs b/clash_lib/src/proxy/transport/tls.rs index 55f127e61..6ae4464cf 100644 --- a/clash_lib/src/proxy/transport/tls.rs +++ b/clash_lib/src/proxy/transport/tls.rs @@ -1,13 +1,11 @@ -use std::{io, sync::Arc}; +use std::io; + +use boring::ssl::{SslConnector, SslMethod}; +use futures::TryFutureExt; -use rustls::{ClientConfig, ServerName}; use serde::Serialize; -use tokio_rustls::TlsConnector; -use crate::{ - common::tls::{self, GLOBAL_ROOT_STORE}, - proxy::AnyStream, -}; +use crate::{common::errors::map_io_error, proxy::AnyStream}; #[derive(Serialize, Clone)] pub struct TLSOptions { @@ -21,44 +19,39 @@ pub async fn wrap_stream( opt: TLSOptions, expected_alpn: Option<&str>, ) -> io::Result { - let mut tls_config = ClientConfig::builder() - .with_safe_defaults() - .with_root_certificates(GLOBAL_ROOT_STORE.clone()) - .with_no_client_auth(); - tls_config.alpn_protocols = opt - .alpn - .unwrap_or_default() - .into_iter() - .map(|x| x.as_bytes().to_vec()) - .collect(); + let mut ssl = SslConnector::builder(SslMethod::tls()).map_err(map_io_error)?; + + if let Some(alpns) = opt.alpn.as_ref() { + let wire = alpns + .into_iter() + .map(|a| [&[a.len() as u8], a.as_bytes()].concat()) + .collect::>>() + .concat(); + ssl.set_alpn_protos(&wire).map_err(map_io_error)?; + } if opt.skip_cert_verify { - tls_config - .dangerous() - .set_certificate_verifier(Arc::new(tls::DummyTlsVerifier {})); + ssl.set_verify(boring::ssl::SslVerifyMode::NONE); } - tls_config.key_log = Arc::new(rustls::KeyLogFile::new()); - - let connector = TlsConnector::from(Arc::new(tls_config)); - let dns_name = ServerName::try_from(opt.sni.as_str()) - .unwrap_or_else(|_| panic!("invalid server name: {}", opt.sni)); - - let c = connector.connect(dns_name, stream).await.and_then(|x| { - if let Some(expected_alpn) = expected_alpn { - if x.get_ref().1.alpn_protocol() != Some(expected_alpn.as_bytes()) { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "unexpected alpn protocol: {:?}, expected: {:?}", - x.get_ref().1.alpn_protocol(), - expected_alpn - ), - )); + let c = tokio_boring::connect(ssl.build().configure().unwrap(), &opt.sni, stream) + .map_err(map_io_error) + .await + .and_then(|x| { + if let Some(expected_alpn) = expected_alpn { + if x.ssl().selected_alpn_protocol() != Some(expected_alpn.as_bytes()) { + return Err(io::Error::new( + io::ErrorKind::Other, + format!( + "unexpected alpn protocol: {:?}, expected: {:?}", + x.ssl().selected_alpn_protocol(), + expected_alpn + ), + )); + } } - } - Ok(x) - }); + Ok(x) + }); c.map(|x| Box::new(x) as _) } diff --git a/deps/boringssl/src b/deps/boringssl/src deleted file mode 160000 index 410247096..000000000 --- a/deps/boringssl/src +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 410247096a96910339f7ca8aaec479f19316152b From 1f9ab89544e16ec1bae4788c22be7d3d989e6efd Mon Sep 17 00:00:00 2001 From: dev0 Date: Mon, 1 Jan 2024 02:59:20 +1100 Subject: [PATCH 2/5] clippy --- clash_lib/src/common/crypto.rs | 30 ++++++++++++++++++++++------ clash_lib/src/proxy/transport/tls.rs | 2 +- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/clash_lib/src/common/crypto.rs b/clash_lib/src/common/crypto.rs index 3fffe089b..83a3d13cc 100644 --- a/clash_lib/src/common/crypto.rs +++ b/clash_lib/src/common/crypto.rs @@ -8,18 +8,36 @@ use aes_gcm::{AeadInPlace, KeyInit}; pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Result<()> { match key.len() { - 16 => Ok(cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data)), - 24 => Ok(cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data)), - 32 => Ok(cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data)), + 16 => { + cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); + Ok(()) + }, + 24 => { + cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); + Ok(()) + }, + 32 => { + cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); + Ok(()) + }, _ => anyhow::bail!("invalid key length"), } } pub fn aes_cfb_decrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Result<()> { match key.len() { - 16 => Ok(cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data)), - 24 => Ok(cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data)), - 32 => Ok(cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data)), + 16 => { + cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); + Ok(()) + }, + 24 => { + cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); + Ok(()) + }, + 32 => { + cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); + Ok(()) + }, _ => anyhow::bail!("invalid key length"), } } diff --git a/clash_lib/src/proxy/transport/tls.rs b/clash_lib/src/proxy/transport/tls.rs index 6ae4464cf..f3c56c951 100644 --- a/clash_lib/src/proxy/transport/tls.rs +++ b/clash_lib/src/proxy/transport/tls.rs @@ -23,7 +23,7 @@ pub async fn wrap_stream( if let Some(alpns) = opt.alpn.as_ref() { let wire = alpns - .into_iter() + .iter() .map(|a| [&[a.len() as u8], a.as_bytes()].concat()) .collect::>>() .concat(); From 8cc2ab861b584993f20fb749013448b699ffc444 Mon Sep 17 00:00:00 2001 From: dev0 Date: Mon, 1 Jan 2024 02:59:42 +1100 Subject: [PATCH 3/5] fmt --- clash_lib/src/common/crypto.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clash_lib/src/common/crypto.rs b/clash_lib/src/common/crypto.rs index 83a3d13cc..0ce030d20 100644 --- a/clash_lib/src/common/crypto.rs +++ b/clash_lib/src/common/crypto.rs @@ -11,15 +11,15 @@ pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Res 16 => { cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); Ok(()) - }, + } 24 => { cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); Ok(()) - }, + } 32 => { cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); Ok(()) - }, + } _ => anyhow::bail!("invalid key length"), } } @@ -29,15 +29,15 @@ pub fn aes_cfb_decrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Res 16 => { cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); Ok(()) - }, + } 24 => { cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); Ok(()) - }, + } 32 => { cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); Ok(()) - }, + } _ => anyhow::bail!("invalid key length"), } } From 7f4571c71fd281b73ca57998f22ca88fafe8bfa4 Mon Sep 17 00:00:00 2001 From: dev0 Date: Mon, 1 Jan 2024 03:04:37 +1100 Subject: [PATCH 4/5] clippy --- clash_lib/src/common/crypto.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clash_lib/src/common/crypto.rs b/clash_lib/src/common/crypto.rs index 0ce030d20..e5f4771aa 100644 --- a/clash_lib/src/common/crypto.rs +++ b/clash_lib/src/common/crypto.rs @@ -6,7 +6,7 @@ use aes::cipher::{AsyncStreamCipher, KeyIvInit}; use aes_gcm::aes::cipher::Unsigned; use aes_gcm::{AeadInPlace, KeyInit}; -pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Result<()> { +pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut [u8]) -> anyhow::Result<()> { match key.len() { 16 => { cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); @@ -24,7 +24,7 @@ pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Res } } -pub fn aes_cfb_decrypt(key: &[u8], iv: &[u8], data: &mut Vec) -> anyhow::Result<()> { +pub fn aes_cfb_decrypt(key: &[u8], iv: &[u8], data: &mut [u8]) -> anyhow::Result<()> { match key.len() { 16 => { cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); From 3ba5b65de4386df5dde604e8ea1387bdcb596940 Mon Sep 17 00:00:00 2001 From: dev0 Date: Mon, 1 Jan 2024 04:12:38 +1100 Subject: [PATCH 5/5] fix --- clash_lib/src/common/crypto.rs | 8 ++++---- clash_lib/src/lib.rs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/clash_lib/src/common/crypto.rs b/clash_lib/src/common/crypto.rs index e5f4771aa..10b32c640 100644 --- a/clash_lib/src/common/crypto.rs +++ b/clash_lib/src/common/crypto.rs @@ -9,7 +9,7 @@ use aes_gcm::{AeadInPlace, KeyInit}; pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut [u8]) -> anyhow::Result<()> { match key.len() { 16 => { - cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); + cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); Ok(()) } 24 => { @@ -17,7 +17,7 @@ pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut [u8]) -> anyhow::Result Ok(()) } 32 => { - cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); + cfb_mode::Encryptor::::new(key.into(), iv.into()).encrypt(data); Ok(()) } _ => anyhow::bail!("invalid key length"), @@ -27,7 +27,7 @@ pub fn aes_cfb_encrypt(key: &[u8], iv: &[u8], data: &mut [u8]) -> anyhow::Result pub fn aes_cfb_decrypt(key: &[u8], iv: &[u8], data: &mut [u8]) -> anyhow::Result<()> { match key.len() { 16 => { - cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); + cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); Ok(()) } 24 => { @@ -35,7 +35,7 @@ pub fn aes_cfb_decrypt(key: &[u8], iv: &[u8], data: &mut [u8]) -> anyhow::Result Ok(()) } 32 => { - cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); + cfb_mode::Decryptor::::new(key.into(), iv.into()).decrypt(data); Ok(()) } _ => anyhow::bail!("invalid key length"), diff --git a/clash_lib/src/lib.rs b/clash_lib/src/lib.rs index 389d6f337..82f12cdd4 100644 --- a/clash_lib/src/lib.rs +++ b/clash_lib/src/lib.rs @@ -471,12 +471,11 @@ mod tests { use std::time::Duration; #[test] - #[ignore] fn start_and_stop() { let conf = r#" socks-port: 7891 bind-address: 127.0.0.1 - mmdb: "clash_lib/tests/data/Country.mmdb" + mmdb: "tests/data/Country.mmdb" "#; let handle = thread::spawn(|| {