From c399ff2bfad765e126a1acdf2eaf6fcc40c299e1 Mon Sep 17 00:00:00 2001 From: Valentin Tolmer Date: Fri, 15 Jul 2022 14:59:15 +0200 Subject: [PATCH] server: switch from OpenSSL to Rustls --- Cargo.lock | 183 ++++++++++++++++++++++++++------ server/Cargo.toml | 19 ++-- server/src/infra/ldap_server.rs | 45 ++++---- 3 files changed, 183 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 185a1eb..1d6725e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,7 +199,9 @@ dependencies = [ "futures-core", "http", "log", + "tokio-rustls 0.22.0", "tokio-util 0.6.10", + "webpki-roots 0.21.1", ] [[package]] @@ -1577,17 +1579,6 @@ dependencies = [ "digest", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - [[package]] name = "http" version = "0.2.8" @@ -1901,18 +1892,19 @@ dependencies = [ "fastrand", "futures-io", "futures-util", - "hostname", "httpdate", "idna", "mime", - "native-tls", "nom 7.1.1", "once_cell", "quoted_printable", + "rustls 0.20.6", + "rustls-pemfile", "serde", "socket2", "tokio", - "tokio-native-tls", + "tokio-rustls 0.23.4", + "webpki-roots 0.22.4", ] [[package]] @@ -1992,11 +1984,11 @@ dependencies = [ "lldap_auth", "log", "mockall", - "native-tls", "opaque-ke", - "openssl-sys", "orion", "rand 0.8.5", + "rustls 0.20.6", + "rustls-pemfile", "sea-query", "sea-query-binder", "secstr", @@ -2008,7 +2000,7 @@ dependencies = [ "thiserror", "time 0.2.27", "tokio", - "tokio-native-tls", + "tokio-rustls 0.23.4", "tokio-stream", "tokio-util 0.6.10", "tracing", @@ -2099,12 +2091,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "matchers" version = "0.1.0" @@ -2455,15 +2441,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "111.22.0+1.1.1q" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f31f0d509d1c1ae9cada2f9539ff8f37933831fd5098879e482aa687d659853" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.74" @@ -2473,7 +2450,6 @@ dependencies = [ "autocfg 1.1.0", "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -2939,6 +2915,21 @@ dependencies = [ "winreg", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "rsa" version = "0.5.0" @@ -2995,6 +2986,40 @@ dependencies = [ "semver 1.0.12", ] +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64", + "log", + "ring", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" +dependencies = [ + "base64", +] + [[package]] name = "ryu" version = "1.0.10" @@ -3017,6 +3042,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sea-query" version = "0.25.2" @@ -3363,6 +3408,7 @@ dependencies = [ "percent-encoding", "rand 0.8.5", "rsa", + "rustls 0.19.1", "serde", "serde_json", "sha-1", @@ -3374,6 +3420,8 @@ dependencies = [ "thiserror", "tokio-stream", "url", + "webpki 0.21.4", + "webpki-roots 0.21.1", "whoami", ] @@ -3403,10 +3451,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" dependencies = [ "actix-rt", - "native-tls", "once_cell", "tokio", - "tokio-native-tls", + "tokio-rustls 0.22.0", ] [[package]] @@ -3692,6 +3739,28 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls 0.19.1", + "tokio", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.6", + "tokio", + "webpki 0.22.0", +] + [[package]] name = "tokio-stream" version = "0.1.9" @@ -3938,6 +4007,12 @@ dependencies = [ "void", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.2.2" @@ -4132,6 +4207,44 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki 0.21.4", +] + +[[package]] +name = "webpki-roots" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +dependencies = [ + "webpki 0.22.0", +] + [[package]] name = "whoami" version = "1.2.1" diff --git a/server/Cargo.toml b/server/Cargo.toml index b63d7d0..cb4cefc 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -11,7 +11,6 @@ actix-http = "=3.0.0-beta.9" actix-rt = "2.2.0" actix-server = "=2.0.0-beta.5" actix-service = "2.0.0" -actix-tls = "=3.0.0-beta.5" actix-web = "=4.0.0-beta.8" actix-web-httpauth = "0.6.0-beta.2" anyhow = "*" @@ -30,21 +29,22 @@ juniper_actix = "0.4.0" jwt = "0.13" ldap3_server = "=0.1.11" log = "*" -native-tls = "0.2.10" orion = "0.16" +rustls = "0.20" serde = "*" serde_json = "1" sha2 = "0.9" sqlx-core = "0.5.11" thiserror = "*" time = "0.2" -tokio-native-tls = "0.3" +tokio-rustls = "0.23" tokio-stream = "*" tokio-util = "0.6.3" tracing = "*" tracing-actix-web = "0.4.0-beta.7" tracing-attributes = "^0.1.21" tracing-log = "*" +rustls-pemfile = "1.0.0" [dependencies.chrono] features = ["serde"] @@ -63,7 +63,8 @@ version = "0.3" features = ["env-filter", "tracing-log"] [dependencies.lettre] -features = ["builder", "serde", "smtp-transport", "tokio1-native-tls", "tokio1"] +features = ["builder", "serde", "smtp-transport", "tokio1-rustls-tls"] +default-features = false version = "0.10.0-rc.3" [dependencies.sqlx] @@ -74,7 +75,7 @@ features = [ "macros", "mysql", "postgres", - "runtime-actix-native-tls", + "runtime-actix-rustls", "sqlite", ] @@ -92,10 +93,6 @@ features = ["with-chrono", "sqlx-sqlite", "sqlx-any"] [dependencies.opaque-ke] version = "0.6" -[dependencies.openssl-sys] -features = ["vendored"] -version = "*" - [dependencies.rand] features = ["small_rng", "getrandom"] version = "0.8" @@ -116,5 +113,9 @@ version = "*" features = ["smallvec", "chrono", "tokio"] version = "^0.1.4" +[dependencies.actix-tls] +features = ["default", "rustls"] +version = "=3.0.0-beta.5" + [dev-dependencies] mockall = "0.9.1" diff --git a/server/src/infra/ldap_server.rs b/server/src/infra/ldap_server.rs index 9a48c2b..9a1c55c 100644 --- a/server/src/infra/ldap_server.rs +++ b/server/src/infra/ldap_server.rs @@ -10,8 +10,7 @@ use actix_server::ServerBuilder; use actix_service::{fn_service, ServiceFactoryExt}; use anyhow::{Context, Result}; use ldap3_server::{proto::LdapMsg, LdapCodec}; -use native_tls::{Identity, TlsAcceptor}; -use tokio_native_tls::TlsAcceptor as NativeTlsAcceptor; +use tokio_rustls::TlsAcceptor as RustlsTlsAcceptor; use tokio_util::codec::{FramedRead, FramedWrite}; use tracing::{debug, error, info, instrument}; @@ -54,19 +53,6 @@ where Ok(true) } -fn get_file_as_byte_vec(filename: &str) -> Result> { - (|| -> Result> { - use std::fs::{metadata, File}; - use std::io::Read; - let mut f = File::open(&filename).context("file not found")?; - let metadata = metadata(&filename).context("unable to read metadata")?; - let mut buffer = vec![0; metadata.len() as usize]; - f.read(&mut buffer).context("buffer overflow")?; - Ok(buffer) - })() - .context(format!("while reading file {}", filename)) -} - #[instrument(skip_all, level = "info", name = "LDAP session")] async fn handle_ldap_stream( stream: Stream, @@ -103,12 +89,31 @@ where Ok(requests.into_inner().unsplit(resp.into_inner())) } -fn get_tls_acceptor(config: &Configuration) -> Result { +fn get_tls_acceptor(config: &Configuration) -> Result { + use rustls::{Certificate, PrivateKey, ServerConfig}; + use rustls_pemfile::{certs, pkcs8_private_keys}; + use std::{fs::File, io::BufReader}; // Load TLS key and cert files - let cert_file = get_file_as_byte_vec(&config.ldaps_options.cert_file)?; - let key_file = get_file_as_byte_vec(&config.ldaps_options.key_file)?; - let identity = Identity::from_pkcs8(&cert_file, &key_file)?; - Ok(TlsAcceptor::new(identity)?.into()) + let certs = certs(&mut BufReader::new(File::open( + &config.ldaps_options.cert_file, + )?))? + .into_iter() + .map(Certificate) + .collect::>(); + let private_key = pkcs8_private_keys(&mut BufReader::new(File::open( + &config.ldaps_options.key_file, + )?))? + .into_iter() + .map(PrivateKey) + .next() + .ok_or_else(|| anyhow::anyhow!("No private keys"))?; + let server_config = std::sync::Arc::new( + ServerConfig::builder() + .with_safe_defaults() + .with_no_client_auth() + .with_single_cert(certs, private_key)?, + ); + Ok(server_config.into()) } pub fn build_ldap_server(