Skip to content

Commit

Permalink
build(gateway,http,lavalink): Update to rustls 0.23
Browse files Browse the repository at this point in the history
This also adds support for rustls-platform-verifier and makes it the
default. Further, support for aws-lc-rs is added, but not enabled by
default.

Users disabling default features will have to manually enable a crypto
backend for rustls now or install a global default using the rustls'
CrytoProvider::install_default method [1].

[1]: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html#method.install_default

Signed-off-by: Jens Reidel <[email protected]>
  • Loading branch information
Gelbpunkt committed Sep 4, 2024
1 parent 5a9da42 commit f71e6e4
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 37 deletions.
12 changes: 8 additions & 4 deletions twilight-gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ futures-sink = { default-features = false, features = ["std"], version = "0.3" }
serde = { default-features = false, features = ["derive"], version = "1" }
serde_json = { default-features = false, features = ["std"], version = "1" }
tokio = { default-features = false, features = ["net", "rt", "sync", "time"], version = "1.19" }
tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.7" }
tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.10" }
tracing = { default-features = false, features = ["std", "attributes"], version = "0.1" }
twilight-gateway-queue = { default-features = false, path = "../twilight-gateway-queue", version = "0.16.0-rc.1" }
twilight-model = { default-features = false, path = "../twilight-model", version = "0.16.0-rc.1" }
Expand All @@ -44,10 +44,14 @@ tokio-stream = { default-features = false, version = "0.1" }
tracing-subscriber = { default-features = false, features = ["fmt", "tracing-log"], version = "0.3" }

[features]
default = ["rustls-native-roots", "twilight-http", "zlib-stock"]
default = ["rustls-platform-verifier", "rustls-ring", "twilight-http", "zlib-stock"]
native-tls = ["tokio-websockets/native-tls", "tokio-websockets/openssl"]
rustls-native-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-native-roots"]
rustls-webpki-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-webpki-roots"]
rustls-platform-verifier = ["tokio-websockets/rustls-platform-verifier"]
rustls-native-roots = ["tokio-websockets/rustls-native-roots"]
rustls-webpki-roots = ["tokio-websockets/rustls-webpki-roots"]
rustls-ring = ["tokio-websockets/ring"]
rustls-aws_lc_rs = ["tokio-websockets/aws_lc_rs"]
rustls-aws-lc-rs = ["rustls-aws_lc_rs"] # Alias for convenience, underscores are preferred in the rustls stack
zlib-simd = ["dep:flate2", "flate2?/zlib-ng"]
zlib-stock = ["dep:flate2", "flate2?/zlib"]

Expand Down
14 changes: 13 additions & 1 deletion twilight-gateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@ from a `Fn(ShardId, ConfigBuilder) -> Config` closure, with the help of the
events
* TLS (mutually exclusive)
* `native-tls`: platform's native TLS implementation via [`native-tls`]
* `rustls-native-roots` (*default*): [`rustls`] using native root certificates
* `rustls-native-roots`: [`rustls`] using native root certificates
* `rustls-platform-verifier` (*default*): [`rustls`] using operating system's
certificate facilities via [`rustls-platform-verifier`]
* `rustls-webpki-roots`: [`rustls`] using [`webpki-roots`] for root
certificates, useful for `scratch` containers
* Crypto providers (required with [`rustls`])
* `rustls-ring` (*default*): [`ring`] as the cryto provider, recommended for

Check failure on line 32 in twilight-gateway/README.md

View workflow job for this annotation

GitHub Actions / Spelling

