Skip to content

Commit e1092d3

Browse files
committed
Upgrade axum to latest version
1 parent 38d5c1c commit e1092d3

File tree

12 files changed

+827
-378
lines changed

12 files changed

+827
-378
lines changed

Cargo.lock

Lines changed: 720 additions & 248 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ async-tungstenite = { version = "0.23", features = [
8282
"tokio-runtime",
8383
"tokio-rustls-native-certs",
8484
] }
85-
axum = "0.6"
85+
axum = "0.8.1"
8686
axum-server = { version = "0.5.1", features = ["tls-rustls"] }
8787
backoff = { version = "0.4", features = ["tokio"] }
8888
base64 = "0.13"
@@ -116,7 +116,8 @@ http-body = "0.4"
116116
httparse = "1.9.3"
117117
humantime = "2.1.0"
118118
hyper = { version = "0.14", default-features = false }
119-
hyper-rustls = { version = "0.24", default-features = false, features = [
119+
hyper-util = { version = "0.1" }
120+
hyper-rustls = { version = "0.27.5", default-features = false, features = [
120121
"tokio-runtime",
121122
"tls12",
122123
"rustls-native-certs",
@@ -151,14 +152,14 @@ quote = "1"
151152
rand = "0.8"
152153
rcgen = { version = "0.12", features = ["pem", "zeroize"] }
153154
regex = "1.4"
154-
reqwest = { version = "0.11", default-features = false }
155+
reqwest = { version = "0.12", default-features = false }
155156
rpassword = "5.0"
156157
rstest = "0.16.0"
157-
rumqttc = "0.23"
158+
rumqttc = { git = "https://github.com/bytebeamio/rumqtt", ref = "49c3b5f81360299c316b052778905a7420bea579" }
158159
rumqttd = "0.19"
159-
rustls = "0.21.11"
160+
rustls = "0.23"
160161
rustls-native-certs = "0.6.3"
161-
rustls-pemfile = "1.0.1"
162+
rustls-pemfile = "2.2"
162163
serde = "1.0"
163164
serde_ignored = "0.1"
164165
serde_json = "1.0"
@@ -176,7 +177,7 @@ test-case = "3.2"
176177
thiserror = "1.0"
177178
time = "0.3"
178179
tokio = { version = "1.37", default-features = false }
179-
tokio-rustls = "0.24.1"
180+
tokio-rustls = "0.26.1"
180181
tokio-tungstenite = { version = "0.20.0" }
181182
tokio-util = { version = "0.7", features = ["codec"] }
182183
toml = "0.8"

crates/common/axum_tls/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repository = { workspace = true }
1010
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1111

1212
[features]
13-
error-matching = ["dep:reqwest"]
13+
error-matching = ["dep:reqwest", "dep:hyper-util"]
1414
test-helpers = ["dep:assert_matches", "error-matching"]
1515

1616
[dependencies]
@@ -22,6 +22,7 @@ camino = { workspace = true }
2222
futures = { workspace = true }
2323
hyper = { workspace = true }
2424
pin-project = { workspace = true }
25+
hyper-util = { workspace = true, features = ["client", "client-legacy"], optional = true }
2526
reqwest = { workspace = true, features = [
2627
"rustls-tls-native-roots",
2728
], optional = true }
@@ -37,6 +38,7 @@ yansi = { workspace = true }
3738

3839
[dev-dependencies]
3940
assert_matches = { workspace = true }
41+
hyper-util = { workspace = true, features = ["client", "client-legacy"] }
4042
rcgen = { workspace = true }
4143
reqwest = { workspace = true, features = ["rustls-tls-native-roots"] }
4244
tempfile = { workspace = true }

crates/common/axum_tls/src/acceptor.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use axum_server::tls_rustls::RustlsConfig;
99

1010
use futures::future::BoxFuture;
1111

12-
use rustls::ServerConfig;
12+
use tokio_rustls::rustls::ServerConfig;
1313

1414
use std::io;
1515
use std::sync::Arc;
@@ -88,7 +88,7 @@ where
8888
let (stream, service) = acceptor.accept(stream, service).await?;
8989
let server_conn = stream.get_ref().1;
9090
let cert = (|| {
91-
X509Certificate::from_der(&server_conn.peer_certificates()?.first()?.0).ok()
91+
X509Certificate::from_der(&server_conn.peer_certificates()?.first()?).ok()
9292
})();
9393
let certificate_info = TlsData {
9494
common_name: common_name(cert.as_ref()).map(Arc::from),
@@ -117,6 +117,10 @@ mod tests {
117117
use reqwest::Certificate;
118118
use reqwest::Client;
119119
use reqwest::Identity;
120+
use rustls::crypto::CryptoProvider;
121+
use rustls::pki_types::pem::PemObject as _;
122+
use rustls::pki_types::CertificateDer;
123+
use rustls::pki_types::PrivateKeyDer;
120124
use rustls::RootCertStore;
121125
use std::net::SocketAddr;
122126
use std::net::TcpListener;
@@ -169,7 +173,10 @@ mod tests {
169173

170174
#[tokio::test]
171175
async fn acceptor_rejects_untrusted_client_certificates() {
172-
let server = Server::with_trusted_roots(RootCertStore::empty());
176+
let permitted_certificate = rcgen::generate_simple_self_signed(vec!["not-my-client".into()]).unwrap();
177+
let mut roots = RootCertStore::empty();
178+
roots.add(permitted_certificate.serialize_der().unwrap().into()).unwrap();
179+
let server = Server::with_trusted_roots(roots);
173180
let client = Client::builder()
174181
.add_root_certificate(server.certificate.clone())
175182
.identity(identity_with_name("my-client"))
@@ -180,6 +187,7 @@ mod tests {
180187
.get_with_scheme(Scheme::HTTPS, &client)
181188
.await
182189
.unwrap_err();
190+
println!("{}", err);
183191
crate::error_matching::assert_error_matches(err, rustls::AlertDescription::UnknownCA);
184192
}
185193

@@ -188,7 +196,9 @@ mod tests {
188196
let client_cert = rcgen::generate_simple_self_signed(["my-client".into()]).unwrap();
189197
let identity = identity_from(&client_cert);
190198
let mut cert_store = RootCertStore::empty();
191-
cert_store.add_parsable_certificates(&[client_cert.serialize_der().unwrap()]);
199+
cert_store.add_parsable_certificates([CertificateDer::from(
200+
client_cert.serialize_der().unwrap(),
201+
)]);
192202

193203
let server = Server::with_trusted_roots(cert_store);
194204
let client = Client::builder()
@@ -247,6 +257,7 @@ mod tests {
247257
}
248258

249259
fn start(trusted_roots: Option<RootCertStore>) -> Self {
260+
let _ = CryptoProvider::install_default(rustls::crypto::ring::default_provider());
250261
let mut port = 3000;
251262
let listener = loop {
252263
if let Ok(listener) = TcpListener::bind::<SocketAddr>(([127, 0, 0, 1], port).into())
@@ -256,8 +267,10 @@ mod tests {
256267
port += 1;
257268
};
258269
let certificate = rcgen::generate_simple_self_signed(["localhost".to_owned()]).unwrap();
259-
let certificate_der = certificate.serialize_der().unwrap();
260-
let private_key_der = certificate.serialize_private_key_der();
270+
let certificate_der = CertificateDer::from(certificate.serialize_der().unwrap());
271+
let private_key_der =
272+
PrivateKeyDer::from_pem_slice(certificate.serialize_private_key_pem().as_bytes())
273+
.unwrap();
261274
let certificate = reqwest::Certificate::from_der(&certificate_der).unwrap();
262275
let config = ssl_config(vec![certificate_der], private_key_der, trusted_roots).unwrap();
263276
tokio::spawn(

crates/common/axum_tls/src/config.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::ssl_config;
55
use anyhow::anyhow;
66
use anyhow::Context;
77
use camino::Utf8Path;
8+
use rustls::pki_types::CertificateDer;
9+
use rustls::pki_types::PrivateKeyDer;
810
use rustls::RootCertStore;
911
use std::fmt::Debug;
1012
use std::fs::File;
@@ -100,7 +102,7 @@ pub fn load_ssl_config(
100102
}
101103
}
102104

103-
type CertKeyPair = (Vec<Vec<u8>>, Vec<u8>);
105+
type CertKeyPair = (Vec<CertificateDer<'static>>, PrivateKeyDer<'static>);
104106

105107
fn load_certificate_and_key(
106108
cert_path: &OptionalConfig<impl PemReader>,

crates/common/axum_tls/src/error_matching.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ pub fn assert_error_matches(err: reqwest::Error, alert_description: rustls::Aler
1414

1515
pub fn rustls_error_from_reqwest(err: &reqwest::Error) -> Option<&rustls::Error> {
1616
err.source()?
17-
.downcast_ref::<hyper::Error>()?
17+
.downcast_ref::<hyper_util::client::legacy::Error>()?
18+
.source()?
1819
.source()?
1920
.downcast_ref::<std::io::Error>()?
2021
.get_ref()?

crates/common/axum_tls/src/files.rs

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use crate::config::PemReader;
22
use anyhow::anyhow;
33
use anyhow::Context;
44
use camino::Utf8Path;
5-
use rustls::server::AllowAnyAuthenticatedClient;
6-
use rustls::Certificate;
7-
use rustls::PrivateKey;
5+
use rustls::pki_types::CertificateDer;
6+
use rustls::pki_types::PrivateKeyDer;
7+
use rustls::server::WebPkiClientVerifier;
88
use rustls::RootCertStore;
99
use rustls::ServerConfig;
1010
use rustls_pemfile::Item;
1111
use std::fs::File;
1212
use std::io;
13-
use std::sync::Arc;
1413

1514
/// Read a directory into a [RootCertStore]
1615
pub fn read_trust_store(ca_dir: &Utf8Path) -> anyhow::Result<RootCertStore> {
@@ -32,54 +31,47 @@ pub fn read_trust_store(ca_dir: &Utf8Path) -> anyhow::Result<RootCertStore> {
3231
let Ok(mut pem_file) = File::open(&path).map(std::io::BufReader::new) else {
3332
continue;
3433
};
35-
if let Some(value) = rustls_pemfile::certs(&mut pem_file)
36-
.with_context(|| format!("reading {path}"))?
37-
.into_iter()
38-
.next()
39-
{
40-
ders.push(value);
41-
};
34+
35+
ders.extend(rustls_pemfile::certs(&mut pem_file).filter_map(Result::ok));
4236
}
43-
roots.add_parsable_certificates(&ders);
37+
roots.add_parsable_certificates(ders);
4438

4539
Ok(roots)
4640
}
4741

4842
/// Load the SSL configuration for rustls
4943
pub fn ssl_config(
50-
certificate_chain: Vec<Vec<u8>>,
51-
key_der: Vec<u8>,
44+
server_cert_chain: Vec<CertificateDer<'static>>,
45+
server_key: PrivateKeyDer<'static>,
5246
root_certs: Option<RootCertStore>,
5347
) -> anyhow::Result<ServerConfig> {
5448
// Trusted CA for client certificates
55-
let config = ServerConfig::builder().with_safe_defaults();
49+
let config = ServerConfig::builder();
5650

5751
let config = if let Some(root_certs) = root_certs {
58-
config.with_client_cert_verifier(Arc::new(AllowAnyAuthenticatedClient::new(root_certs)))
52+
config.with_client_cert_verifier(WebPkiClientVerifier::builder(root_certs.into()).build()?)
5953
} else {
6054
config.with_no_client_auth()
6155
};
6256

63-
let server_cert = certificate_chain.into_iter().map(Certificate).collect();
64-
let server_key = PrivateKey(key_der);
65-
6657
config
67-
.with_single_cert(server_cert, server_key)
58+
.with_single_cert(server_cert_chain, server_key)
6859
.context("invalid key or certificate")
6960
}
7061

7162
/// Load the server certificate
72-
pub fn load_cert(path: &(impl PemReader + ?Sized)) -> anyhow::Result<Vec<Vec<u8>>> {
63+
pub fn load_cert(path: &(impl PemReader + ?Sized)) -> anyhow::Result<Vec<CertificateDer<'static>>> {
7364
let file = path
7465
.open()
7566
.with_context(|| format!("cannot open certificate file: {path:?}"))?;
7667
let mut reader = std::io::BufReader::new(file);
7768
rustls_pemfile::certs(&mut reader)
69+
.collect::<Result<Vec<_>, _>>()
7870
.with_context(|| format!("parsing PEM-encoded certificate from {path:?}"))
7971
}
8072

8173
/// Load the server private key
82-
pub fn load_pkey(path: &(impl PemReader + ?Sized)) -> anyhow::Result<Vec<u8>> {
74+
pub fn load_pkey(path: &(impl PemReader + ?Sized)) -> anyhow::Result<PrivateKeyDer<'static>> {
8375
let key_file = path
8476
.open()
8577
.with_context(|| format!("cannot open certificate file: {path:?}"))?;
@@ -90,14 +82,16 @@ pub fn load_pkey(path: &(impl PemReader + ?Sized)) -> anyhow::Result<Vec<u8>> {
9082
pub fn pkey_from_pem(
9183
reader: &mut dyn io::BufRead,
9284
filename: &(impl PemReader + ?Sized),
93-
) -> anyhow::Result<Vec<u8>> {
85+
) -> anyhow::Result<PrivateKeyDer<'static>> {
9486
rustls_pemfile::read_one(reader)
9587
.with_context(|| format!("reading PEM-encoded private key from {filename:?}"))?
9688
.ok_or(anyhow!(
9789
"expected private key in {filename:?}, but found no PEM-encoded data"
9890
))
9991
.and_then(|item| match item {
100-
Item::ECKey(key) | Item::PKCS8Key(key) | Item::RSAKey(key) => Ok(key),
92+
Item::Sec1Key(key) => Ok(PrivateKeyDer::Sec1(key)),
93+
Item::Pkcs8Key(key) => Ok(PrivateKeyDer::Pkcs8(key)),
94+
Item::Pkcs1Key(key) => Ok(PrivateKeyDer::Pkcs1(key)),
10195
Item::Crl(_) => Err(anyhow!("expected private key in {filename:?}, found a CRL")),
10296
Item::X509Certificate(_) => Err(anyhow!(
10397
"expected private key in {filename:?}, found an X509 certificate"
@@ -226,60 +220,71 @@ mod tests {
226220
}
227221

228222
mod server_accepts {
223+
use rustls::crypto::CryptoProvider;
224+
229225
use super::*;
230226

227+
fn init_crypto() {
228+
let _ = CryptoProvider::install_default(rustls::crypto::ring::default_provider());
229+
}
230+
231231
#[tokio::test]
232232
async fn alg_ed25519_pkcs8() {
233+
init_crypto();
233234
let key = test_data("ed25519.key");
234235
let cert = test_data("ed25519.crt");
235236

236237
let (config, cert) = config_from_pem(&key, &cert).unwrap();
237238

238-
assert_matches!(parse_key_to_item(&key), Item::PKCS8Key(_));
239+
assert_matches!(parse_key_to_item(&key), Item::Pkcs8Key(_));
239240
assert_server_works_with(config, cert).await;
240241
}
241242

242243
#[tokio::test]
243244
async fn alg_ec() {
245+
init_crypto();
244246
let key = test_data("ec.key");
245247
let cert = test_data("ec.crt");
246248

247249
let (config, cert) = config_from_pem(&key, &cert).unwrap();
248250

249-
assert_matches!(parse_key_to_item(&key), Item::ECKey(_));
251+
assert_matches!(parse_key_to_item(&key), Item::Sec1Key(_));
250252
assert_server_works_with(config, cert).await;
251253
}
252254

253255
#[tokio::test]
254256
async fn alg_ec_pkcs8() {
257+
init_crypto();
255258
let key = test_data("ec.pkcs8.key");
256259
let cert = test_data("ec.crt");
257260

258261
let (config, cert) = config_from_pem(&key, &cert).unwrap();
259262

260-
assert_matches!(parse_key_to_item(&key), Item::PKCS8Key(_));
263+
assert_matches!(parse_key_to_item(&key), Item::Pkcs8Key(_));
261264
assert_server_works_with(config, cert).await;
262265
}
263266

264267
#[tokio::test]
265268
async fn alg_rsa_pkcs8() {
269+
init_crypto();
266270
let key = test_data("rsa.pkcs8.key");
267271
let cert = test_data("rsa.crt");
268272

269273
let (config, cert) = config_from_pem(&key, &cert).unwrap();
270274

271-
assert_matches!(parse_key_to_item(&key), Item::PKCS8Key(_));
275+
assert_matches!(parse_key_to_item(&key), Item::Pkcs8Key(_));
272276
assert_server_works_with(config, cert).await;
273277
}
274278

275279
#[tokio::test]
276280
async fn alg_rsa_pkcs1() {
281+
init_crypto();
277282
let key = test_data("rsa.pkcs1.key");
278283
let cert = test_data("rsa.crt");
279284

280285
let (config, cert) = config_from_pem(&key, &cert).unwrap();
281286

282-
assert_matches!(parse_key_to_item(&key), Item::RSAKey(_));
287+
assert_matches!(parse_key_to_item(&key), Item::Pkcs1Key(_));
283288
assert_server_works_with(config, cert).await;
284289
}
285290

@@ -300,18 +305,20 @@ mod tests {
300305
key: &str,
301306
cert: &str,
302307
) -> anyhow::Result<(ServerConfig, reqwest::tls::Certificate)> {
303-
let chain = rustls_pemfile::certs(&mut Cursor::new(cert)).context("reading certs")?;
308+
let chain = rustls_pemfile::certs(&mut Cursor::new(cert))
309+
.collect::<Result<Vec<_>, _>>()
310+
.context("reading certs")?;
304311
let key_der = parse_key_to_der(key)?;
305312
let cert = reqwest::tls::Certificate::from_der(
306-
chain.first().expect("chain should contain certificate"),
313+
&*chain.first().expect("chain should contain certificate"),
307314
)
308315
.context("converting certificate to reqwest::tls::Certificate")?;
309316
let config = ssl_config(chain, key_der, None)?;
310317

311318
Ok((config, cert))
312319
}
313320

314-
fn parse_key_to_der(pem: &str) -> anyhow::Result<Vec<u8>> {
321+
fn parse_key_to_der(pem: &str) -> anyhow::Result<PrivateKeyDer<'static>> {
315322
pkey_from_pem(
316323
&mut Cursor::new(pem),
317324
Utf8Path::new("just-in-memory-not-a-file.pem"),

crates/common/certificate/src/cloud_root_certificate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ pub fn read_trust_store(ca_dir_or_file: &Utf8Path) -> anyhow::Result<Vec<Certifi
8282
};
8383

8484
let ders = rustls_pemfile::certs(&mut pem_file)
85-
.with_context(|| format!("reading {path}"))?
86-
.into_iter()
87-
.map(|der| Certificate::from_der(&der).unwrap());
85+
.map(|res| Ok(Certificate::from_der(&res?)?))
86+
.collect::<anyhow::Result<Vec<_>>>()
87+
.with_context(|| format!("reading {path}"))?;
8888
certs.extend(ders)
8989
}
9090

0 commit comments

Comments
 (0)