Skip to content

Commit 80d5a00

Browse files
committed
Set OkHttp protocols to TLSv1.2 and TLSv1.3 only
1 parent b3184e1 commit 80d5a00

File tree

4 files changed

+60
-27
lines changed

4 files changed

+60
-27
lines changed

build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ dependencies {
4343

4444
implementation(libs.commons.text)
4545

46+
implementation(libs.conscrypt.android)
4647
implementation(libs.okhttp)
4748
implementation(libs.netcipher.webkit)
4849
implementation(libs.media3.exoplayer)

gradle/libs.versions.toml

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ androidx-swiperefreshlayout = "1.1.0"
2020
checkstyle = "10.17.0"
2121
commons-lang = "3.17.0"
2222
commons-text = "1.13.0"
23+
conscrypt-android = "2.5.3"
2324
google-flexbox = "3.0.0"
2425
google-material = "1.12.0"
2526
jackson = "2.18.3"
@@ -53,6 +54,7 @@ androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefre
5354

5455
commons-lang = { module = "org.apache.commons:commons-lang3", version.ref = "commons-lang" }
5556
commons-text = { module = "org.apache.commons:commons-text", version.ref = "commons-text" }
57+
conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref = "conscrypt-android" }
5658
google-flexbox = { module = "com.google.android.flexbox:flexbox", version.ref = "google-flexbox" }
5759
google-material = { module = "com.google.android.material:material", version.ref = "google-material" }
5860
jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" }

src/main/java/org/quantumbadger/redreader/http/LegacyTLSSocketFactory.java renamed to src/main/java/org/quantumbadger/redreader/http/InternalSSLSocketFactory.java

+34-27
Original file line numberDiff line numberDiff line change
@@ -17,77 +17,84 @@
1717

1818
package org.quantumbadger.redreader.http;
1919

20-
import androidx.annotation.NonNull;
21-
22-
import javax.net.ssl.SSLSocket;
23-
import javax.net.ssl.SSLSocketFactory;
2420
import java.io.IOException;
2521
import java.net.InetAddress;
2622
import java.net.Socket;
2723

