From c788c9843727e5c64acd6cc3884631bdf80c9987 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 21 Sep 2023 14:17:49 -0700 Subject: [PATCH] meshtls: update to `rustls` v0.21.7 (#2472) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the proxy [depends on an outdated version of `rustls`][1], v0.20.8. The `rustls` dependency is via our dependency on `tokio-rustls` v0.23.4; we don't have a direct `rustls` dependency, in order to ensure that the version of `rustls` is always the same version as used by `tokio-rustls`. `rustls` also has a dependency on `webpki`, and v0.20.x of `rustls` uses the original `webpki` crate, rather than the `rustls-webpki` crate. So, unfortunately, because we have a transitive dep on `webpki` via `rustls`, PR linkerd/linkerd2-proxy#2465 did not remove _all_ `webpki` deps from our dependency tree, only the direct dependency. This branch updates to `rustls` v0.21.x, which depends on `rustls-webpki` rather than `webpki`, removing the `webpki` dependency. This is accomplished by updating `tokio-rustls` to v0.24.x, implicitly updating the transitive `rustls` dep. In order to update to the semver-incompatible version of `rustls`, it was necessary to modify our code in order to track some breaking API changes. I've also added a `cargo-deny` ban for `webpki` to our `deny.toml`, to ensure that we always use the actively-maintained `rustls-webpki` crate rather than `webpki` classic. Since peer certificate validation is performed through `rustls` rather than through the direct `rustls-webpki` dependency, this should hopefully resolve issues with issuer certs that contain name constraints --- these were not fixed by linkerd/linkerd2-proxy#2465, because the failure with certs containing name constraints occurred inside of the *`webpki` version depended on by `rustls`*, rather than inside of the proxy's direct dep. See [this comment][2] for details. In addition, it was necessary to update `rustls-webpki` to v0.101.6, since v0.101.5 was yanked due to an accidental API breaking change.
Verifying that we no longer depend on `webpki`: Before: ```console $ cargo tree -p webpki -i webpki v0.22.1 ├── rustls v0.20.8 │ └── tokio-rustls v0.23.4 │ ├── linkerd-app-integration v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/integration) │ └── linkerd-meshtls-rustls v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/meshtls/rustls) │ ├── linkerd-app-inbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/inbound) │ │ ├── linkerd-app v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app) │ │ │ ├── linkerd-app-integration v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/integration) │ │ │ └── linkerd2-proxy v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd2-proxy) │ │ ├── linkerd-app-admin v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/admin) │ │ │ └── linkerd-app v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app) (*) │ │ │ [dev-dependencies] │ │ │ └── linkerd-app-integration v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/integration) │ │ └── linkerd-app-gateway v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/gateway) │ │ └── linkerd-app v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app) (*) │ │ [dev-dependencies] │ │ └── linkerd-app-gateway v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/gateway) (*) │ ├── linkerd-app-outbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/outbound) │ │ ├── linkerd-app v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app) (*) │ │ └── linkerd-app-gateway v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/gateway) (*) │ │ [dev-dependencies] │ │ └── linkerd-app-gateway v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/gateway) (*) │ └── linkerd-meshtls v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/meshtls) │ ├── linkerd-app-core v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/core) │ │ ├── linkerd-app v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app) (*) │ │ ├── linkerd-app-admin v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/admin) (*) │ │ ├── linkerd-app-gateway v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/gateway) (*) │ │ ├── linkerd-app-inbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/inbound) (*) │ │ ├── linkerd-app-integration v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/integration) │ │ ├── linkerd-app-outbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/outbound) (*) │ │ └── linkerd-app-test v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/test) │ │ ├── linkerd-app-inbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/inbound) (*) │ │ ├── linkerd-app-integration v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/integration) │ │ └── linkerd-app-outbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/outbound) (*) │ │ [dev-dependencies] │ │ ├── linkerd-app-gateway v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/gateway) (*) │ │ ├── linkerd-app-inbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/inbound) (*) │ │ └── linkerd-app-outbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/outbound) (*) │ ├── linkerd-app-inbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/inbound) (*) │ ├── linkerd-proxy-tap v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/proxy/tap) │ │ └── linkerd-app-core v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/core) (*) │ └── linkerd2-proxy v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd2-proxy) │ [dev-dependencies] │ ├── linkerd-app-inbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/inbound) (*) │ ├── linkerd-app-integration v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/integration) │ └── linkerd-app-outbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/outbound) (*) │ [dev-dependencies] │ ├── linkerd-app-inbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/inbound) (*) │ └── linkerd-app-outbound v0.1.0 (/home/eliza/Code/linkerd2-proxy/linkerd/app/outbound) (*) └── tokio-rustls v0.23.4 (*) ``` After: ```console $ cargo tree -p webpki -i error: package ID specification `webpki` did not match any packages ```
[1]: https://github.com/linkerd/linkerd2-proxy/blob/8afc72258b8ced868fbd0bde0235955c0adf4ccd/Cargo.lock#L2450-L2460C2 [2]: https://github.com/linkerd/linkerd2/issues/9299#issuecomment-1730094953 --- Cargo.lock | 25 ++++++-------------- deny.toml | 2 ++ linkerd/app/integration/Cargo.toml | 2 +- linkerd/app/integration/src/identity.rs | 4 ++-- linkerd/meshtls/rustls/Cargo.toml | 2 +- linkerd/meshtls/rustls/src/creds.rs | 10 +++++--- linkerd/meshtls/rustls/src/creds/receiver.rs | 2 +- linkerd/meshtls/rustls/src/creds/store.rs | 8 ++++--- 8 files changed, 26 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd55154966..5eeaecf837 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2415,14 +2415,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -2436,9 +2436,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.5" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ "ring", "untrusted", @@ -2708,13 +2708,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", - "webpki", ] [[package]] @@ -3122,16 +3121,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "which" version = "4.4.0" diff --git a/deny.toml b/deny.toml index 94ec1293c4..e4c9433935 100644 --- a/deny.toml +++ b/deny.toml @@ -51,6 +51,8 @@ wildcards = "allow" highlight = "all" deny = [ { name = "rustls", wrappers = ["tokio-rustls"] }, + # rustls-webpki should be used instead. + { name = "webpki" }, ] skip = [ # The proc-macro ecosystem is in the middle of a migration from `syn` v1 to diff --git a/linkerd/app/integration/Cargo.toml b/linkerd/app/integration/Cargo.toml index 39080a0621..773cfd773c 100644 --- a/linkerd/app/integration/Cargo.toml +++ b/linkerd/app/integration/Cargo.toml @@ -46,7 +46,7 @@ regex = "1" socket2 = "0.4" tokio = { version = "1", features = ["io-util", "net", "rt", "macros"] } tokio-stream = { version = "0.1", features = ["sync"] } -tokio-rustls = "0.23" +tokio-rustls = "0.24" rustls-pemfile = "1.0" tower = { version = "0.4", default-features = false } tonic = { version = "0.8", features = ["transport"], default-features = false } diff --git a/linkerd/app/integration/src/identity.rs b/linkerd/app/integration/src/identity.rs index 69ebaf340f..94bff0cdb5 100644 --- a/linkerd/app/integration/src/identity.rs +++ b/linkerd/app/integration/src/identity.rs @@ -114,8 +114,8 @@ impl Identity { .with_safe_default_kx_groups() .with_protocol_versions(TLS_VERSIONS) .expect("server config must be valid") - .with_client_cert_verifier(rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new( - roots, + .with_client_cert_verifier(Arc::new( + rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(roots), )) .with_single_cert(certs.chain(), key) .unwrap(); diff --git a/linkerd/meshtls/rustls/Cargo.toml b/linkerd/meshtls/rustls/Cargo.toml index 7a01e3e5ba..51e56a1826 100644 --- a/linkerd/meshtls/rustls/Cargo.toml +++ b/linkerd/meshtls/rustls/Cargo.toml @@ -22,7 +22,7 @@ rustls-pemfile = "1.0" rustls-webpki = { version = "0.101.5", features = [ "std"] } thiserror = "1" tokio = { version = "1", features = ["macros", "rt", "sync"] } -tokio-rustls = { version = "0.23", features = ["dangerous_configuration"] } +tokio-rustls = { version = "0.24", features = ["dangerous_configuration"] } tracing = "0.1" [dev-dependencies] diff --git a/linkerd/meshtls/rustls/src/creds.rs b/linkerd/meshtls/rustls/src/creds.rs index 5baf1df745..084efecae3 100644 --- a/linkerd/meshtls/rustls/src/creds.rs +++ b/linkerd/meshtls/rustls/src/creds.rs @@ -65,7 +65,11 @@ pub fn watch( // client certificate resolver. let mut c = store::client_config_builder(server_cert_verifier.clone()).with_no_client_auth(); - c.enable_tickets = false; + + // Disable session resumption for the time-being until resumption is + // more tested. + c.resumption = rustls::client::Resumption::disabled(); + watch::channel(Arc::new(c)) }; let (server_tx, server_rx) = { @@ -114,8 +118,8 @@ mod params { &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING; pub const SIGNATURE_ALG_RUSTLS_SCHEME: rustls::SignatureScheme = rustls::SignatureScheme::ECDSA_NISTP256_SHA256; - pub const SIGNATURE_ALG_RUSTLS_ALGORITHM: rustls::internal::msgs::enums::SignatureAlgorithm = - rustls::internal::msgs::enums::SignatureAlgorithm::ECDSA; + pub const SIGNATURE_ALG_RUSTLS_ALGORITHM: rustls::SignatureAlgorithm = + rustls::SignatureAlgorithm::ECDSA; pub static TLS_VERSIONS: &[&rustls::SupportedProtocolVersion] = &[&rustls::version::TLS13]; pub static TLS_SUPPORTED_CIPHERSUITES: &[rustls::SupportedCipherSuite] = &[rustls::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256]; diff --git a/linkerd/meshtls/rustls/src/creds/receiver.rs b/linkerd/meshtls/rustls/src/creds/receiver.rs index 0b69b63095..51c1a1f558 100644 --- a/linkerd/meshtls/rustls/src/creds/receiver.rs +++ b/linkerd/meshtls/rustls/src/creds/receiver.rs @@ -63,7 +63,7 @@ mod tests { fn empty_server_config() -> rustls::ServerConfig { rustls::ServerConfig::builder() .with_safe_defaults() - .with_client_cert_verifier(rustls::server::NoClientAuth::new()) + .with_client_cert_verifier(Arc::new(rustls::server::NoClientAuth)) .with_cert_resolver(Arc::new(rustls::server::ResolvesServerCertUsingSni::new())) } diff --git a/linkerd/meshtls/rustls/src/creds/store.rs b/linkerd/meshtls/rustls/src/creds/store.rs index 864222732b..1c744106bd 100644 --- a/linkerd/meshtls/rustls/src/creds/store.rs +++ b/linkerd/meshtls/rustls/src/creds/store.rs @@ -54,7 +54,9 @@ pub(super) fn server_config( // controlling the set of trusted signature algorithms), but they provide good enough // defaults for now. // TODO: lock down the verification further. - let client_cert_verifier = rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(roots); + let client_cert_verifier = Arc::new( + rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(roots), + ); rustls::ServerConfig::builder() .with_cipher_suites(TLS_SUPPORTED_CIPHERSUITES) .with_safe_default_kx_groups() @@ -95,7 +97,7 @@ impl Store { // Disable session resumption for the time-being until resumption is // more tested. - cfg.enable_tickets = false; + cfg.resumption = rustls::client::Resumption::disabled(); cfg.into() } @@ -183,7 +185,7 @@ impl rustls::sign::SigningKey for Key { Some(Box::new(self.clone())) } - fn algorithm(&self) -> rustls::internal::msgs::enums::SignatureAlgorithm { + fn algorithm(&self) -> rustls::SignatureAlgorithm { SIGNATURE_ALG_RUSTLS_ALGORITHM } }