cryto ==> crypto
compatibility
* `rustls-aws_lc_rs`: [`aws-lc-rs`] as the crypto provider, recommended for
performance and widely used platforms
* none of the above: install your own via [`CryptoProvider::install_default`]
* `twilight-http` (*default*): enable the `stream::create_recommended` function
* Zlib (mutually exclusive)
* `zlib-stock` (*default*): [`flate2`]'s stock zlib implementation
Expand Down Expand Up @@ -104,9 +112,13 @@ async fn runner(mut shard: Shard) {
There are a few additional examples located in the
[repository][github examples link].

[`CryptoProvider::install_default`]: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html#method.install_default
[`aws-lc-rs`]: https://crates.io/crates/aws-lc-rs
[`flate2`]: https://crates.io/crates/flate2
[`native-tls`]: https://crates.io/crates/native-tls
[`ring`]: https://crates.io/crates/ring
[`rustls`]: https://crates.io/crates/rustls
[`rustls-platform-verifier`]: https://crates.io/crates/rustls-platform-verifier
[`serde_json`]: https://crates.io/crates/serde_json
[`simd-json`]: https://crates.io/crates/simd-json
[`webpki-roots`]: https://crates.io/crates/webpki-roots
Expand Down
2 changes: 2 additions & 0 deletions twilight-gateway/src/shard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use serde::{de::DeserializeOwned, Deserialize};
#[cfg(any(
feature = "native-tls",
feature = "rustls-native-roots",
feature = "rustls-platform-verifier",
feature = "rustls-webpki-roots"
))]
use std::io::ErrorKind as IoErrorKind;
Expand Down Expand Up @@ -916,6 +917,7 @@ impl<Q: Queue + Unpin> Stream for Shard<Q> {
#[cfg(any(
feature = "native-tls",
feature = "rustls-native-roots",
feature = "rustls-platform-verifier",
feature = "rustls-webpki-roots"
))]
Some(Err(WebsocketError::Io(e)))
Expand Down
15 changes: 10 additions & 5 deletions twilight-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ http = { default-features = false, version = "1" }
http-body-util = { default-features = false, version = "0.1" }
hyper = { default-features = false, version = "1" }
hyper-util = { default-features = false, features = ["client-legacy", "http1", "http2", "tokio"], version = "0.1.2" }
hyper-rustls = { default-features = false, optional = true, features = ["http1", "http2", "ring"], version = "0.26" }
hyper-rustls = { default-features = false, optional = true, features = ["http1", "http2"], version = "0.27.3" }
hyper-tls = { default-features = false, optional = true, features = ["alpn"], version = "0.6" }
hyper-hickory = { default-features = false, optional = true, version = "0.7" }
percent-encoding = { default-features = false, version = "2" }
rustls = { default-features = false, optional = true, version = "0.23" }
serde = { default-features = false, features = ["derive"], version = "1" }
serde_json = { default-features = false, features = ["std"], version = "1" }
tokio = { default-features = false, features = ["sync", "time"], version = "1.0" }
Expand All @@ -36,12 +37,16 @@ brotli-decompressor = { default-features = false, features = ["std"], optional =
simd-json = { default-features = false, features = ["serde_impl", "swar-number-parsing"], optional = true, version = ">=0.4, <0.14" }

[features]
default = ["decompression", "rustls-native-roots"]
default = ["decompression", "rustls-platform-verifier", "rustls-ring"]
decompression = ["dep:brotli-decompressor"]
native-tls = ["dep:hyper-tls"]
rustls-native-roots = ["dep:hyper-rustls", "hyper-rustls?/native-tokio"]
rustls-webpki-roots = ["dep:hyper-rustls", "hyper-rustls?/webpki-tokio"]
hickory = ["dep:hyper-hickory"]
native-tls = ["dep:hyper-tls"]
rustls-platform-verifier = ["dep:hyper-rustls", "dep:rustls", "hyper-rustls?/rustls-platform-verifier"]
rustls-native-roots = ["dep:hyper-rustls", "dep:rustls", "hyper-rustls?/native-tokio"]
rustls-webpki-roots = ["dep:hyper-rustls", "dep:rustls", "hyper-rustls?/webpki-tokio"]
rustls-ring = ["hyper-rustls?/ring"]
rustls-aws_lc_rs = ["hyper-rustls?/aws-lc-rs"]
rustls-aws-lc-rs = ["rustls-aws_lc_rs"] # Alias for convenience, underscores are preferred in the rustls stack

[dev-dependencies]
serde_test = { default-features = false, version = "1" }
Expand Down
37 changes: 34 additions & 3 deletions twilight-http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@ repository][github examples link].

## Features

### Crypto provider

Using [`rustls`] for TLS requires configuring a crypto provider via crate
features or manually installing a global default. The default is `rustls-ring`.

#### `rustls-ring`

The `rustls-ring` feature will enable the use of [`ring`] as the crypto
provider. This is recommended for platform compatibility.

#### `rustls-aws_lc_rs`

The `rustls-aws_lc_rs` feature will enable the use of [`aws-lc-rs`] as the
crypto provider. This is recommended for performance and on widely used
platforms.

#### Manual installation

If none of the other crypto providers are enabled, a custom one must be
installed by the application using [`CryptoProvider::install_default`].

