Skip to content

Commit 23eb3a2

Browse files
committed
fix: Replace rustls-pemfile with rustls-pki-types
Summary: rustls-pemfile is now unmaintained and the recommendation is to migrate to rustls-pki-types. RUSTSEC advisory https://rustsec.org/advisories/RUSTSEC-2025-0134 Test Plan: ``` cargo test --features tls-rustls-no-provider ``` and ``` cargo test --features tls-rustls ``` Fixes #177
1 parent 272dff9 commit 23eb3a2

File tree

2 files changed

+45
-44
lines changed

2 files changed

+45
-44
lines changed

Cargo.toml

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
[package]
2-
authors = ["Programatik <[email protected]>", "Adi Salimgereev <[email protected]>"]
2+
authors = [
3+
"Programatik <[email protected]>",
4+
"Adi Salimgereev <[email protected]>",
5+
]
36
categories = ["asynchronous", "network-programming", "web-programming"]
47
description = "High level server designed to be used with axum framework."
58
edition = "2021"
@@ -15,8 +18,22 @@ rust-version = "1.82"
1518
[features]
1619
default = []
1720
tls-rustls = ["tls-rustls-no-provider", "rustls/aws-lc-rs"]
18-
tls-rustls-no-provider = ["arc-swap", "rustls", "rustls-pemfile", "tokio/fs", "tokio/time", "tokio-rustls", "rustls-pki-types", "dep:pin-project-lite"]
19-
tls-openssl = ["arc-swap", "openssl", "openssl-sys", "tokio-openssl", "dep:pin-project-lite"]
21+
tls-rustls-no-provider = [
22+
"arc-swap",
23+
"rustls",
24+
"tokio/fs",
25+
"tokio/time",
26+
"tokio-rustls",
27+
"rustls-pki-types",
28+
"dep:pin-project-lite",
29+
]
30+
tls-openssl = [
31+
"arc-swap",
32+
"openssl",
33+
"openssl-sys",
34+
"tokio-openssl",
35+
"dep:pin-project-lite",
36+
]
2037

2138
[dependencies]
2239
bytes = "1"
@@ -27,14 +44,17 @@ http-body = "1.0"
2744
hyper = { version = "1.4", features = ["http1", "http2", "server"] }
2845
tokio = { version = "1", features = ["macros", "net", "sync"] }
2946
tower-service = "0.3"
30-
hyper-util = { version = "0.1.18", features = ["server-auto", "service", "tokio"] }
47+
hyper-util = { version = "0.1.18", features = [
48+
"server-auto",
49+
"service",
50+
"tokio",
51+
] }
3152

3253
# optional dependencies
3354
## rustls
3455
arc-swap = { version = "1", optional = true }
3556
rustls = { version = "0.23", default-features = false, optional = true }
36-
rustls-pki-types = { version = "1.7", optional = true }
37-
rustls-pemfile = { version = "2.2", optional = true }
57+
rustls-pki-types = { version = "1.9", features = ["std"], optional = true }
3858
tokio-rustls = { version = "0.26", default-features = false, optional = true }
3959

4060
## openssl

src/tls_rustls/mod.rs

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use crate::{
3434
};
3535
use arc_swap::ArcSwap;
3636
use rustls::ServerConfig;
37-
use rustls_pemfile::Item;
37+
use rustls_pki_types::pem::PemObject;
3838
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
3939
use std::time::Duration;
4040
use std::{fmt, io, net::SocketAddr, path::Path, sync::Arc};
@@ -295,32 +295,17 @@ fn config_from_der(cert: Vec<Vec<u8>>, key: Vec<u8>) -> io::Result<ServerConfig>
295295
}
296296

