Restrict okhttp to 1.2/1.3

This commit is contained in:
Moxie Marlinspike 2019-03-12 19:43:51 -07:00
parent 28f380ab51
commit a6eb6bbc99
3 changed files with 78 additions and 5 deletions

View File

@ -0,0 +1,69 @@
package org.whispersystems.signalservice.api.util;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
* Enables TLS v1.2 when creating SSLSockets.
* <p/>
* For some reason, android supports TLS v1.2 from API 16, but enables it by
* default only from API 20.
* @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
* @see SSLSocketFactory
*/
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_V13_ONLY = {"TLSv1.3", "TLSv1.2"};
final SSLSocketFactory delegate;
public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_V12_V13_ONLY);
}
return s;
}
}

View File

@ -35,6 +35,7 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import org.whispersystems.signalservice.api.push.exceptions.RateLimitException;
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
import org.whispersystems.signalservice.api.util.CredentialsProvider;
import org.whispersystems.signalservice.api.util.Tls12SocketFactory;
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
import org.whispersystems.signalservice.internal.configuration.SignalUrl;
import org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest;
@ -1044,12 +1045,12 @@ public class PushServiceSocket {
try {
TrustManager[] trustManagers = BlacklistingTrustManager.createFor(url.getTrustStore());
SSLContext context = SSLContext.getInstance("TLS");
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(null, trustManagers, null);
return new OkHttpClient.Builder()
.sslSocketFactory(context.getSocketFactory(), (X509TrustManager)trustManagers[0])
.connectionSpecs(url.getConnectionSpecs().or(Util.immutableList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS)))
.sslSocketFactory(new Tls12SocketFactory(context.getSocketFactory()), (X509TrustManager)trustManagers[0])
.connectionSpecs(url.getConnectionSpecs().or(Util.immutableList(ConnectionSpec.RESTRICTED_TLS)))
.build();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new AssertionError(e);

View File

@ -8,6 +8,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.push.TrustStore;
import org.whispersystems.signalservice.api.util.CredentialsProvider;
import org.whispersystems.signalservice.api.util.SleepTimer;
import org.whispersystems.signalservice.api.util.Tls12SocketFactory;
import org.whispersystems.signalservice.api.websocket.ConnectivityListener;
import org.whispersystems.signalservice.internal.util.BlacklistingTrustManager;
import org.whispersystems.signalservice.internal.util.Util;
@ -30,6 +31,7 @@ import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
@ -97,7 +99,8 @@ public class WebSocketConnection extends WebSocketListener {
Pair<SSLSocketFactory, X509TrustManager> socketFactory = createTlsSocketFactory(trustStore);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.sslSocketFactory(socketFactory.first(), socketFactory.second())
.sslSocketFactory(new Tls12SocketFactory(socketFactory.first()), socketFactory.second())
.connectionSpecs(Util.immutableList(ConnectionSpec.RESTRICTED_TLS))
.readTimeout(KEEPALIVE_TIMEOUT_SECONDS + 10, TimeUnit.SECONDS)
.connectTimeout(KEEPALIVE_TIMEOUT_SECONDS + 10, TimeUnit.SECONDS)
.build();
@ -300,7 +303,7 @@ public class WebSocketConnection extends WebSocketListener {
private Pair<SSLSocketFactory, X509TrustManager> createTlsSocketFactory(TrustStore trustStore) {
try {
SSLContext context = SSLContext.getInstance("TLS");
SSLContext context = SSLContext.getInstance("TLSv1.2");
TrustManager[] trustManagers = BlacklistingTrustManager.createFor(trustStore);
context.init(null, trustManagers, null);