Skip to content

Commit be6a5c4

Browse files
Myk Syrmyksyr-tdy
authored andcommitted
okhttp: enable TLS 1.3 on Android, retain TLS 1.2-only for desktop JVM
The ConnectionSpec used by OkHttpChannelBuilder had TLS 1.3 explicitly disabled since Dec 2020 due to a Conscrypt/SunJSSE incompatibility. However, this incompatibility does not affect Android. The previous code applied the TLS 1.2-only restriction unconditionally to all platforms. Regulatory impact: TLS 1.2 is classified as a legacy mechanism in ENISA Agreed Cryptographic Mechanisms v2.0 (April 2025), with TLS 1.3 listed as the recommended protocol. This limitation has been forcing all downstream components using grpc-okhttp on Android to operate with a legacy protocol, creating compliance friction with the EU Radio Equipment Directive (RED) and EU Cyber Resilience Act (CRA) certification requirements. Fixes: #7431 (Android only) Fixes: #7765 (Android only)
1 parent 13b4b97 commit be6a5c4

2 files changed

Lines changed: 30 additions & 13 deletions

File tree

okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,26 @@ private enum NegotiationType {
116116
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
117117
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
118118
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
119-
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
120-
121-
// TLS 1.3 does not work so far. See issues:
122-
// https://github.com/grpc/grpc-java/issues/7765
123-
//
124-
// TLS 1.3
125-
//CipherSuite.TLS_AES_128_GCM_SHA256,
126-
//CipherSuite.TLS_AES_256_GCM_SHA384,
127-
//CipherSuite.TLS_CHACHA20_POLY1305_SHA256
128-
)
129-
.tlsVersions(/*TlsVersion.TLS_1_3,*/ TlsVersion.TLS_1_2)
119+
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
120+
CipherSuite.TLS_AES_128_GCM_SHA256,
121+
CipherSuite.TLS_AES_256_GCM_SHA384,
122+
CipherSuite.TLS_CHACHA20_POLY1305_SHA256)
123+
.tlsVersions(TlsVersion.TLS_1_3, TlsVersion.TLS_1_2)
124+
.supportsTlsExtensions(true)
125+
.build();
126+
127+
// @VisibleForTesting
128+
static final ConnectionSpec INTERNAL_LEGACY_CONNECTION_SPEC =
129+
new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
130+
.cipherSuites(
131+
// The following items should be sync with Netty's Http2SecurityUtil.CIPHERS.
132+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
133+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
134+
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
135+
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
136+
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
137+
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
138+
.tlsVersions(TlsVersion.TLS_1_2)
130139
.supportsTlsExtensions(true)
131140
.build();
132141

@@ -184,7 +193,7 @@ public static OkHttpChannelBuilder forTarget(String target, ChannelCredentials c
184193
private SSLSocketFactory sslSocketFactory;
185194
private final boolean freezeSecurityConfiguration;
186195
private HostnameVerifier hostnameVerifier;
187-
private ConnectionSpec connectionSpec = INTERNAL_DEFAULT_CONNECTION_SPEC;
196+
private ConnectionSpec connectionSpec;
188197
private NegotiationType negotiationType = NegotiationType.TLS;
189198
private long keepAliveTimeNanos = KEEPALIVE_TIME_NANOS_DISABLED;
190199
private long keepAliveTimeoutNanos = DEFAULT_KEEPALIVE_TIMEOUT_NANOS;
@@ -199,6 +208,12 @@ public static OkHttpChannelBuilder forTarget(String target, ChannelCredentials c
199208
*/
200209
private final boolean useGetForSafeMethods = false;
201210

211+
private static ConnectionSpec initialConnectionSpec() {
212+
return (OkHttpProtocolNegotiator.get() instanceof OkHttpProtocolNegotiator.AndroidNegotiator)
213+
? INTERNAL_DEFAULT_CONNECTION_SPEC
214+
: INTERNAL_LEGACY_CONNECTION_SPEC;
215+
}
216+
202217
private OkHttpChannelBuilder(String host, int port) {
203218
this(GrpcUtil.authorityFromHostAndPort(host, port));
204219
}
@@ -209,6 +224,7 @@ private OkHttpChannelBuilder(String target) {
209224
new OkHttpChannelDefaultPortProvider());
210225
this.freezeSecurityConfiguration = false;
211226
this.channelCredentials = null;
227+
this.connectionSpec = initialConnectionSpec();
212228
}
213229

214230
OkHttpChannelBuilder(
@@ -222,6 +238,7 @@ private OkHttpChannelBuilder(String target) {
222238
this.negotiationType = factory == null ? NegotiationType.PLAINTEXT : NegotiationType.TLS;
223239
this.freezeSecurityConfiguration = true;
224240
this.channelCredentials = channelCreds;
241+
this.connectionSpec = initialConnectionSpec();
225242
}
226243

227244
private final class OkHttpChannelTransportFactoryBuilder

okhttp/src/main/java/io/grpc/okhttp/SslSocketFactoryServerCredentials.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static final class ServerCredentials extends io.grpc.ServerCredentials {
4141
private final ConnectionSpec connectionSpec;
4242

4343
ServerCredentials(SSLSocketFactory factory) {
44-
this(factory, OkHttpChannelBuilder.INTERNAL_DEFAULT_CONNECTION_SPEC);
44+
this(factory, OkHttpChannelBuilder.INTERNAL_LEGACY_CONNECTION_SPEC);
4545
}
4646

4747
ServerCredentials(SSLSocketFactory factory, ConnectionSpec connectionSpec) {

0 commit comments

Comments
 (0)