diff --git a/Cargo.lock b/Cargo.lock index 29c23bf8..02be0ee4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -437,7 +437,7 @@ dependencies = [ "postmark", "rand", "reqwest 0.11.27", - "rustls 0.21.12", + "rustls 0.23.12", "rustls-pemfile 2.1.2", "semver", "serde", @@ -544,9 +544,9 @@ dependencies = [ [[package]] name = "axum-server" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad46c3ec4e12f4a4b6835e173ba21c25e484c9d02b49770bf006ce5367c036" +checksum = "56bac90848f6a9393ac03c63c640925c4b7c8ca21654de40d53f55964667c7d8" dependencies = [ "arc-swap", "bytes", @@ -557,10 +557,11 @@ dependencies = [ "hyper 1.4.1", "hyper-util", "pin-project-lite", - "rustls 0.21.12", + "rustls 0.23.12", "rustls-pemfile 2.1.2", + "rustls-pki-types", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.0", "tower", "tower-service", ] @@ -3572,9 +3573,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" diff --git a/crates/atuin-server/Cargo.toml b/crates/atuin-server/Cargo.toml index 7f8753b3..5defbf3a 100644 --- a/crates/atuin-server/Cargo.toml +++ b/crates/atuin-server/Cargo.toml @@ -25,13 +25,13 @@ base64 = { workspace = true } rand = { workspace = true } tokio = { workspace = true } async-trait = { workspace = true } -axum = "0.7.4" -axum-server = { version = "0.6.0", features = ["tls-rustls"] } +axum = "0.7" +axum-server = { version = "0.7", features = ["tls-rustls-no-provider"] } fs-err = { workspace = true } tower = { workspace = true } -tower-http = { version = "0.5.1", features = ["trace"] } +tower-http = { version = "0.5", features = ["trace"] } reqwest = { workspace = true } -rustls = "0.21" +rustls = { version = "0.23", features = ["ring"], default-features = false } rustls-pemfile = "2.1" argon2 = "0.5" semver = { workspace = true } diff --git a/crates/atuin-server/src/lib.rs b/crates/atuin-server/src/lib.rs index a0c104dc..4c1619bc 100644 --- a/crates/atuin-server/src/lib.rs +++ b/crates/atuin-server/src/lib.rs @@ -2,19 +2,18 @@ use std::future::Future; use std::net::SocketAddr; -use std::sync::Arc; use atuin_server_database::Database; use axum::{serve, Router}; +use axum_server::tls_rustls::RustlsConfig; use axum_server::Handle; -use eyre::{Context, Result}; +use eyre::{eyre, Context, Result}; mod handlers; mod metrics; mod router; mod utils; -use rustls::ServerConfig; pub use settings::example_config; pub use settings::Settings; @@ -83,16 +82,19 @@ async fn launch_with_tls( addr: SocketAddr, shutdown: impl Future, ) -> Result<()> { - let certificates = settings.tls.certificates()?; - let pkey = settings.tls.private_key()?; - - let server_config = ServerConfig::builder() - .with_safe_defaults() - .with_no_client_auth() - .with_single_cert(certificates, pkey)?; - - let server_config = Arc::new(server_config); - let rustls_config = axum_server::tls_rustls::RustlsConfig::from_config(server_config); + let crypto_provider = rustls::crypto::ring::default_provider().install_default(); + if crypto_provider.is_err() { + return Err(eyre!("Failed to install default crypto provider")); + } + let rustls_config = RustlsConfig::from_pem_file( + settings.tls.cert_path.clone(), + settings.tls.pkey_path.clone(), + ) + .await; + if rustls_config.is_err() { + return Err(eyre!("Failed to load TLS key and/or certificate")); + } + let rustls_config = rustls_config.unwrap(); let r = make_router::(settings).await?; diff --git a/crates/atuin-server/src/settings.rs b/crates/atuin-server/src/settings.rs index b5941c65..db260511 100644 --- a/crates/atuin-server/src/settings.rs +++ b/crates/atuin-server/src/settings.rs @@ -1,7 +1,7 @@ use std::{io::prelude::*, path::PathBuf}; use config::{Config, Environment, File as ConfigFile, FileFormat}; -use eyre::{bail, eyre, Context, Result}; +use eyre::{eyre, Result}; use fs_err::{create_dir_all, File}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -146,43 +146,3 @@ pub struct Tls { pub cert_path: PathBuf, pub pkey_path: PathBuf, } - -impl Tls { - pub fn certificates(&self) -> Result> { - let cert_file = std::fs::File::open(&self.cert_path) - .with_context(|| format!("tls.cert_path {:?} is missing", self.cert_path))?; - let mut reader = std::io::BufReader::new(cert_file); - let certs: Vec<_> = rustls_pemfile::certs(&mut reader) - .map(|c| c.map(|c| rustls::Certificate(c.to_vec()))) - .collect::, _>>() - .with_context(|| format!("tls.cert_path {:?} is invalid", self.cert_path))?; - - if certs.is_empty() { - bail!( - "tls.cert_path {:?} must have at least one certificate", - self.cert_path - ); - } - - Ok(certs) - } - - pub fn private_key(&self) -> Result { - let pkey_file = std::fs::File::open(&self.pkey_path) - .with_context(|| format!("tls.pkey_path {:?} is missing", self.pkey_path))?; - let mut reader = std::io::BufReader::new(pkey_file); - let keys = rustls_pemfile::pkcs8_private_keys(&mut reader) - .map(|c| c.map(|c| rustls::PrivateKey(c.secret_pkcs8_der().to_vec()))) - .collect::, _>>() - .with_context(|| format!("tls.pkey_path {:?} is not PKCS8-encoded", self.pkey_path))?; - - if keys.is_empty() { - bail!( - "tls.pkey_path {:?} must have at least one private key", - self.pkey_path - ); - } - - Ok(keys[0].clone()) - } -}