You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-08-07 17:03:01 +03:00
Upgrade rustls
This commit is contained in:
29
Cargo.lock
generated
29
Cargo.lock
generated
@@ -161,9 +161,9 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
|
||||
[[package]]
|
||||
name = "apalis-core"
|
||||
version = "0.4.9"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1deb48475efcdece1f23a0553209ee842f264c2a5e9bcc4928bfa6a15a044cde"
|
||||
checksum = "5dbe998f2a77a65433e3e893f7ffba5b0c4835a9601ccab02aa868d1d3ed71eb"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
@@ -184,9 +184,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "apalis-cron"
|
||||
version = "0.4.9"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43310b7e0132f9520b09224fb6faafb32eec82a672aa79c09e46b5b488ed505b"
|
||||
checksum = "9fc57450bd6a857d2370bb5504cf3d7f2a1fb85c7b68bdb7f92f50aac0e26aac"
|
||||
dependencies = [
|
||||
"apalis-core",
|
||||
"async-stream",
|
||||
@@ -2252,7 +2252,7 @@ dependencies = [
|
||||
"http 0.2.11",
|
||||
"hyper",
|
||||
"rustls 0.22.2",
|
||||
"rustls-native-certs 0.7.0",
|
||||
"rustls-native-certs",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
@@ -2910,6 +2910,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rustls-pemfile 2.0.0",
|
||||
"rustls-pki-types",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3053,7 +3054,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"opentelemetry",
|
||||
"rustls 0.22.2",
|
||||
"rustls-native-certs 0.6.3",
|
||||
"rustls-native-certs",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
@@ -4441,9 +4442,9 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
|
||||
|
||||
[[package]]
|
||||
name = "psl"
|
||||
version = "2.1.18"
|
||||
version = "2.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e109d6dd5679c4dce63a1c6bd7b61ed6758368af1ccf0701dfb02c021fbb9d0d"
|
||||
checksum = "9667155e4837711406c6a5d26be83cdf53932f182d2ce8785529fd2c1a7e9e97"
|
||||
dependencies = [
|
||||
"psl-types",
|
||||
]
|
||||
@@ -4804,18 +4805,6 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile 1.0.4",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.7.0"
|
||||
|
@@ -285,11 +285,8 @@ where
|
||||
|
||||
pub fn build_tls_server_config(config: &HttpTlsConfig) -> Result<ServerConfig, anyhow::Error> {
|
||||
let (key, chain) = config.load()?;
|
||||
let key = rustls::PrivateKey(key);
|
||||
let chain = chain.into_iter().map(rustls::Certificate).collect();
|
||||
|
||||
let mut config = rustls::ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(chain, key)
|
||||
.context("failed to build TLS server config")?;
|
||||
|
@@ -32,6 +32,7 @@ serde_with = { version = "3.4.0", features = ["hex", "chrono"] }
|
||||
serde_json.workspace = true
|
||||
|
||||
pem-rfc7468 = "0.7.0"
|
||||
rustls-pki-types = "1.1.0"
|
||||
rustls-pemfile = "2.0.0"
|
||||
rand.workspace = true
|
||||
rand_chacha = "0.3.1"
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
#![allow(deprecated)]
|
||||
|
||||
use std::{borrow::Cow, io::Cursor, ops::Deref};
|
||||
use std::{borrow::Cow, io::Cursor};
|
||||
|
||||
use anyhow::bail;
|
||||
use async_trait::async_trait;
|
||||
@@ -22,6 +22,7 @@ use camino::Utf8PathBuf;
|
||||
use ipnetwork::IpNetwork;
|
||||
use mas_keystore::PrivateKey;
|
||||
use rand::Rng;
|
||||
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
@@ -197,7 +198,9 @@ impl TlsConfig {
|
||||
/// - a password was provided but the key was not encrypted
|
||||
/// - decoding the certificate chain as PEM
|
||||
/// - the certificate chain is empty
|
||||
pub fn load(&self) -> Result<(Vec<u8>, Vec<Vec<u8>>), anyhow::Error> {
|
||||
pub fn load(
|
||||
&self,
|
||||
) -> Result<(PrivateKeyDer<'static>, Vec<CertificateDer<'static>>), anyhow::Error> {
|
||||
let password = match &self.password {
|
||||
Some(PasswordOrFile::Password(password)) => Some(Cow::Borrowed(password.as_str())),
|
||||
Some(PasswordOrFile::PasswordFile(path)) => {
|
||||
@@ -230,9 +233,7 @@ impl TlsConfig {
|
||||
|
||||
// Re-serialize the key to PKCS#8 DER, so rustls can consume it
|
||||
let key = key.to_pkcs8_der()?;
|
||||
// This extracts the Vec out of the Zeroizing by copying it
|
||||
// XXX: maybe we should keep that zeroizing?
|
||||
let key = key.deref().clone();
|
||||
let key = PrivatePkcs8KeyDer::from(key.to_vec()).into();
|
||||
|
||||
let certificate_chain_pem = match &self.certificate {
|
||||
CertificateOrFile::Certificate(pem) => Cow::Borrowed(pem.as_str()),
|
||||
@@ -240,7 +241,9 @@ impl TlsConfig {
|
||||
};
|
||||
|
||||
let mut certificate_chain_reader = Cursor::new(certificate_chain_pem.as_bytes());
|
||||
let certificate_chain = rustls_pemfile::certs(&mut certificate_chain_reader)?;
|
||||
let certificate_chain: Result<Vec<_>, _> =
|
||||
rustls_pemfile::certs(&mut certificate_chain_reader).collect();
|
||||
let certificate_chain = certificate_chain?;
|
||||
|
||||
if certificate_chain.is_empty() {
|
||||
bail!("TLS certificate chain is empty (or invalid)")
|
||||
|
@@ -30,7 +30,7 @@ pub use self::{
|
||||
compat_sessions::{CompatSession, CompatSsoLogin},
|
||||
cursor::{Cursor, NodeCursor},
|
||||
node::{Node, NodeType},
|
||||
oauth::{OAuth2Client, OAuth2Consent, OAuth2Session},
|
||||
oauth::{OAuth2Client, OAuth2Session},
|
||||
upstream_oauth::{UpstreamOAuth2Link, UpstreamOAuth2Provider},
|
||||
users::{User, UserEmail},
|
||||
viewer::{Anonymous, Viewer, ViewerSession},
|
||||
|
@@ -23,7 +23,7 @@ hyper-rustls = { version = "0.25.0", features = ["http1", "http2"], default-feat
|
||||
once_cell = "1.18.0"
|
||||
opentelemetry.workspace = true
|
||||
rustls = { version = "0.22.2", optional = true }
|
||||
rustls-native-certs = { version = "0.6.3", optional = true }
|
||||
rustls-native-certs = { version = "0.7.0", optional = true }
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_urlencoded = "0.7.1"
|
||||
|
@@ -75,15 +75,11 @@ async fn tls_roots() -> Result<rustls::RootCertStore, NativeRootsInitError> {
|
||||
#[cfg(feature = "webpki-roots")]
|
||||
#[allow(clippy::unused_async)]
|
||||
async fn tls_roots() -> Result<rustls::RootCertStore, Infallible> {
|
||||
let mut roots = rustls::RootCertStore::empty();
|
||||
roots.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
|
||||
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||
ta.subject,
|
||||
ta.spki,
|
||||
ta.name_constraints,
|
||||
)
|
||||
}));
|
||||
Ok(roots)
|
||||
let root_store = rustls::RootCertStore {
|
||||
roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(),
|
||||
};
|
||||
|
||||
Ok(root_store)
|
||||
}
|
||||
|
||||
#[cfg(feature = "native-roots")]
|
||||
@@ -131,7 +127,6 @@ pub enum NativeRootsLoadError {
|
||||
async fn make_tls_config() -> Result<rustls::ClientConfig, ClientInitError> {
|
||||
let roots = tls_roots().await?;
|
||||
let tls_config = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_root_certificates(roots)
|
||||
.with_no_client_auth();
|
||||
|
||||
|
@@ -24,10 +24,7 @@ use anyhow::Context;
|
||||
use hyper::{service::service_fn, Request, Response};
|
||||
use mas_listener::{server::Server, shutdown::ShutdownStream, ConnectionInfo};
|
||||
use tokio::signal::unix::SignalKind;
|
||||
use tokio_rustls::rustls::{
|
||||
server::AllowAnyAnonymousOrAuthenticatedClient, Certificate, PrivateKey, RootCertStore,
|
||||
ServerConfig,
|
||||
};
|
||||
use tokio_rustls::rustls::{server::WebPkiClientVerifier, RootCertStore, ServerConfig};
|
||||
|
||||
static CA_CERT_PEM: &[u8] = include_bytes!("./certs/ca.pem");
|
||||
static SERVER_CERT_PEM: &[u8] = include_bytes!("./certs/server.pem");
|
||||
@@ -75,27 +72,30 @@ async fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
fn load_tls_config() -> Result<Arc<ServerConfig>, anyhow::Error> {
|
||||
let mut ca_cert_reader = BufReader::new(CA_CERT_PEM);
|
||||
let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader).context("Invalid CA certificate")?;
|
||||
let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.context("Invalid CA certificate")?;
|
||||
let mut ca_cert_store = RootCertStore::empty();
|
||||
ca_cert_store.add_parsable_certificates(&ca_cert);
|
||||
ca_cert_store.add_parsable_certificates(ca_cert);
|
||||
|
||||
let mut server_cert_reader = BufReader::new(SERVER_CERT_PEM);
|
||||
let server_cert: Vec<_> = rustls_pemfile::certs(&mut server_cert_reader)
|
||||
.context("Invalid server certificate")?
|
||||
.into_iter()
|
||||
.map(Certificate)
|
||||
.collect();
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.context("Invalid server certificate")?;
|
||||
|
||||
let mut server_key_reader = BufReader::new(SERVER_KEY_PEM);
|
||||
let mut server_key = rustls_pemfile::rsa_private_keys(&mut server_key_reader)
|
||||
let server_key = rustls_pemfile::rsa_private_keys(&mut server_key_reader)
|
||||
.next()
|
||||
.context("No RSA private key found")?
|
||||
.context("Invalid server TLS keys")?;
|
||||
let server_key = PrivateKey(server_key.pop().context("Missing server TLS key")?);
|
||||
|
||||
let client_cert_verifier = Arc::new(AllowAnyAnonymousOrAuthenticatedClient::new(ca_cert_store));
|
||||
let client_cert_verifier = WebPkiClientVerifier::builder(Arc::new(ca_cert_store))
|
||||
.allow_unauthenticated()
|
||||
.build()?;
|
||||
|
||||
let mut config = ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_client_cert_verifier(client_cert_verifier)
|
||||
.with_single_cert(server_cert, server_key)?;
|
||||
.with_single_cert(server_cert, server_key.into())?;
|
||||
config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
||||
|
||||
Ok(Arc::new(config))
|
||||
|
@@ -20,7 +20,10 @@ use std::{
|
||||
|
||||
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
||||
use tokio_rustls::{
|
||||
rustls::{Certificate, ProtocolVersion, ServerConfig, ServerConnection, SupportedCipherSuite},
|
||||
rustls::{
|
||||
pki_types::CertificateDer, ProtocolVersion, ServerConfig, ServerConnection,
|
||||
SupportedCipherSuite,
|
||||
},
|
||||
TlsAcceptor,
|
||||
};
|
||||
|
||||
@@ -31,7 +34,7 @@ pub struct TlsStreamInfo {
|
||||
pub negotiated_cipher_suite: SupportedCipherSuite,
|
||||
pub sni_hostname: Option<String>,
|
||||
pub alpn_protocol: Option<Vec<u8>>,
|
||||
pub peer_certificates: Option<Vec<Certificate>>,
|
||||
pub peer_certificates: Option<Vec<CertificateDer<'static>>>,
|
||||
}
|
||||
|
||||
impl TlsStreamInfo {
|
||||
@@ -98,7 +101,13 @@ impl<T> MaybeTlsStream<T> {
|
||||
|
||||
let sni_hostname = conn.server_name().map(ToOwned::to_owned);
|
||||
let alpn_protocol = conn.alpn_protocol().map(ToOwned::to_owned);
|
||||
let peer_certificates = conn.peer_certificates().map(ToOwned::to_owned);
|
||||
let peer_certificates = conn.peer_certificates().map(|certs| {
|
||||
certs
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(CertificateDer::into_owned)
|
||||
.collect()
|
||||
});
|
||||
Some(TlsStreamInfo {
|
||||
protocol_version,
|
||||
negotiated_cipher_suite,
|
||||
|
@@ -32,6 +32,10 @@ static MAS_USER_AGENT: HeaderValue = HeaderValue::from_static("mas-oidc-client/0
|
||||
|
||||
/// Constructs a [`HttpService`] using [hyper] as a backend.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If the native TLS root certificates fail to load
|
||||
///
|
||||
/// [hyper]: https://crates.io/crates/hyper
|
||||
#[must_use]
|
||||
pub fn hyper_service() -> HttpService {
|
||||
@@ -41,8 +45,8 @@ pub fn hyper_service() -> HttpService {
|
||||
http.enforce_http(false);
|
||||
|
||||
let tls_config = rustls::ClientConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_native_roots()
|
||||
.expect("Failed to load native TLS")
|
||||
.with_no_client_auth();
|
||||
|
||||
let https = HttpsConnectorBuilder::new()
|
||||
|
@@ -13,8 +13,8 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
apalis-core = { version = "0.4.7", features = ["extensions", "tokio-comp", "storage"] }
|
||||
apalis-cron = "0.4.7"
|
||||
apalis-core = { version = "=0.4.7", features = ["extensions", "tokio-comp", "storage"] }
|
||||
apalis-cron = "=0.4.7"
|
||||
async-stream = "0.3.5"
|
||||
async-trait = "0.1.74"
|
||||
chrono.workspace = true
|
||||
|
Reference in New Issue
Block a user