### Decompression

The `decompression` feature enables brotli decompression support via the [`brotli`] crate.
Expand Down Expand Up @@ -53,7 +74,7 @@ twilight-http = { default-features = false, features = ["rustls-native-roots", "
Discord's API is HTTPS only.

`twilight-http` has features to enable HTTPS connectivity with [`hyper`]. These
features are mutually exclusive. `rustls-native-roots` is enabled by default.
features are mutually exclusive. `rustls-platform-verifier` is enabled by default.

#### `native-tls`

Expand All @@ -70,15 +91,21 @@ twilight-http = { default-features = false, features = ["native"], version = "0.

The `rustls-native-roots` feature uses a HTTPS connector provided by [`hyper-rustls`], which uses
[`rustls`] as the TLS backend, and enables its `native-tokio` feature, which uses [`rustls-native-certs`]
for root certificates.
for root certificates. This requires configuring a crypto provider.

#### `rustls-platform-verifier`

The `rustls-platform-verifier` feature uses a HTTPS connector provided by [`hyper-rustls`], which uses
[`rustls`] as the TLS backend, and enables its [`rustls-platform-verifier`] feature, which uses
[`rustls-platform-verifier`] for certificate validation. This requires configuring a crypto provider.

This is enabled by default.

#### `rustls-webpki-roots`

The `rustls-webpki-roots` feature uses a HTTPS connector provided by [`hyper-rustls`], which uses
[`rustls`] as the TLS backend, and enables its `webpki-tokio` feature, which uses [`webpki-roots`]
for root certificates.
for root certificates. This requires configuring a crypto provider.

This should be preferred over `rustls-native-roots` in Docker containers based on `scratch`.

Expand All @@ -88,13 +115,17 @@ The `hickory` feature enables [`hyper-hickory`], which replaces the default
`GaiResolver` in [`hyper`]. [`hyper-hickory`] instead provides a fully async
DNS resolver on the application level.

[`CryptoProvider::install_default`]: https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html#method.install_default
[`aws-lc-rs`]: https://crates.io/crates/aws-lc-rs
[`brotli`]: https://github.com/dropbox/rust-brotli
[`hyper`]: https://crates.io/crates/hyper
[`hyper-hickory`]: https://crates.io/crates/hyper-hickory
[`hyper-rustls`]: https://crates.io/crates/hyper-rustls
[`hyper-tls`]: https://crates.io/crates/hyper-tls
[`ring`]: https://crates.io/crates/ring
[`rustls`]: https://crates.io/crates/rustls
[`rustls-native-certs`]: https://crates.io/crates/rustls-native-certs
[`rustls-platform-verifier`]: https://crates.io/crates/rustls-platform-verifier
[`serde_json`]: https://crates.io/crates/serde_json
[`simd-json`]: https://crates.io/crates/simd-json
[`webpki-roots`]: https://crates.io/crates/webpki-roots
Expand Down
81 changes: 63 additions & 18 deletions twilight-http/src/client/connector.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
//! HTTP connectors with different features.

/// HTTPS connector using `rustls` as a TLS backend.
#[cfg(any(feature = "rustls-native-roots", feature = "rustls-webpki-roots"))]
#[cfg(any(
feature = "rustls-native-roots",
feature = "rustls-platform-verifier",
feature = "rustls-webpki-roots"
))]
type HttpsConnector<T> = hyper_rustls::HttpsConnector<T>;
/// HTTPS connector using `hyper-tls` as a TLS backend.
#[cfg(all(
feature = "native-tls",
not(any(feature = "rustls-native-roots", feature = "rustls-webpki-roots"))
not(any(
feature = "rustls-native-roots",
feature = "rustls-platform-verifier",
feature = "rustls-webpki-roots"
))
))]
type HttpsConnector<T> = hyper_tls::HttpsConnector<T>;

