Skip to content
This repository has been archived by the owner on Dec 10, 2023. It is now read-only.

Commit

Permalink
Enable TLS 1.2 on Android 4.1-4.4 (See Issue facebook#7192)
Browse files Browse the repository at this point in the history
Credits to Alex Gotev (@gotev) for the nice implementation.
  • Loading branch information
fkoester committed Sep 7, 2016
1 parent 7a1410a commit 8585872
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@

package com.facebook.react.modules.network;

import android.os.Build;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.Nullable;
import javax.net.ssl.SSLContext;

import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;

/**
* Helper class that provides the same OkHttpClient instance that will be used for all networking
Expand All @@ -39,11 +47,43 @@ public static void replaceOkHttpClient(OkHttpClient client) {

private static OkHttpClient createClient() {
// No timeouts by default
return new OkHttpClient.Builder()
OkHttpClient.Builder client = new OkHttpClient.Builder()
.connectTimeout(0, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer())
.build();
.cookieJar(new ReactCookieJarContainer());

return enableTls12OnPreLollipop(client).build();
}

/*
On Android 4.1-4.4 (API level 16 to 19) TLS 1.1 and 1.2 are
available but not enabled by default. The following method
enables it.
See also https://github.com/facebook/react-native/issues/7192
*/
public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 20) {
try {
client.sslSocketFactory(new TLSSocketFactory());

ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build();

List<ConnectionSpec> specs = new ArrayList<>();
specs.add(cs);
specs.add(ConnectionSpec.COMPATIBLE_TLS);
specs.add(ConnectionSpec.CLEARTEXT);

client.connectionSpecs(specs);
} catch (Exception exc) {
Log.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc);
}
}

return client;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.modules.network;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

/**
*
* This class is needed for TLS 1.2 support on Android 4.x
*
* Source: http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/
*/
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;

public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
delegate = context.getSocketFactory();
}

@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 enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
}

@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(delegate.createSocket(host, port));
}

@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
}

@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(delegate.createSocket(host, port));
}

@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort));
}

private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}

0 comments on commit 8585872

Please sign in to comment.