Skip to content

Commit 05112d1

Browse files
authored
Update TLS configuration to use aws-lc-rs crypto provider (#4230)
* Update TLS configuration to use aws-lc-rs crypto provider and improve error handling * Update approved licenses and remove obsolete package from manual approval list --------- Signed-off-by: Avi Fenesh <[email protected]>
1 parent 857ca73 commit 05112d1

File tree

5 files changed

+83
-63
lines changed

5 files changed

+83
-63
lines changed

glide-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ criterion = { version = "^0.6", features = ["html_reports", "async_tokio"] }
6565
which = "8"
6666
ctor = "0.4"
6767
redis = { path = "./redis-rs/redis", features = ["tls-rustls-insecure"] }
68-
rustls = { version = "0.23", features = ["ring"], default-features = false}
68+
rustls = { version = "0.23", features = ["aws-lc-rs"]}
6969
iai-callgrind = "0.14"
7070
tokio = { version = "1", features = ["rt-multi-thread"] }
7171
glide-core = { path = ".", features = [

glide-core/redis-rs/redis/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repository = "https://github.com/redis-rs/redis-rs"
88
documentation = "https://docs.rs/redis"
99
license = "BSD-3-Clause"
1010
edition = "2021"
11-
rust-version = "1.70"
11+
rust-version = "1.71"
1212
readme = "../README.md"
1313

1414
[package.metadata.docs.rs]
@@ -66,7 +66,7 @@ async-trait = { version = "0.1", optional = true }
6666
tokio-retry2 = { version = "0.5", features = ["jitter"], optional = true }
6767

6868
# Only needed for rustls (default TLS implementation)
69-
rustls = { version = "0.23", features = ["ring"], default-features = false }
69+
rustls = { version = "0.23", features = ["aws-lc-rs"] }
7070
rustls-platform-verifier = { version = "0.6", default-features = false }
7171
tokio-rustls = { version = "0.26", default-features = false }
7272
rustls-pemfile = { version = "2" }
@@ -122,7 +122,6 @@ aio = [
122122
json = ["serde", "serde/derive", "serde_json"]
123123
cluster = ["crc16", "rand"]
124124
tls-rustls-insecure = []
125-
126125
tokio-comp = ["aio", "tokio/net", "tokio-retry2"]
127126
tokio-rustls-comp = ["tokio-comp"]
128127
connection-manager = ["futures", "aio", "tokio-retry2"]

glide-core/redis-rs/redis/src/connection.rs

Lines changed: 74 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -766,105 +766,123 @@ pub(crate) fn create_rustls_config(
766766
insecure: bool,
767767
tls_params: Option<TlsConnParams>,
768768
) -> RedisResult<rustls::ClientConfig> {
769-
// install the default (ring) crypto provider exactly once
769+
// Install the default (aws-lc-rs) crypto provider exactly once.
770+
// This is the recommended approach as of rustls 0.23+ for best security and performance.
770771
CRYPTO_PROVIDER.get_or_init(|| {
771-
let _ = rustls::crypto::ring::default_provider().install_default();
772+
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
772773
});
773774

774775
use crate::tls::ClientTlsParams;
775776
use rustls_platform_verifier::BuilderVerifierExt;
776777

777-
let config = if let Some(tls_params) = tls_params {
778-
if let Some(root_cert_store) = tls_params.root_cert_store {
779-
// If custom root certificates are provided, use them instead of platform verifier
778+
// Build the TLS configuration following rustls best practices:
779+
// 1. Prefer platform verifier (recommended by rustls team for maximum compatibility)
780+
// 2. Fall back to custom root certificates only when explicitly provided
781+
// 3. Support client certificate authentication when needed
782+
let config = match tls_params {
783+
Some(tls_params) if tls_params.root_cert_store.is_some() => {
784+
// Custom root certificates explicitly provided - use them instead of platform verifier
785+
// This is for cases where specific certificate validation is required
786+
let root_cert_store = tls_params.root_cert_store.unwrap();
780787
let config = rustls::ClientConfig::builder().with_root_certificates(root_cert_store);
781788

782-
if let Some(ClientTlsParams {
783-
client_cert_chain: client_cert,
784-
client_key,
785-
}) = tls_params.client_tls_params
786-
{
787-
config
789+
match tls_params.client_tls_params {
790+
Some(ClientTlsParams {
791+
client_cert_chain: client_cert,
792+
client_key,
793+
}) => config
788794
.with_client_auth_cert(client_cert, client_key)
789795
.map_err(|err| {
790-
RedisError::from((
791-
ErrorKind::InvalidClientConfig,
792-
"Unable to build client with TLS parameters provided.",
793-
err.to_string(),
794-
))
795-
})?
796-
} else {
797-
config.with_no_client_auth()
796+
tls_config_error(
797+
"Failed to configure client certificate authentication with custom root store",
798+
err,
799+
)
800+
})?,
801+
None => config.with_no_client_auth(),
798802
}
799-
} else {
800-
// Use platform verifier when no custom root certificates are provided
803+
}
804+
Some(tls_params) => {
805+
// TLS params provided but no custom root certificates - use platform verifier (recommended)
806+
// Platform verifier provides live trust information and matches user expectations
801807
let config = rustls::ClientConfig::builder()
802808
.with_platform_verifier()
803809
.map_err(|err| {
804-
RedisError::from((
805-
ErrorKind::InvalidClientConfig,
806-
"Unable to configure platform verifier.",
807-
err.to_string(),
808-
))
810+
tls_config_error(
811+
"Failed to configure platform certificate verifier. This may indicate missing system certificate store or unsupported platform",
812+
err,
813+
)
809814
})?;
810815

811-
if let Some(ClientTlsParams {
812-
client_cert_chain: client_cert,
813-
client_key,
814-
}) = tls_params.client_tls_params
815-
{
816-
config
816+
match tls_params.client_tls_params {
817+
Some(ClientTlsParams {
818+
client_cert_chain: client_cert,
819+
client_key,
820+
}) => config
817821
.with_client_auth_cert(client_cert, client_key)
818822
.map_err(|err| {
819-
RedisError::from((
820-
ErrorKind::InvalidClientConfig,
821-
"Unable to build client with TLS parameters provided.",
822-
err.to_string(),
823-
))
824-
})?
825-
} else {
826-
config.with_no_client_auth()
823+
tls_config_error(
824+
"Failed to configure client certificate authentication with platform verifier",
825+
err,
826+
)
827+
})?,
828+
None => config.with_no_client_auth(),
827829
}
828830
}
829-
} else {
830-
// Default case: use platform verifier
831-
rustls::ClientConfig::builder()
832-
.with_platform_verifier()
833-
.map_err(|err| {
834-
RedisError::from((
835-
ErrorKind::InvalidClientConfig,
836-
"Unable to configure platform verifier.",
837-
err.to_string(),
838-
))
839-
})?
840-
.with_no_client_auth()
831+
None => {
832+
// Default case: use platform verifier with no client authentication
833+
// This is the recommended default configuration for most applications
834+
rustls::ClientConfig::builder()
835+
.with_platform_verifier()
836+
.map_err(|err| {
837+
tls_config_error(
838+
"Failed to configure default TLS settings with platform verifier. This may indicate missing system certificate store",
839+
err,
840+
)
841+
})?
842+
.with_no_client_auth()
843+
}
841844
};
842845

846+
// Handle insecure configurations (only when explicitly requested and feature enabled)
843847
match (insecure, cfg!(feature = "tls-rustls-insecure")) {
844848
#[cfg(feature = "tls-rustls-insecure")]
845849
(true, true) => {
850+
// WARNING: This disables certificate verification - use only for testing!
851+
// This configuration is inherently insecure and should never be used in production
846852
let mut config = config;
847853
config.enable_sni = false;
848-
// nosemgrep
854+
855+
// Use dangerous certificate verifier that accepts any certificate
856+
// nosemgrep - intentionally dangerous for testing purposes
849857
config
850858
.dangerous()
851859
.set_certificate_verifier(Arc::new(NoCertificateVerification {
852-
supported: rustls::crypto::ring::default_provider()
860+
supported: rustls::crypto::aws_lc_rs::default_provider()
853861
.signature_verification_algorithms,
854862
}));
855863

856864
Ok(config)
857865
}
858866
(true, false) => {
867+
// Insecure mode requested but feature not enabled - this is a configuration error
859868
fail!((
860869
ErrorKind::InvalidClientConfig,
861-
"Cannot create insecure client without tls-rustls-insecure feature"
870+
"Insecure TLS mode requested but 'tls-rustls-insecure' feature is not enabled. \
871+
Enable the feature flag or use secure TLS configuration."
862872
));
863873
}
864-
_ => Ok(config),
874+
(false, _) => {
875+
// Secure mode (default) - return the properly configured client
876+
Ok(config)
877+
}
865878
}
866879
}
867880

881+
/// Helper function to create consistent TLS configuration errors
882+
fn tls_config_error(context: &'static str, error: impl std::fmt::Display) -> RedisError {
883+
RedisError::from((ErrorKind::InvalidClientConfig, context, error.to_string()))
884+
}
885+
868886
fn connect_auth(con: &mut Connection, connection_info: &RedisConnectionInfo) -> RedisResult<()> {
869887
let mut command = cmd("AUTH");
870888
if let Some(username) = &connection_info.username {

glide-core/tests/utilities/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,8 +731,9 @@ fn init() {
731731
logger_core::init(Some(logger_core::Level::Debug), None);
732732

733733
// This needs to be done before any TLS connections are made
734-
let _ =
735-
rustls::crypto::CryptoProvider::install_default(rustls::crypto::ring::default_provider());
734+
let _ = rustls::crypto::CryptoProvider::install_default(
735+
rustls::crypto::aws_lc_rs::default_provider(),
736+
);
736737
}
737738

738739
pub async fn kill_connection(client: &mut impl glide_core::client::GlideClientForTests) {

utils/get_licenses_from_ort.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
"Apache-2.0 OR LGPL-2.1-or-later OR MIT",
4646
"Apache-2.0 AND ISC",
4747
"Apache-2.0 AND (Apache-2.0 OR MIT) AND MIT",
48+
"(Apache-2.0 OR ISC) AND ISC",
49+
"(Apache-2.0 OR ISC) AND ISC AND OpenSSL",
50+
"CDLA-Permissive-2.0"
4851
]
4952

5053
# Packages with non-pre-approved licenses that received manual approval.
@@ -53,7 +56,6 @@
5356
"PyPI::certifi:2023.11.17",
5457
"Crate::ring:0.17.8",
5558
"Maven:org.json:json:20231013",
56-
"Crate::webpki-root-certs:1.0.0"
5759
]
5860
SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
5961

0 commit comments

Comments
 (0)