diff --git a/Cargo.lock b/Cargo.lock index 57fab39d6dd..65ba8751de3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2247,7 +2247,6 @@ dependencies = [ "redb", "regex", "rustls", - "rustls-pemfile", "serde", "struct_iterable", "strum", @@ -2393,7 +2392,6 @@ dependencies = [ "rustls", "rustls-cert-file-reader", "rustls-cert-reloadable-resolver", - "rustls-pemfile", "rustls-pki-types", "serde", "serde_bytes", diff --git a/deny.toml b/deny.toml index ad5f7f66406..cc23a1d1440 100644 --- a/deny.toml +++ b/deny.toml @@ -24,7 +24,6 @@ ignore = [ "RUSTSEC-2024-0384", # unmaintained, no upgrade available "RUSTSEC-2024-0436", # paste "RUSTSEC-2023-0089", # unmainatined: postcard -> heapless -> atomic-polyfill - "RUSTSEC-2025-0134", # rustls-pemfile is unmaintained, but we need some time to update deps ] [sources] diff --git a/iroh-dns-server/Cargo.toml b/iroh-dns-server/Cargo.toml index 951382138b2..c21125c6c1d 100644 --- a/iroh-dns-server/Cargo.toml +++ b/iroh-dns-server/Cargo.toml @@ -36,7 +36,6 @@ rcgen = "0.14" redb = "3.1.0" regex = "1.10.3" rustls = { version = "0.23.33", default-features = false, features = ["ring"] } -rustls-pemfile = { version = "2.1" } serde = { version = "1", features = ["derive"] } struct_iterable = "0.1.1" n0-error = "0.1.0" diff --git a/iroh-dns-server/src/http/tls.rs b/iroh-dns-server/src/http/tls.rs index 624bf0e44e1..d93ad3fa3d1 100644 --- a/iroh-dns-server/src/http/tls.rs +++ b/iroh-dns-server/src/http/tls.rs @@ -11,6 +11,7 @@ use axum_server::{ }; use n0_error::{Result, StackResultExt, StdResultExt, bail_any}; use n0_future::{FutureExt, future::Boxed as BoxFuture}; +use rustls::pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}; use serde::{Deserialize, Serialize}; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls_acme::{AcmeConfig, axum::AxumAcceptor, caches::DirCache}; @@ -135,49 +136,23 @@ impl TlsAcceptor { } } -async fn load_certs( - filename: impl AsRef, -) -> Result>> { +async fn load_certs(filename: impl AsRef) -> Result>> { + let filename = filename.as_ref(); let certfile = tokio::fs::read(filename) .await - .std_context("cannot open certificate file")?; - let mut reader = std::io::Cursor::new(certfile); - let certs: Result, std::io::Error> = rustls_pemfile::certs(&mut reader).collect(); - let certs = certs.anyerr()?; - - Ok(certs) + .with_std_context(|_| format!("cannot open certificate file at {}", filename.display()))?; + CertificateDer::pem_slice_iter(&certfile) + .collect::, _>>() + .with_std_context(|_| format!("cannot parse certificates from {}", filename.display())) } -async fn load_secret_key( - filename: impl AsRef, -) -> Result> { - let keyfile = tokio::fs::read(filename.as_ref()) +async fn load_secret_key(filename: impl AsRef) -> Result> { + let filename = filename.as_ref(); + let keyfile = tokio::fs::read(filename) .await - .std_context("cannot open secret key file")?; - let mut reader = std::io::Cursor::new(keyfile); - - loop { - match rustls_pemfile::read_one(&mut reader) - .std_context("cannot parse secret key .pem file")? - { - Some(rustls_pemfile::Item::Pkcs1Key(key)) => { - return Ok(rustls::pki_types::PrivateKeyDer::Pkcs1(key)); - } - Some(rustls_pemfile::Item::Pkcs8Key(key)) => { - return Ok(rustls::pki_types::PrivateKeyDer::Pkcs8(key)); - } - Some(rustls_pemfile::Item::Sec1Key(key)) => { - return Ok(rustls::pki_types::PrivateKeyDer::Sec1(key)); - } - None => break, - _ => {} - } - } - - bail_any!( - "no keys found in {} (encrypted keys not supported)", - filename.as_ref().display() - ); + .with_std_context(|_| format!("cannot open secret key file at {}", filename.display()))?; + PrivateKeyDer::from_pem_slice(&keyfile) + .with_std_context(|_| format!("cannot parse secret key from {}", filename.display())) } static UNSAFE_HOSTNAME_CHARACTERS: OnceLock = OnceLock::new(); diff --git a/iroh-relay/Cargo.toml b/iroh-relay/Cargo.toml index 17428cbffbf..cb30dd82eba 100644 --- a/iroh-relay/Cargo.toml +++ b/iroh-relay/Cargo.toml @@ -80,7 +80,6 @@ rcgen = { version = "0.14", optional = true } reloadable-state = { version = "0.1", optional = true } rustls-cert-reloadable-resolver = { version = "0.7.1", optional = true } rustls-cert-file-reader = { version = "0.4.1", optional = true } -rustls-pemfile = { version = "2.1", optional = true } time = { version = "0.3.37", optional = true } tokio-rustls-acme = { version = "0.8", optional = true } tokio-websockets = { version = "0.12", features = ["rustls-bring-your-own-connector", "ring", "getrandom", "rand", "server"], optional = true } # server-side websocket implementation @@ -146,7 +145,6 @@ server = [ "dep:reloadable-state", "dep:rustls-cert-file-reader", "dep:rustls-cert-reloadable-resolver", - "dep:rustls-pemfile", "dep:time", "dep:tokio-rustls-acme", "dep:tokio-websockets", diff --git a/iroh-relay/src/main.rs b/iroh-relay/src/main.rs index 5f558dbaa15..da8d6caad07 100644 --- a/iroh-relay/src/main.rs +++ b/iroh-relay/src/main.rs @@ -19,13 +19,14 @@ use iroh_relay::{ }, server::{self as relay, ClientRateLimit, QuicConfig}, }; -use n0_error::{AnyError as Error, Result, StdResultExt, bail_any}; +use n0_error::{Result, StdResultExt, bail_any}; use n0_future::FutureExt; use serde::{Deserialize, Serialize}; use tokio_rustls_acme::{AcmeConfig, caches::DirCache}; use tracing::{debug, warn}; use tracing_subscriber::{EnvFilter, prelude::*}; use url::Url; +use webpki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}; /// The default `http_bind_port` when using `--dev`. const DEV_MODE_HTTP_PORT: u16 = 3340; @@ -61,45 +62,19 @@ enum CertMode { fn load_certs( filename: impl AsRef, ) -> Result>> { - let certfile = std::fs::File::open(filename).std_context("cannot open certificate file")?; - let mut reader = std::io::BufReader::new(certfile); - - let certs: Result, std::io::Error> = rustls_pemfile::certs(&mut reader).collect(); - let certs = certs.std_context("reading cert")?; - - Ok(certs) + let filename = filename.as_ref(); + CertificateDer::pem_file_iter(filename) + .with_std_context(|_| format!("failed to open certificate file at {}", filename.display()))? + .collect::, _>>() + .with_std_context(|_| format!("failed to read certificates from {}", filename.display())) } fn load_secret_key( filename: impl AsRef, ) -> Result> { let filename = filename.as_ref(); - let keyfile = std::fs::File::open(filename) - .with_std_context(|_| format!("cannot open secret key file {}", filename.display()))?; - let mut reader = std::io::BufReader::new(keyfile); - - loop { - match rustls_pemfile::read_one(&mut reader) - .std_context("cannot parse secret key .pem file")? - { - Some(rustls_pemfile::Item::Pkcs1Key(key)) => { - return Ok(rustls::pki_types::PrivateKeyDer::Pkcs1(key)); - } - Some(rustls_pemfile::Item::Pkcs8Key(key)) => { - return Ok(rustls::pki_types::PrivateKeyDer::Pkcs8(key)); - } - Some(rustls_pemfile::Item::Sec1Key(key)) => { - return Ok(rustls::pki_types::PrivateKeyDer::Sec1(key)); - } - None => break, - _ => {} - } - } - - bail_any!( - "no keys found in {} (encrypted keys not supported)", - filename.display() - ); + PrivateKeyDer::from_pem_file(filename) + .with_std_context(|_| format!("failed to read secret key from {}", filename.display())) } /// Configuration for the relay-server. @@ -573,7 +548,7 @@ async fn maybe_load_tls( let (private_key, certs) = tokio::task::spawn_blocking(move || { let key = load_secret_key(key_path)?; let certs = load_certs(cert_path)?; - Ok::<_, Error>((key, certs)) + n0_error::Ok((key, certs)) }) .await .std_context("join")??;