Expand All @@ -21,13 +29,15 @@ type HttpConnector = hyper_util::client::legacy::connect::HttpConnector;
#[cfg(any(
feature = "native-tls",
feature = "rustls-native-roots",
feature = "rustls-webpki-roots"
feature = "rustls-platform-verifier",
feature = "rustls-webpki-roots",
))]
pub type Connector = HttpsConnector<HttpConnector>;
/// Re-exported generic connector for use in the client.
#[cfg(not(any(
feature = "native-tls",
feature = "rustls-native-roots",
feature = "rustls-platform-verifier",
feature = "rustls-webpki-roots"
)))]
pub type Connector = HttpConnector;
Expand All @@ -41,24 +51,59 @@ pub fn create() -> Connector {

connector.enforce_http(false);

#[cfg(feature = "rustls-native-roots")]
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.expect("no native root certificates found")
.https_or_http()
.enable_http1()
.enable_http2()
.wrap_connector(connector);
#[cfg(all(feature = "rustls-webpki-roots", not(feature = "rustls-native-roots")))]
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_webpki_roots()
.https_or_http()
.enable_http1()
.enable_http2()
.wrap_connector(connector);
#[cfg(any(
feature = "rustls-native-roots",
feature = "rustls-platform-verifier",
feature = "rustls-webpki-roots"
))]
let connector = {
#[cfg(not(any(feature = "rustls-ring", feature = "rustls-aws_lc_rs")))]
let crypto_provider = rustls::crypto::CryptoProvider::get_default()
.expect("No default crypto provider installed or configured via crate features")
.clone();
#[cfg(feature = "rustls-aws_lc_rs")]
let crypto_provider = rustls::crypto::aws_lc_rs::default_provider();
#[cfg(all(feature = "rustls-ring", not(feature = "rustls-aws_lc_rs")))]
let crypto_provider = rustls::crypto::ring::default_provider();

#[cfg(all(
feature = "rustls-native-roots",
not(feature = "rustls-platform-verifier")
))]
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_provider_and_native_roots(crypto_provider)
.expect("no native roots found")
.https_or_http()
.enable_http1()
.enable_http2()
.wrap_connector(connector);
#[cfg(feature = "rustls-platform-verifier")]
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_provider_and_platform_verifier(crypto_provider)
.expect("no usable cipher suites in crypto provider")
.https_or_http()
.enable_http1()
.enable_http2()
.wrap_connector(connector);
#[cfg(all(
feature = "rustls-webpki-roots",
not(any(feature = "rustls-native-roots", feature = "rustls-platform-verifier"))
))]
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_provider_and_webpki_roots(crypto_provider)
.expect("no usable cipher suites in crypto provider")
.https_or_http()
.enable_http1()
.enable_http2()
.wrap_connector(connector);

connector
};

#[cfg(all(
feature = "native-tls",
not(feature = "rustls-native-roots"),
not(feature = "rustls-platform-verifier"),
not(feature = "rustls-webpki-roots")
))]
let connector = hyper_tls::HttpsConnector::new_with_connector(connector);
Expand Down
12 changes: 8 additions & 4 deletions twilight-lavalink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ http = { default-features = false, version = "1" }
serde = { default-features = false, features = ["derive", "std"], version = "1" }
serde_json = { default-features = false, features = ["std"], version = "1" }
tokio = { default-features = false, features = ["macros", "net", "rt", "sync", "time"], version = "1.0" }
tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.7" }
tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.10" }
tracing = { default-features = false, features = ["std", "attributes"], version = "0.1" }
twilight-model = { default-features = false, path = "../twilight-model", version = "0.16.0-rc.1" }

Expand All @@ -37,11 +37,15 @@ twilight-gateway = { default-features = false, features = ["rustls-native-roots"
twilight-http = { default-features = false, features = ["rustls-native-roots"], path = "../twilight-http", version = "0.16.0-rc.1" }

[features]
default = ["http-support", "rustls-native-roots"]
default = ["http-support", "rustls-platform-verifier", "rustls-ring"]
http-support = ["dep:percent-encoding"]
native-tls = ["tokio-websockets/native-tls", "tokio-websockets/openssl"]
rustls-native-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-native-roots"]
rustls-webpki-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-webpki-roots"]
rustls-platform-verifier = ["tokio-websockets/rustls-platform-verifier"]
rustls-native-roots = ["tokio-websockets/rustls-native-roots"]
rustls-webpki-roots = ["tokio-websockets/rustls-webpki-roots"]
rustls-ring = ["tokio-websockets/ring"]
rustls-aws_lc_rs = ["tokio-websockets/aws_lc_rs"]
rustls-aws-lc-rs = ["rustls-aws_lc_rs"] # Alias for convenience, underscores are preferred in the rustls stack

[package.metadata.docs.rs]
all-features = true
Expand Down
Loading

0 comments on commit f71e6e4

Please sign in to comment.