Skip to content

Commit e285b2a

Browse files
committed
feat: make iroh-relay server work without default crypto provider
1 parent f829593 commit e285b2a

7 files changed

Lines changed: 36 additions & 27 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ unexpected_cfgs = { level = "warn", check-cfg = ["cfg(iroh_docsrs)", "cfg(iroh_l
4040

4141
[workspace.lints.clippy]
4242
unused-async = "warn"
43+
44+
[patch.crates-io]
45+
tokio-rustls-acme = { git = "https://github.com/n0-computer/tokio-rustls-acme", branch = "Frando/crypto-provider"}

iroh-relay/src/main.rs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use iroh_relay::{
1818
DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT, DEFAULT_METRICS_PORT, DEFAULT_RELAY_QUIC_PORT,
1919
},
2020
server::{self as relay, ClientRateLimit, QuicConfig},
21+
tls::CaRootsConfig,
2122
};
2223
use n0_error::{Result, StdResultExt, bail_any};
2324
use n0_future::FutureExt;
@@ -496,16 +497,6 @@ async fn main() -> Result<()> {
496497
.with(EnvFilter::from_default_env())
497498
.init();
498499

499-
// Install `ring` as default crypto provider for rustls.
500-
// This helps when both the tls-ring and tls-aws-lc-rs features are enabled,
501-
// otherwise some crypto operations would panic because rustls can't determine
502-
// a default provider.
503-
// `ring` is enabled by the `tls-ring` feature, which is included in the `server` feature,
504-
// which is required for the main.rs binary. Therefore, this does not need any feature flags.
505-
rustls::crypto::ring::default_provider()
506-
.install_default()
507-
.expect("failed to set default crypto provider");
508-
509500
let cli = Cli::parse();
510501
let mut cfg = Config::load(&cli).await?;
511502
if cfg.enable_quic_addr_discovery && cfg.tls.is_none() {
@@ -544,12 +535,11 @@ async fn maybe_load_tls(
544535
let Some(ref tls) = cfg.tls else {
545536
return Ok(None);
546537
};
547-
let server_config = rustls::ServerConfig::builder_with_provider(std::sync::Arc::new(
548-
rustls::crypto::ring::default_provider(),
549-
))
550-
.with_safe_default_protocol_versions()
551-
.expect("protocols supported by ring")
552-
.with_no_client_auth();
538+
let crypto_provider = Arc::new(rustls::crypto::ring::default_provider());
539+
let server_config = rustls::ServerConfig::builder_with_provider(crypto_provider.clone())
540+
.with_safe_default_protocol_versions()
541+
.expect("protocols supported by ring")
542+
.with_no_client_auth();
553543
let (cert_config, server_config) = match tls.cert_mode {
554544
CertMode::Manual => {
555545
let cert_path = tls.cert_path();
@@ -576,10 +566,14 @@ async fn maybe_load_tls(
576566
.contact
577567
.clone()
578568
.std_context("LetsEncrypt needs a contact email")?;
579-
let config = AcmeConfig::new(vec![hostname.clone()])
580-
.contact([format!("mailto:{contact}")])
581-
.cache_option(Some(DirCache::new(tls.cert_dir())))
582-
.directory_lets_encrypt(tls.prod_tls);
569+
let client_config = CaRootsConfig::default().client_config(crypto_provider.clone())?;
570+
let config = AcmeConfig::new_with_client_tls_config(
571+
vec![hostname.clone()],
572+
Arc::new(client_config),
573+
)
574+
.contact([format!("mailto:{contact}")])
575+
.cache_option(Some(DirCache::new(tls.cert_dir())))
576+
.directory_lets_encrypt(tls.prod_tls);
583577
let state = config.state();
584578
let resolver = state.resolver().clone();
585579
let server_config = server_config.with_cert_resolver(resolver);
@@ -628,6 +622,7 @@ async fn maybe_load_tls(
628622
cert: cert_config,
629623
server_config,
630624
quic_bind_addr: tls.quic_bind_addr(cfg),
625+
crypto_provider,
631626
}))
632627
}
633628

iroh-relay/src/server.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use iroh_base::EndpointId;
2828
use iroh_base::RelayUrl;
2929
use n0_error::{e, stack_error};
3030
use n0_future::{StreamExt, future::Boxed};
31+
use rustls::crypto::CryptoProvider;
3132
use serde::Serialize;
3233
use tokio::{
3334
net::TcpListener,
@@ -194,6 +195,8 @@ pub struct TlsConfig<EC: fmt::Debug, EA: fmt::Debug = EC> {
194195
pub cert: CertConfig<EC, EA>,
195196
/// The server configuration.
196197
pub server_config: rustls::ServerConfig,
198+
/// The rustls crypto provider to use for all crypto.
199+
pub crypto_provider: Arc<CryptoProvider>,
197200
}
198201

199202
/// Rate limits.
@@ -394,8 +397,11 @@ impl Server {
394397
Some(tls_config) => {
395398
let server_tls_config = match tls_config.cert {
396399
CertConfig::LetsEncrypt { mut state } => {
397-
let acceptor =
398-
http_server::TlsAcceptor::LetsEncrypt(state.acceptor());
400+
let acceptor = http_server::TlsAcceptor::LetsEncrypt(
401+
state.acceptor_with_crypto_provider(
402+
tls_config.crypto_provider.clone(),
403+
),
404+
);
399405
tasks.spawn(
400406
async move {
401407
while let Some(event) = state.next().await {

iroh-relay/src/server/testing.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Exposes functions to quickly configure a server suitable for testing.
2-
use std::net::Ipv4Addr;
2+
use std::{net::Ipv4Addr, sync::Arc};
33

44
use super::{AccessConfig, CertConfig, QuicConfig, RelayConfig, ServerConfig, TlsConfig};
55

@@ -44,6 +44,7 @@ pub fn tls_config() -> TlsConfig<()> {
4444
cert: CertConfig::<(), ()>::Manual { certs },
4545
https_bind_addr: (Ipv4Addr::LOCALHOST, 0).into(),
4646
quic_bind_addr: (Ipv4Addr::UNSPECIFIED, 0).into(),
47+
crypto_provider: Arc::new(rustls::crypto::ring::default_provider()),
4748
}
4849
}
4950

iroh/src/test_utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Internal utilities to support testing.
2-
use std::net::Ipv4Addr;
2+
use std::{net::Ipv4Addr, sync::Arc};
33

44
use iroh_base::RelayUrl;
55
use iroh_relay::{
@@ -49,6 +49,7 @@ pub async fn run_relay_server_with(quic: bool) -> Result<(RelayMap, RelayUrl, Se
4949
https_bind_addr: (Ipv4Addr::LOCALHOST, 0).into(),
5050
quic_bind_addr: (Ipv4Addr::LOCALHOST, 0).into(),
5151
server_config,
52+
crypto_provider: Arc::new(rustls::crypto::ring::default_provider()),
5253
};
5354
let quic = if quic {
5455
Some(QuicConfig {

iroh/tests/patchbay/util.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,10 @@ fn addr_relay_only(addr: EndpointAddr) -> EndpointAddr {
493493
}
494494

495495
mod relay {
496-
use std::net::{IpAddr, Ipv6Addr};
496+
use std::{
497+
net::{IpAddr, Ipv6Addr},
498+
sync::Arc,
499+
};
497500

498501
use iroh_base::RelayUrl;
499502
use iroh_relay::{
@@ -520,6 +523,7 @@ mod relay {
520523
https_bind_addr: (bind_ip, 443).into(),
521524
quic_bind_addr: (bind_ip, 7842).into(),
522525
server_config,
526+
crypto_provider: Arc::new(rustls::crypto::ring::default_provider()),
523527
};
524528
let quic = Some(QuicConfig {
525529
server_config: tls.server_config.clone(),

0 commit comments

Comments
 (0)