How to Use Custom Crypto Providers in iroh: A Complete Guide
You can inject any rustls-compatible CryptoProvider into iroh by calling the crypto_provider() method on the endpoint Builder, passing an Arc-wrapped provider that implements the rustls trait.
iroh's TLS layer is built on rustls, which abstracts cryptographic implementations behind the CryptoProvider trait. By default, the library ships with preset providers (ring and aws‑lc‑rs) that are selected automatically when Cargo features tls‑ring or tls‑aws‑lc‑rs are enabled. When you need a different provider—whether a custom-built implementation or a third-party crate—you can inject it directly into the endpoint builder to control the cryptographic primitives used for all TLS and QUIC communication.
Understanding iroh's Crypto Provider Architecture
iroh delegates all cryptographic operations to rustls, which defines the CryptoProvider trait as the interface for cipher suites, signature schemes, and key‑exchange algorithms. The library selects a default provider based on feature flags:
tls‑ring: Enables theringcrate providertls‑aws‑lc‑rs: Enables the AWS Libcrypto provider
These presets are wired into the build configuration, but the Builder API allows you to override this selection at runtime with any compatible implementation.
Setting a Custom Crypto Provider on the Endpoint Builder
The Builder::crypto_provider method in iroh/src/endpoint.rs (lines 47‑64) accepts an Arc<CryptoProvider> and stores it for all subsequent TLS operations, including QUIC connections, HTTPS calls to relays, and PKARR publishing.
Using a Built‑in Provider Explicitly
To use one of the built‑in rustls providers directly, obtain it via default_provider() and wrap it in Arc:
use std::sync::Arc;
use rustls::crypto::{CryptoProvider, ring};
use iroh::endpoint::Builder;
// Obtain the ring provider
let provider = Arc::new(ring::default_provider());
// Inject into the builder
let endpoint = Builder::empty()
.crypto_provider(provider) // ← custom crypto provider injection
.bind()
.await?;
Overriding Preset Configurations
Presets like Minimal or N0 configure default providers based on feature flags, but you can override them after instantiation. The preset logic resides in iroh/src/endpoint/presets.rs (lines 58‑78):
use iroh::endpoint::{Builder, presets};
use rustls::crypto::aws_lc_rs;
// Start with a preset that includes relay and address lookup
let endpoint = Builder::new(presets::N0)
.crypto_provider(Arc::new(aws_lc_rs::default_provider())) // override provider
.bind()
.await?;
Implementing a Fully Custom Crypto Provider
For custom implementations—whether your own code or third‑party crates—you must implement the full rustls::crypto::CryptoProvider trait. The provider must support the cipher suites required by QUIC, specifically TLS 1.3 AES 128‑GCM‑SHA256.
iroh validates this requirement at runtime. If your provider lacks the necessary cipher suite, the library emits an error from iroh/src/tls.rs:
The configured crypto provider is missing support for TLS13_AES_128_GCM_SHA256
Ensure your implementation includes:
- TLS 1.3 cipher suites (mandatory: AES 128‑GCM‑SHA256)
- Supported signature schemes
- Key‑exchange algorithms compatible with QUIC
Summary
- iroh uses rustls's
CryptoProvidertrait to abstract cryptographic implementations, with default providers selected viatls‑ringortls‑aws‑lc‑rsfeatures. - Call
Builder::crypto_provider()with anArc-wrapped provider to inject custom crypto providers in iroh, overriding any preset defaults. - The method is implemented in
iroh/src/endpoint.rs(lines 47‑64) and affects all TLS operations including QUIC and HTTPS. - Presets can be customized by chaining
crypto_provider()after instantiating the preset, as shown iniroh/src/endpoint/presets.rs(lines 58‑78). - Custom providers must implement the full rustls trait and support TLS 1.3 AES 128‑GCM‑SHA256; missing support triggers an error from
iroh/src/tls.rs.
Frequently Asked Questions
What is a CryptoProvider in iroh?
A CryptoProvider is a rustls trait implementation that supplies cryptographic primitives—including cipher suites, signature schemes, and key‑exchange algorithms—to iroh's TLS and QUIC stack. iroh uses this abstraction to allow swapping between different cryptographic libraries (like ring or aws‑lc‑rs) or custom implementations without changing the application code.
Can I use a custom crypto provider with iroh's built‑in presets?
Yes. Presets like N0 or Minimal configure default providers based on Cargo features, but you can override them by calling crypto_provider() on the builder after instantiating the preset. This allows you to keep the preset's relay and discovery configuration while substituting your own cryptographic implementation.
What happens if my custom provider doesn't support the required cipher suites?
iroh validates that the provided CryptoProvider supports TLS 1.3 AES 128‑GCM‑SHA256, which is required for QUIC. If your provider lacks this support, the library will return an error stating "The configured crypto provider is missing support for TLS13_AES_128_GCM_SHA256" from the validation logic in iroh/src/tls.rs.
Do I need to enable a Cargo feature to use custom crypto providers?
No. The tls‑ring and tls‑aws‑lc‑rs features only control the default providers included in the build. To use a custom crypto provider, you simply pass it to Builder::crypto_provider() at runtime, regardless of which default features are enabled. However, you must ensure your custom provider is compatible with the rustls version used by iroh.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →