Skip to content

Commit 27ee656

Browse files
author
Gerardo Pacheco
committed
Fix TLS 1.2 support for Android 4.4.x devices
1 parent d8c79f6 commit 27ee656

File tree

2 files changed

+76
-15
lines changed

2 files changed

+76
-15
lines changed

android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
1515
import com.RNFetchBlob.Response.RNFetchBlobFileResp;
16+
import com.RNFetchBlob.Utils.Tls12SocketFactory;
1617
import com.facebook.common.logging.FLog;
1718
import com.facebook.react.bridge.Arguments;
1819
import com.facebook.react.bridge.Callback;
@@ -722,32 +723,23 @@ public void onReceive(Context context, Intent intent) {
722723
public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
723724
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
724725
try {
725-
// Code from https://stackoverflow.com/a/40874952/544779
726-
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
727-
trustManagerFactory.init((KeyStore) null);
728-
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
729-
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
730-
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
731-
}
732-
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
733-
SSLContext sslContext = SSLContext.getInstance("SSL");
734-
sslContext.init(null, new TrustManager[] { trustManager }, null);
735-
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
736-
737-
client.sslSocketFactory(sslSocketFactory, trustManager);
726+
// Code from https://github.com/square/okhttp/issues/2372#issuecomment-244807676
727+
SSLContext sc = SSLContext.getInstance("TLSv1.2");
728+
sc.init(null, null, null);
729+
client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
738730

739731
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
740732
.tlsVersions(TlsVersion.TLS_1_2)
741733
.build();
742734

743-
List< ConnectionSpec > specs = new ArrayList < > ();
735+
List<ConnectionSpec> specs = new ArrayList<>();
744736
specs.add(cs);
745737
specs.add(ConnectionSpec.COMPATIBLE_TLS);
746738
specs.add(ConnectionSpec.CLEARTEXT);
747739

748740
client.connectionSpecs(specs);
749741
} catch (Exception exc) {
750-
FLog.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc);
742+
FLog.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
751743
}
752744
}
753745

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.RNFetchBlob.Utils;
2+
3+
import java.io.IOException;
4+
import java.net.InetAddress;
5+
import java.net.Socket;
6+
import java.net.UnknownHostException;
7+
8+
import javax.net.ssl.SSLSocket;
9+
import javax.net.ssl.SSLSocketFactory;
10+
11+
/**
12+
* Enables TLS v1.2 when creating SSLSockets.
13+
* <p/>
14+
* For some reason, android supports TLS v1.2 from API 16, but enables it by
15+
* default only from API 20.
16+
* @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
17+
* @see SSLSocketFactory
18+
*/
19+
public class Tls12SocketFactory extends SSLSocketFactory {
20+
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
21+
22+
final SSLSocketFactory delegate;
23+
24+
public Tls12SocketFactory(SSLSocketFactory base) {
25+
this.delegate = base;
26+
}
27+
28+
@Override
29+
public String[] getDefaultCipherSuites() {
30+
return delegate.getDefaultCipherSuites();
31+
}
32+
33+
@Override
34+
public String[] getSupportedCipherSuites() {
35+
return delegate.getSupportedCipherSuites();
36+
}
37+
38+
@Override
39+
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
40+
return patch(delegate.createSocket(s, host, port, autoClose));
41+
}
42+
43+
@Override
44+
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
45+
return patch(delegate.createSocket(host, port));
46+
}
47+
48+
@Override
49+
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
50+
return patch(delegate.createSocket(host, port, localHost, localPort));
51+
}
52+
53+
@Override
54+
public Socket createSocket(InetAddress host, int port) throws IOException {
55+
return patch(delegate.createSocket(host, port));
56+
}
57+
58+
@Override
59+
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
60+
return patch(delegate.createSocket(address, port, localAddress, localPort));
61+
}
62+
63+
private Socket patch(Socket s) {
64+
if (s instanceof SSLSocket) {
65+
((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
66+
}
67+
return s;
68+
}
69+
}

0 commit comments

Comments
 (0)