297297
fn config_from_pem(cert: Vec<u8>, key: Vec<u8>) -> io::Result<ServerConfig> {
298-
let cert = rustls_pemfile::certs(&mut cert.as_ref())
299-
.map(|it| it.map(|it| it.to_vec()))
300-
.collect::<Result<Vec<_>, _>>()?;
298+
let cert: Vec<CertificateDer> = CertificateDer::pem_slice_iter(&cert)
299+
.collect::<Result<Vec<_>, _>>()
300+
.map_err(|_| io_other("failed to parse certificate"))?;
301301

302-
let mut key_result = Err(io_other("The private key file contained no keys"));
302+
let mut key_result: Result<PrivateKeyDer, io::Error> =
303+
Err(io_other("The private key file contained no keys"));
303304

304305
// Check the entire PEM file for the key in case it is not first section
305-
for item in rustls_pemfile::read_all(&mut key.as_ref()) {
306-
let key = item.and_then(|i| match i {
307-
Item::Sec1Key(key) => Ok(key.secret_sec1_der().to_vec()),
308-
Item::Pkcs1Key(key) => Ok(key.secret_pkcs1_der().to_vec()),
309-
Item::Pkcs8Key(key) => Ok(key.secret_pkcs8_der().to_vec()),
310-
Item::X509Certificate(_) => {
311-
Err(io_other("Unsupported private key format 'X509Certificate'"))
312-
}
313-
Item::Crl(_) => Err(io_other(
314-
"Unsupported private key format 'CertificateRevocationList'",
315-
)),
316-
Item::Csr(_) => Err(io_other(
317-
"Unsupported private key format 'CertificateSigningRequest'",
318-
)),
319-
Item::SubjectPublicKeyInfo(_) => Err(io_other(
320-
"Unsupported private key format 'SubjectPublicKeyInfo'",
321-
)),
322-
_ => Err(io_other("Unrecognized private key format")),
323-
});
306+
for item in rustls_pki_types::pem::PemObject::pem_slice_iter(&key) {
307+
let key: Result<PrivateKeyDer, io::Error> =
308+
item.map_err(|_| io_other("failed to parse PEM"));
324309

325310
match key_result {
326311
// if we already got a key, then...
@@ -339,7 +324,11 @@ fn config_from_pem(cert: Vec<u8>, key: Vec<u8>) -> io::Result<ServerConfig> {
339324
}
340325
}
341326

342-
config_from_der(cert, key_result?)
327+
let key = key_result?;
328+
let cert_der: Vec<Vec<u8>> = cert.into_iter().map(|c| c.to_vec()).collect();
329+
let key_der = key.secret_der().to_vec();
330+
331+
config_from_der(cert_der, key_der)
343332
}
344333

345334
async fn config_from_pem_file(
@@ -357,20 +346,12 @@ async fn config_from_pem_chain_file(
357346
chain: impl AsRef<Path>,
358347
) -> io::Result<ServerConfig> {
359348
let cert = fs_err::tokio::read(cert.as_ref()).await?;
360-
let cert = rustls_pemfile::certs(&mut cert.as_ref())
361-
.map(|it| it.map(|it| CertificateDer::from(it.to_vec())))
362-
.collect::<Result<Vec<_>, _>>()?;
349+
let cert = CertificateDer::pem_slice_iter(&cert)
350+
.collect::<Result<Vec<_>, _>>()
351+
.map_err(|_| io_other("failed to parse certificate"))?;
363352
let key = fs_err::tokio::read(chain.as_ref()).await?;
364-
let key_cert: PrivateKeyDer = match rustls_pemfile::read_one(&mut key.as_ref())?
365-
.ok_or_else(|| io_other("could not parse pem file"))?
366-
{
367-
Item::Pkcs8Key(key) => Ok(key.into()),
368-
Item::Sec1Key(key) => Ok(key.into()),
369-
Item::Pkcs1Key(key) => Ok(key.into()),
370-
x => Err(io_other(format!(
371-
"invalid certificate format, received: {x:?}"
372-
))),
373-
}?;
353+
let key_cert: PrivateKeyDer =
354+
PrivateKeyDer::from_pem_slice(&key).map_err(|_| io_other("could not parse pem file"))?;
374355

375356
ServerConfig::builder()
376357
.with_no_client_auth()

0 commit comments

Comments
 (0)