introduced custom tls socket factory to make tls1.2 work for http connections

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java | 14 
src/main/java/eu/siacs/conversations/utils/TLSSocketFactory.java     | 69 
2 files changed, 71 insertions(+), 12 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/http/HttpConnectionManager.java 🔗

@@ -24,6 +24,7 @@ import eu.siacs.conversations.services.AbstractConnectionManager;
 import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.utils.CryptoHelper;
 import eu.siacs.conversations.utils.SSLSocketHelper;
+import eu.siacs.conversations.utils.TLSSocketFactory;
 
 public class HttpConnectionManager extends AbstractConnectionManager {
 
@@ -77,18 +78,7 @@ public class HttpConnectionManager extends AbstractConnectionManager {
 							new StrictHostnameVerifier());
 		}
 		try {
-			final SSLContext sc = SSLSocketHelper.getSSLContext();
-			sc.init(null, new X509TrustManager[]{trustManager},
-					mXmppConnectionService.getRNG());
-
-			final SSLSocketFactory sf = sc.getSocketFactory();
-			final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites(
-					sf.getSupportedCipherSuites());
-			if (cipherSuites.length > 0) {
-				sc.getDefaultSSLParameters().setCipherSuites(cipherSuites);
-
-			}
-
+			final SSLSocketFactory sf = new TLSSocketFactory(new X509TrustManager[]{trustManager}, mXmppConnectionService.getRNG());
 			connection.setSSLSocketFactory(sf);
 			connection.setHostnameVerifier(hostnameVerifier);
 		} catch (final KeyManagementException | NoSuchAlgorithmException ignored) {

src/main/java/eu/siacs/conversations/utils/TLSSocketFactory.java 🔗

@@ -0,0 +1,69 @@
+package eu.siacs.conversations.utils;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509TrustManager;
+
+public class TLSSocketFactory extends SSLSocketFactory {
+
+    private final SSLSocketFactory internalSSLSocketFactory;
+
+    public TLSSocketFactory(X509TrustManager[] trustManager, SecureRandom random) throws KeyManagementException, NoSuchAlgorithmException {
+        SSLContext context = SSLContext.getInstance("TLS");
+        context.init(null, trustManager, random);
+        this.internalSSLSocketFactory = context.getSocketFactory();
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites() {
+        return CryptoHelper.getOrderedCipherSuites(internalSSLSocketFactory.getDefaultCipherSuites());
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return internalSSLSocketFactory.getSupportedCipherSuites();
+    }
+
+    @Override
+    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
+        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
+    }
+
+    @Override
+    public Socket createSocket(String host, int port) throws IOException {
+        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
+    }
+
+    @Override
+    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
+        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
+    }
+
+    @Override
+    public Socket createSocket(InetAddress host, int port) throws IOException {
+        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
+    }
+
+    @Override
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
+        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
+    }
+
+    private static Socket enableTLSOnSocket(Socket socket) {
+        if(socket != null && (socket instanceof SSLSocket)) {
+            try {
+                SSLSocketHelper.setSecurity((SSLSocket) socket);
+            } catch (NoSuchAlgorithmException e) {
+                //ignoring
+            }
+        }
+        return socket;
+    }
+}