28-
public class LegacyTLSSocketFactory extends SSLSocketFactory {
24+
import javax.net.ssl.SSLSocket;
25+
import javax.net.ssl.SSLSocketFactory;
2926

30-
private static final String[] TLS_V1_2_ONLY = {"TLSv1.2"};
27+
public final class InternalSSLSocketFactory extends SSLSocketFactory {
28+
private static final String[] ENABLED_PROTOCOLS = {"TLSv1.2", "TLSv1.3"};
3129

32-
private final SSLSocketFactory delegate;
30+
private final SSLSocketFactory sslSocketFactory;
3331

34-
public LegacyTLSSocketFactory(@NonNull final SSLSocketFactory base) {
35-
this.delegate = base;
32+
public InternalSSLSocketFactory(final SSLSocketFactory sslSocketFactory) {
33+
this.sslSocketFactory = sslSocketFactory;
3634
}
3735

3836
@Override
3937
public String[] getDefaultCipherSuites() {
40-
return delegate.getDefaultCipherSuites();
38+
return sslSocketFactory.getDefaultCipherSuites();
4139
}
4240

4341
@Override
4442
public String[] getSupportedCipherSuites() {
45-
return delegate.getSupportedCipherSuites();
43+
return sslSocketFactory.getSupportedCipherSuites();
44+
}
45+
46+
@Override
47+
public Socket createSocket() throws IOException {
48+
return enableTLSOnSocket(sslSocketFactory.createSocket());
4649
}
4750

4851
@Override
4952
public Socket createSocket(
50-
final Socket s,
53+
final Socket socket,
5154
final String host,
5255
final int port,
53-
final boolean autoClose) throws IOException {
54-
return enableTLS1_2(delegate.createSocket(s, host, port, autoClose));
56+
final boolean autoClose
57+
) throws IOException {
58+
return enableTLSOnSocket(sslSocketFactory.createSocket(socket, host, port, autoClose));
5559
}
5660

5761
@Override
5862
public Socket createSocket(final String host, final int port) throws IOException {
59-
return enableTLS1_2(delegate.createSocket(host, port));
63+
return enableTLSOnSocket(sslSocketFactory.createSocket(host, port));
6064
}
6165

6266
@Override
6367
public Socket createSocket(
6468
final String host,
6569
final int port,
6670
final InetAddress localHost,
67-
final int localPort) throws IOException {
68-
return enableTLS1_2(delegate.createSocket(host, port, localHost, localPort));
71+
final int localPort
72+
) throws IOException {
73+
return enableTLSOnSocket(sslSocketFactory.createSocket(host, port, localHost, localPort));
6974
}
7075

7176
@Override
72-
public Socket createSocket(
73-
final InetAddress host,
74-
final int port) throws IOException {
75-
return enableTLS1_2(delegate.createSocket(host, port));
77+
public Socket createSocket(final InetAddress host, final int port) throws IOException {
78+
return enableTLSOnSocket(sslSocketFactory.createSocket(host, port));
7679
}
7780

7881
@Override
7982
public Socket createSocket(
8083
final InetAddress address,
8184
final int port,
8285
final InetAddress localAddress,
83-
final int localPort) throws IOException {
84-
return enableTLS1_2(delegate.createSocket(address, port, localAddress, localPort));
86+
final int localPort
87+
) throws IOException {
88+
return enableTLSOnSocket(
89+
sslSocketFactory.createSocket(address, port, localAddress, localPort)
90+
);
8591
}
8692

87-
private Socket enableTLS1_2(final Socket s) {
88-
if (s instanceof SSLSocket) {
89-
((SSLSocket)s).setEnabledProtocols(TLS_V1_2_ONLY);
93+
private Socket enableTLSOnSocket(final Socket socket) {
94+
if (socket instanceof SSLSocket) {
95+
final SSLSocket sslSocket = (SSLSocket) socket;
96+
sslSocket.setEnabledProtocols(ENABLED_PROTOCOLS);
9097
}
91-
return s;
98+
return socket;
9299
}
93100
}

src/main/java/org/quantumbadger/redreader/http/okhttp/OKHTTPBackend.kt

+23
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ import android.util.Log
2222
import okhttp3.CacheControl
2323
import okhttp3.Call
2424
import okhttp3.ConnectionPool
25+
import okhttp3.ConnectionSpec
2526
import okhttp3.Cookie
2627
import okhttp3.CookieJar
2728
import okhttp3.HttpUrl
2829
import okhttp3.MediaType.Companion.toMediaType
2930
import okhttp3.MultipartBody
3031
import okhttp3.OkHttpClient
3132
import okhttp3.RequestBody.Companion.toRequestBody
33+
import org.conscrypt.Conscrypt
3234
import org.quantumbadger.redreader.cache.CacheRequest
3335
import org.quantumbadger.redreader.common.Constants
3436
import org.quantumbadger.redreader.common.General.getGeneralErrorForFailure
@@ -41,23 +43,44 @@ import org.quantumbadger.redreader.common.TorCommon
4143
import org.quantumbadger.redreader.common.UriString
4244
import org.quantumbadger.redreader.http.FailedRequestBody
4345
import org.quantumbadger.redreader.http.HTTPBackend
46+
import org.quantumbadger.redreader.http.InternalSSLSocketFactory
4447
import org.quantumbadger.redreader.http.body.HTTPRequestBody
4548
import org.quantumbadger.redreader.http.body.multipart.Part
4649
import java.io.IOException
4750
import java.io.InputStream
4851
import java.net.InetSocketAddress
4952
import java.net.Proxy
53+
import java.security.Provider
54+
import java.security.Security
5055
import java.util.Locale
5156
import java.util.concurrent.TimeUnit
5257
import java.util.concurrent.atomic.AtomicBoolean
5358
import java.util.concurrent.atomic.AtomicReference
59+
import javax.net.ssl.SSLContext
60+
import javax.net.ssl.TrustManager
5461
import okhttp3.Request as OkHTTPRequest
5562

5663
class OKHTTPBackend private constructor() : HTTPBackend() {
5764
private val mClient: OkHttpClient
5865

5966
init {
67+
// Init Conscrypt
68+
val conscrypt: Provider = Conscrypt.newProvider()
69+
70+
// Add as provider
71+
Security.insertProviderAt(conscrypt, 1)
72+
6073
val builder: OkHttpClient.Builder = OkHttpClient.Builder()
74+
.connectionSpecs(listOf(ConnectionSpec.RESTRICTED_TLS))
75+
76+
try {
77+
val tm = Conscrypt.getDefaultX509TrustManager()
78+
val sslContext: SSLContext = SSLContext.getInstance("TLS", conscrypt)
79+
sslContext.init(null, arrayOf<TrustManager>(tm), null)
80+
builder.sslSocketFactory(InternalSSLSocketFactory(sslContext.socketFactory), tm)
81+
} catch (e: java.lang.Exception) {
82+
e.printStackTrace()
83+
}
6184

6285
// Here we set the over18 cookie if needed, and return it whenever the url contains search
6386
// this is necessary to get the reddit API to return NSFW search results

0 commit comments

Comments
 (0)