From 89a434c4558354a386a5a832fe0876af0ccac4e8 Mon Sep 17 00:00:00 2001 From: Steven McDonald Date: Wed, 4 Jun 2025 12:06:00 -0700 Subject: [PATCH] TLS options from GreatFire Envoy patch from Matthew Bogner --- components/cronet/android/api.txt | 8 +++- .../src/org/chromium/net/CronetEngine.java | 18 ++++++++ .../chromium/net/ICronetEngineBuilder.java | 6 +++ components/cronet/android/api_version.txt | 2 +- .../cronet/android/cronet_context_adapter.cc | 3 ++ .../impl/AndroidHttpEngineBuilderWrapper.java | 24 +++++++++++ .../net/impl/CronetEngineBuilderImpl.java | 33 ++++++++++++++ .../net/impl/CronetUrlRequestContext.java | 12 ++++++ .../proto/request_context_config.proto | 3 ++ .../CronetSampleApplication.java | 8 +++- ...xperimentalOptionsTranslationTestUtil.java | 15 +++++++ components/cronet/native/cronet.idl | 7 +++ components/cronet/native/engine.cc | 3 ++ .../cronet/native/generated/cronet.idl_c.h | 18 ++++++++ .../generated/cronet.idl_impl_struct.cc | 36 ++++++++++++++++ .../native/generated/cronet.idl_impl_struct.h | 3 ++ components/cronet/native/sample/main.cc | 3 ++ .../cronet/url_request_context_config.cc | 43 +++++++++++++++++++ .../cronet/url_request_context_config.h | 26 +++++++++++ net/ssl/ssl_config_service_defaults.cc | 5 +++ net/ssl/ssl_config_service_defaults.h | 2 + 21 files changed, 275 insertions(+), 3 deletions(-) diff --git a/components/cronet/android/api.txt b/components/cronet/android/api.txt index dd438268ceb942..86135d4ac74be2 100644 --- a/components/cronet/android/api.txt +++ b/components/cronet/android/api.txt @@ -96,9 +96,12 @@ public class org.chromium.net.CronetEngine$Builder { public org.chromium.net.CronetEngine$Builder enableSdch(boolean); public org.chromium.net.CronetEngine$Builder setConnectionMigrationOptions(org.chromium.net.ConnectionMigrationOptions$Builder); public org.chromium.net.CronetEngine$Builder setConnectionMigrationOptions(org.chromium.net.ConnectionMigrationOptions); + public org.chromium.net.CronetEngine$Builder setDisabledCipherSuites(java.lang.String); public org.chromium.net.CronetEngine$Builder setDnsOptions(org.chromium.net.DnsOptions$Builder); public org.chromium.net.CronetEngine$Builder setDnsOptions(org.chromium.net.DnsOptions); public org.chromium.net.CronetEngine$Builder setLibraryLoader(org.chromium.net.CronetEngine$Builder$LibraryLoader); + public org.chromium.net.CronetEngine$Builder setMaxSslVersion(java.lang.Short); + public org.chromium.net.CronetEngine$Builder setMinSslVersion(java.lang.Short); public org.chromium.net.CronetEngine$Builder setQuicOptions(org.chromium.net.QuicOptions$Builder); public org.chromium.net.CronetEngine$Builder setQuicOptions(org.chromium.net.QuicOptions); public org.chromium.net.CronetEngine$Builder setStoragePath(java.lang.String); @@ -321,8 +324,11 @@ public abstract class org.chromium.net.ICronetEngineBuilder { public abstract org.chromium.net.ICronetEngineBuilder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean); public abstract org.chromium.net.ICronetEngineBuilder enableQuic(boolean); public abstract org.chromium.net.ICronetEngineBuilder enableSdch(boolean); + public abstract org.chromium.net.ICronetEngineBuilder setDisabledCipherSuites(java.lang.String); public abstract org.chromium.net.ICronetEngineBuilder setExperimentalOptions(java.lang.String); public abstract org.chromium.net.ICronetEngineBuilder setLibraryLoader(org.chromium.net.CronetEngine$Builder$LibraryLoader); + public abstract org.chromium.net.ICronetEngineBuilder setMaxSslVersion(java.lang.Short); + public abstract org.chromium.net.ICronetEngineBuilder setMinSslVersion(java.lang.Short); public abstract org.chromium.net.ICronetEngineBuilder setStoragePath(java.lang.String); public abstract org.chromium.net.ICronetEngineBuilder setUserAgent(java.lang.String); public org.chromium.net.ICronetEngineBuilder enableBrotli(boolean); @@ -640,4 +646,4 @@ public class org.chromium.net.apihelpers.UrlRequestCallbacks { public static org.chromium.net.apihelpers.UrlRequestCallbacks$CallbackAndResponseFuturePair forStringBody(org.chromium.net.apihelpers.RedirectHandler); public static org.chromium.net.apihelpers.UrlRequestCallbacks$CallbackAndResponseFuturePair forJsonBody(org.chromium.net.apihelpers.RedirectHandler); } -Stamp: ded30b9fbe22dff6cc175cd483aa1e4b +Stamp: 360967594a7b7589a4d46adb87bdcd88 diff --git a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java index 69794dee12b5c2..118063c38fcf69 100644 --- a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java +++ b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java @@ -136,6 +136,24 @@ public abstract static class LibraryLoader { /** Reference to the actual builder implementation. {@hide exclude from JavaDoc}. */ protected final ICronetEngineBuilder mBuilderDelegate; + /** + * Additional arguments to configure the url request context. + */ + public Builder setDisabledCipherSuites(String disabledCipherSuites) { + mBuilderDelegate.setDisabledCipherSuites(disabledCipherSuites); + return this; + } + + public Builder setMinSslVersion(Short minSslVersion) { + mBuilderDelegate.setMinSslVersion(minSslVersion); + return this; + } + + public Builder setMaxSslVersion(Short maxSslVersion) { + mBuilderDelegate.setMaxSslVersion(maxSslVersion); + return this; + } + /** * Constructs a {@link Builder} object that facilitates creating a {@link CronetEngine}. The * default configuration enables HTTP/2 and QUIC, but disables the HTTP cache. diff --git a/components/cronet/android/api/src/org/chromium/net/ICronetEngineBuilder.java b/components/cronet/android/api/src/org/chromium/net/ICronetEngineBuilder.java index f340a87dc2ee15..99081fc7557be3 100644 --- a/components/cronet/android/api/src/org/chromium/net/ICronetEngineBuilder.java +++ b/components/cronet/android/api/src/org/chromium/net/ICronetEngineBuilder.java @@ -75,6 +75,12 @@ public abstract ICronetEngineBuilder setLibraryLoader( public abstract ICronetEngineBuilder setUserAgent(String userAgent); + public abstract ICronetEngineBuilder setDisabledCipherSuites(String disabledSuites); + + public abstract ICronetEngineBuilder setMinSslVersion(Short minVersion); + + public abstract ICronetEngineBuilder setMaxSslVersion(Short maxVersion); + public abstract String getDefaultUserAgent(); public abstract ExperimentalCronetEngine build(); diff --git a/components/cronet/android/api_version.txt b/components/cronet/android/api_version.txt index 7facc89938bbc5..81b5c5d06cc0b8 100644 --- a/components/cronet/android/api_version.txt +++ b/components/cronet/android/api_version.txt @@ -1 +1 @@ -36 +37 diff --git a/components/cronet/android/cronet_context_adapter.cc b/components/cronet/android/cronet_context_adapter.cc index d0a82f4a345f7e..4a1c99f408c1cc 100644 --- a/components/cronet/android/cronet_context_adapter.cc +++ b/components/cronet/android/cronet_context_adapter.cc @@ -243,6 +243,9 @@ static jlong JNI_CronetUrlRequestContext_CreateRequestContextConfig( configOptions.http_cache_max_size(), configOptions.disable_cache(), configOptions.storage_path(), /* accept_languages */ std::string(), configOptions.user_agent(), + configOptions.disabled_cipher_suites(), + configOptions.min_ssl_version(), + configOptions.max_ssl_version(), configOptions.experimental_options(), base::WrapUnique(reinterpret_cast( configOptions.mock_cert_verifier())), diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineBuilderWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineBuilderWrapper.java index a213d30854d163..dcd7356a6d96f4 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineBuilderWrapper.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineBuilderWrapper.java @@ -47,6 +47,30 @@ public ICronetEngineBuilder setUserAgent(String userAgent) { return this; } + @Override + public ICronetEngineBuilder setDisabledCipherSuites(String disabledCipherSuites) { + // need to implement abstract method, but mBackend + // class has not been updated with new parameters + // mBackend.setDisabledCipherSuites(disabledCipherSuites); + return this; + } + + @Override + public ICronetEngineBuilder setMinSslVersion(Short minSslVersion) { + // need to implement abstract method, but mBackend + // class has not been updated with new parameters + // mBackend.setMinSslVersion(minSslVersion); + return this; + } + + @Override + public ICronetEngineBuilder setMaxSslVersion(Short maxSslVersion) { + // need to implement abstract method, but mBackend + // class has not been updated with new parameters + // mBackend.setMaxSslVersion(maxSslVersion); + return this; + } + @Override public ICronetEngineBuilder setStoragePath(String value) { mBackend.setStoragePath(value); diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java index 5660d160231f1a..248c6983af6447 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java @@ -143,6 +143,9 @@ static HttpCacheMode fromPublicBuilderCacheMode(@HttpCacheSetting int cacheMode) private boolean mBrotiEnabled; private HttpCacheMode mHttpCacheMode; private long mHttpCacheMaxSize; + private String mDisabledCipherSuites; + private Short mMinSslVersion; + private Short mMaxSslVersion; private String mExperimentalOptions; protected long mMockCertVerifier; private boolean mNetworkQualityEstimatorEnabled; @@ -226,6 +229,36 @@ String getUserAgent() { return mUserAgent; } + @Override + public CronetEngineBuilderImpl setDisabledCipherSuites(String disabledCipherSuites) { + mDisabledCipherSuites = disabledCipherSuites; + return this; + } + + public String getDisabledCipherSuites() { + return mDisabledCipherSuites; + } + + @Override + public CronetEngineBuilderImpl setMinSslVersion(Short minSslVersion) { + mMinSslVersion = minSslVersion; + return this; + } + + public Short getMinSslVersion() { + return mMinSslVersion; + } + + @Override + public CronetEngineBuilderImpl setMaxSslVersion(Short maxSslVersion) { + mMaxSslVersion = maxSslVersion; + return this; + } + + public Short getMaxSslVersion() { + return mMaxSslVersion; + } + @Override public CronetEngineBuilderImpl setStoragePath(String value) { if (!new File(value).isDirectory()) { diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java index dcaf7703e79f93..33d7ea29400fe8 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java @@ -447,6 +447,18 @@ private static RequestContextConfigOptions createRequestContextConfigOptions( resultBuilder.setExperimentalOptions(engineBuilder.experimentalOptions()); } + if (engineBuilder.getDisabledCipherSuites() != null) { + resultBuilder.setDisabledCipherSuites(engineBuilder.getDisabledCipherSuites()); + } + + if (engineBuilder.getMinSslVersion() != null) { + resultBuilder.setMinSslVersion(engineBuilder.getMinSslVersion()); + } + + if (engineBuilder.getMaxSslVersion() != null) { + resultBuilder.setMaxSslVersion(engineBuilder.getMaxSslVersion()); + } + return resultBuilder.build(); } diff --git a/components/cronet/android/proto/request_context_config.proto b/components/cronet/android/proto/request_context_config.proto index 348bd84d5e23ef..57fc2271493888 100644 --- a/components/cronet/android/proto/request_context_config.proto +++ b/components/cronet/android/proto/request_context_config.proto @@ -21,4 +21,7 @@ message RequestContextConfigOptions { optional bool enable_network_quality_estimator = 12; optional bool bypass_public_key_pinning_for_local_trust_anchors = 13; optional int32 network_thread_priority = 14; + optional string disabled_cipher_suites = 17; + optional int32 min_ssl_version = 18; + optional int32 max_ssl_version = 19; } diff --git a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java index 87436d5a2d90c4..749c1f9240965e 100644 --- a/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java +++ b/components/cronet/android/sample/src/org/chromium/cronet_sample_apk/CronetSampleApplication.java @@ -24,7 +24,10 @@ public void onCreate() { myBuilder .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024) .enableHttp2(true) - .enableQuic(true); + .enableQuic(true) + .setDisabledCipherSuites("0xc024,0xc02f,0002") + .setMinSslVersion((short)0x0303) // net::SSL_PROTOCOL_VERSION_TLS1_2 + .setMaxSslVersion((short)0x0304); // net::SSL_PROTOCOL_VERSION_TLS1_3 mCronetEngine = myBuilder.build(); } @@ -61,6 +64,9 @@ public void restartCronetEngine() { .setDnsOptions(dnsOptionsBuilder) .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024) .enableHttp2(true) + .setDisabledCipherSuites("0xc024,0xc02f,0002") + .setMinSslVersion((short)0x0303) // net::SSL_PROTOCOL_VERSION_TLS1_2 + .setMaxSslVersion((short)0x0304) // net::SSL_PROTOCOL_VERSION_TLS1_3 .enableQuic(true) .build(); } diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTestUtil.java b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTestUtil.java index a070ec49d39596..8911589663c027 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTestUtil.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTestUtil.java @@ -190,6 +190,21 @@ public String getDefaultUserAgent() { throw new UnsupportedOperationException(); } + @Override + public ICronetEngineBuilder setDisabledCipherSuites(String disabledSuites) { + throw new UnsupportedOperationException(); + } + + @Override + public ICronetEngineBuilder setMinSslVersion(Short minVersion) { + throw new UnsupportedOperationException(); + } + + @Override + public ICronetEngineBuilder setMaxSslVersion(Short maxVersion) { + throw new UnsupportedOperationException(); + } + @Override public ICronetEngineBuilder setConnectionMigrationOptions( ConnectionMigrationOptions options) { diff --git a/components/cronet/native/cronet.idl b/components/cronet/native/cronet.idl index 8e83cb0cf70a40..9c2715559d8d89 100644 --- a/components/cronet/native/cronet.idl +++ b/components/cronet/native/cronet.idl @@ -511,6 +511,13 @@ struct EngineParams { */ string user_agent; + /** + * Additional arguments to configure the url request context. + */ + string disabled_cipher_suites; + uint16_t min_ssl_version; + uint16_t max_ssl_version; + /** * Sets a default value for the Accept-Language header value for UrlRequests * created by this engine. Explicitly setting the Accept-Language header diff --git a/components/cronet/native/engine.cc b/components/cronet/native/engine.cc index c35c4dbfc33ec1..dbc6a45b58d03c 100644 --- a/components/cronet/native/engine.cc +++ b/components/cronet/native/engine.cc @@ -149,6 +149,9 @@ Cronet_RESULT Cronet_EngineImpl::StartWithParams( context_config_builder.storage_path = params->storage_path; context_config_builder.accept_language = params->accept_language; context_config_builder.user_agent = params->user_agent; + context_config_builder.disabled_cipher_suites = params->disabled_cipher_suites; + context_config_builder.min_ssl_version = params->min_ssl_version; + context_config_builder.max_ssl_version = params->max_ssl_version; context_config_builder.experimental_options = params->experimental_options; context_config_builder.bypass_public_key_pinning_for_local_trust_anchors = params->enable_public_key_pinning_bypass_for_local_trust_anchors; diff --git a/components/cronet/native/generated/cronet.idl_c.h b/components/cronet/native/generated/cronet.idl_c.h index 988e6efacb0f32..ff5fdca1991e99 100644 --- a/components/cronet/native/generated/cronet.idl_c.h +++ b/components/cronet/native/generated/cronet.idl_c.h @@ -795,6 +795,15 @@ CRONET_EXPORT void Cronet_EngineParams_user_agent_set(Cronet_EngineParamsPtr self, const Cronet_String user_agent); CRONET_EXPORT +void Cronet_EngineParams_disabled_cipher_suites_set(Cronet_EngineParamsPtr self, + const Cronet_String disabled_cipher_suites); +CRONET_EXPORT +void Cronet_EngineParams_min_ssl_version_set(Cronet_EngineParamsPtr self, + const uint16_t min_ssl_version); +CRONET_EXPORT +void Cronet_EngineParams_max_ssl_version_set(Cronet_EngineParamsPtr self, + const uint16_t max_ssl_version); +CRONET_EXPORT void Cronet_EngineParams_accept_language_set( Cronet_EngineParamsPtr self, const Cronet_String accept_language); @@ -845,6 +854,15 @@ CRONET_EXPORT Cronet_String Cronet_EngineParams_user_agent_get( const Cronet_EngineParamsPtr self); CRONET_EXPORT +Cronet_String Cronet_EngineParams_disabled_cipher_suites_get( + const Cronet_EngineParamsPtr self); +CRONET_EXPORT +uint16_t Cronet_EngineParams_min_ssl_version_get( + const Cronet_EngineParamsPtr self); +CRONET_EXPORT +uint16_t Cronet_EngineParams_max_ssl_version_get( + const Cronet_EngineParamsPtr self); +CRONET_EXPORT Cronet_String Cronet_EngineParams_accept_language_get( const Cronet_EngineParamsPtr self); CRONET_EXPORT diff --git a/components/cronet/native/generated/cronet.idl_impl_struct.cc b/components/cronet/native/generated/cronet.idl_impl_struct.cc index b9120ff8c24f69..086248c48f0109 100644 --- a/components/cronet/native/generated/cronet.idl_impl_struct.cc +++ b/components/cronet/native/generated/cronet.idl_impl_struct.cc @@ -249,6 +249,24 @@ void Cronet_EngineParams_user_agent_set(Cronet_EngineParamsPtr self, self->user_agent = user_agent; } +void Cronet_EngineParams_disabled_cipher_suites_set(Cronet_EngineParamsPtr self, + const Cronet_String disabled_cipher_suites) { + DCHECK(self); + self->disabled_cipher_suites = disabled_cipher_suites; +} + +void Cronet_EngineParams_min_ssl_version_set(Cronet_EngineParamsPtr self, + const uint16_t min_ssl_version) { + DCHECK(self); + self->min_ssl_version = min_ssl_version; +} + +void Cronet_EngineParams_max_ssl_version_set(Cronet_EngineParamsPtr self, + const uint16_t max_ssl_version) { + DCHECK(self); + self->max_ssl_version = max_ssl_version; +} + void Cronet_EngineParams_accept_language_set( Cronet_EngineParamsPtr self, const Cronet_String accept_language) { @@ -342,6 +360,24 @@ Cronet_String Cronet_EngineParams_user_agent_get( return self->user_agent.c_str(); } +Cronet_String Cronet_EngineParams_disabled_cipher_suites_get( + const Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->disabled_cipher_suites.c_str(); +} + +uint16_t Cronet_EngineParams_min_ssl_version_get( + const Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->min_ssl_version; +} + +uint16_t Cronet_EngineParams_max_ssl_version_get( + const Cronet_EngineParamsPtr self) { + DCHECK(self); + return self->max_ssl_version; +} + Cronet_String Cronet_EngineParams_accept_language_get( const Cronet_EngineParamsPtr self) { DCHECK(self); diff --git a/components/cronet/native/generated/cronet.idl_impl_struct.h b/components/cronet/native/generated/cronet.idl_impl_struct.h index badb341ce331cd..9c23e359495535 100644 --- a/components/cronet/native/generated/cronet.idl_impl_struct.h +++ b/components/cronet/native/generated/cronet.idl_impl_struct.h @@ -94,6 +94,9 @@ struct Cronet_EngineParams { std::vector public_key_pins; bool enable_public_key_pinning_bypass_for_local_trust_anchors = true; double network_thread_priority = std::numeric_limits::quiet_NaN(); + std::string disabled_cipher_suites; + uint16_t min_ssl_version; + uint16_t max_ssl_version; std::string experimental_options; }; diff --git a/components/cronet/native/sample/main.cc b/components/cronet/native/sample/main.cc index fe9ff6f1ee2791..2aed74e7458786 100644 --- a/components/cronet/native/sample/main.cc +++ b/components/cronet/native/sample/main.cc @@ -18,6 +18,9 @@ Cronet_EnginePtr CreateCronetEngine() { Cronet_EngineParamsPtr engine_params = Cronet_EngineParams_Create(); Cronet_EngineParams_user_agent_set(engine_params, "CronetSample/1"); Cronet_EngineParams_enable_quic_set(engine_params, true); + Cronet_EngineParams_disabled_cipher_suites_set(engine_params, "0xc024,0xc02f,0002"); + Cronet_EngineParams_min_ssl_version_set(engine_params, 0x0303); // TLS 1.2 + Cronet_EngineParams_max_ssl_version_set(engine_params, 0x0304); // TLS 1.3 Cronet_Engine_StartWithParams(cronet_engine, engine_params); Cronet_EngineParams_Destroy(engine_params); diff --git a/components/cronet/url_request_context_config.cc b/components/cronet/url_request_context_config.cc index 8da024badd93ab..51e4d1e9de39a6 100644 --- a/components/cronet/url_request_context_config.cc +++ b/components/cronet/url_request_context_config.cc @@ -37,6 +37,9 @@ #include "net/nqe/network_quality_estimator_params.h" #include "net/quic/set_quic_flag.h" #include "net/socket/ssl_client_socket.h" +#include "net/ssl/ssl_cipher_suite_names.h" +#include "net/ssl/ssl_config.h" +#include "net/ssl/ssl_config_service_defaults.h" #include "net/ssl/ssl_key_logger_impl.h" #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h" #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h" @@ -311,6 +314,9 @@ URLRequestContextConfig::URLRequestContextConfig( const std::string& storage_path, const std::string& accept_language, const std::string& user_agent, + const std::string& disabled_cipher_suites, + const uint16_t min_ssl_version, + const uint16_t max_ssl_version, base::Value::Dict experimental_options, std::unique_ptr mock_cert_verifier, bool enable_network_quality_estimator, @@ -325,6 +331,9 @@ URLRequestContextConfig::URLRequestContextConfig( storage_path(storage_path), accept_language(accept_language), user_agent(user_agent), + disabled_cipher_suites(disabled_cipher_suites), + min_ssl_version(min_ssl_version), + max_ssl_version(max_ssl_version), mock_cert_verifier(std::move(mock_cert_verifier)), enable_network_quality_estimator(enable_network_quality_estimator), bypass_public_key_pinning_for_local_trust_anchors( @@ -351,6 +360,9 @@ URLRequestContextConfig::CreateURLRequestContextConfig( const std::string& storage_path, const std::string& accept_language, const std::string& user_agent, + const std::string& disabled_cipher_suites, + const uint16_t min_ssl_version, + const uint16_t max_ssl_version, const std::string& unparsed_experimental_options, std::unique_ptr mock_cert_verifier, bool enable_network_quality_estimator, @@ -369,6 +381,7 @@ URLRequestContextConfig::CreateURLRequestContextConfig( return base::WrapUnique(new URLRequestContextConfig( enable_quic, enable_spdy, enable_brotli, http_cache, http_cache_max_size, load_disable_cache, storage_path, accept_language, user_agent, + disabled_cipher_suites, min_ssl_version, max_ssl_version, std::move(experimental_options).value(), std::move(mock_cert_verifier), enable_network_quality_estimator, bypass_public_key_pinning_for_local_trust_anchors, @@ -879,6 +892,35 @@ void URLRequestContextConfig::ConfigureURLRequestContextBuilder( } context_builder->set_accept_language(accept_language); context_builder->set_user_agent(user_agent); + + net::SSLContextConfig ssl_context_config; + if (!disabled_cipher_suites.empty()) { + auto cipher_strings = base::SplitString(disabled_cipher_suites, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + // see net::ParseCipherSuites(cipher_strings); + std::vector cipher_suites; + cipher_suites.reserve(cipher_strings.size()); + + for (auto it = cipher_strings.begin(); it != cipher_strings.end(); ++it) { + uint16_t cipher_suite = 0; + if (!net::ParseSSLCipherString(*it, &cipher_suite)) { + continue; + } + cipher_suites.push_back(cipher_suite); + } + std::sort(cipher_suites.begin(), cipher_suites.end()); + + ssl_context_config.disabled_cipher_suites = cipher_suites; + } + + if (min_ssl_version != net::kDefaultSSLVersionMin) { + ssl_context_config.version_min = min_ssl_version; + } + if (max_ssl_version != net::kDefaultSSLVersionMax) { + ssl_context_config.version_max = max_ssl_version; + } + auto ssl_config_service_ptr = std::make_unique(ssl_context_config); + context_builder->set_ssl_config_service(std::move(ssl_config_service_ptr)); + net::HttpNetworkSessionParams session_params; session_params.enable_http2 = enable_spdy; session_params.enable_quic = enable_quic; @@ -909,6 +951,7 @@ URLRequestContextConfigBuilder::Build() { return URLRequestContextConfig::CreateURLRequestContextConfig( enable_quic, enable_spdy, enable_brotli, http_cache, http_cache_max_size, load_disable_cache, storage_path, accept_language, user_agent, + disabled_cipher_suites, min_ssl_version, max_ssl_version, experimental_options, std::move(mock_cert_verifier), enable_network_quality_estimator, bypass_public_key_pinning_for_local_trust_anchors, diff --git a/components/cronet/url_request_context_config.h b/components/cronet/url_request_context_config.h index 324525466cf245..445c291012207c 100644 --- a/components/cronet/url_request_context_config.h +++ b/components/cronet/url_request_context_config.h @@ -17,6 +17,7 @@ #include "net/base/network_handle.h" #include "net/cert/cert_verifier.h" #include "net/nqe/effective_connection_type.h" +#include "net/ssl/ssl_config.h" #include "url/origin.h" namespace net { @@ -128,6 +129,13 @@ struct URLRequestContextConfig { // User-Agent request header field. const std::string user_agent; + // cipher suite config field. + const std::string disabled_cipher_suites; + + // ssl version config fields. + const uint16_t min_ssl_version; + const uint16_t max_ssl_version; + // Certificate verifier for testing. std::unique_ptr mock_cert_verifier; @@ -200,6 +208,12 @@ struct URLRequestContextConfig { const std::string& accept_language, // User-Agent request header field. const std::string& user_agent, + // Disabled cupher suites. + const std::string& disabled_cipher_suites, + // Min TLS version. + const uint16_t min_ssl_version, + // Max TLS version. + const uint16_t max_ssl_version, // JSON encoded experimental options. const std::string& unparsed_experimental_options, // MockCertVerifier to use for testing purposes. @@ -234,6 +248,12 @@ struct URLRequestContextConfig { const std::string& accept_language, // User-Agent request header field. const std::string& user_agent, + // Disabled cipher suites. + const std::string& disabled_cipher_suites, + // Min TLS version. + const uint16_t min_ssl_version, + // Max TLS version. + const uint16_t max_ssl_version, // Parsed experimental options. base::Value::Dict experimental_options, // MockCertVerifier to use for testing purposes. @@ -302,6 +322,12 @@ struct URLRequestContextConfigBuilder { std::string accept_language = ""; // User-Agent request header field. std::string user_agent = ""; + // Disabled cipher suites. + std::string disabled_cipher_suites = ""; + // Min TLS version. + uint16_t min_ssl_version = net::kDefaultSSLVersionMin; + // Max TLS version. + uint16_t max_ssl_version = net::kDefaultSSLVersionMax; // Experimental options encoded as a string in a JSON format containing // experiments and their corresponding configuration options. The format // is a JSON object with the name of the experiment as the key, and the diff --git a/net/ssl/ssl_config_service_defaults.cc b/net/ssl/ssl_config_service_defaults.cc index 7d137e59662d3e..93fdce1ba95a21 100644 --- a/net/ssl/ssl_config_service_defaults.cc +++ b/net/ssl/ssl_config_service_defaults.cc @@ -9,6 +9,11 @@ namespace net { SSLConfigServiceDefaults::SSLConfigServiceDefaults() = default; SSLConfigServiceDefaults::~SSLConfigServiceDefaults() = default; +SSLConfigServiceDefaults::SSLConfigServiceDefaults(SSLContextConfig default_config): default_config_(default_config) { + // TODO: This is how Envoy implemented it, but it seems like not the ideal solution. Should we make a new SSLConfigService subclass? + // default_config.disabled_cipher_suites = default_config_.disabled_cipher_suites; +} + SSLContextConfig SSLConfigServiceDefaults::GetSSLContextConfig() { return default_config_; } diff --git a/net/ssl/ssl_config_service_defaults.h b/net/ssl/ssl_config_service_defaults.h index 32770a45d4f241..d6c7dde1d1a037 100644 --- a/net/ssl/ssl_config_service_defaults.h +++ b/net/ssl/ssl_config_service_defaults.h @@ -24,6 +24,8 @@ class NET_EXPORT SSLConfigServiceDefaults : public SSLConfigService { ~SSLConfigServiceDefaults() override; + SSLConfigServiceDefaults(SSLContextConfig default_config); + // Returns the default SSL config settings. SSLContextConfig GetSSLContextConfig() override;