1

I'm using Kuzzle with his Android SDK (3.0.10) to receive notifications with the pub/sub system.

In Android 5 and 6, when I try to connect to the server an error callback is executed with the message: {"message":"SSL handshake aborted: ssl=0x7f382c540280: I/O error during system call, Connection reset by peer"}

In other versions of Android it works perfectly.

                Options options = new Options();
                options.setPort(443);
                options.setOfflineMode(Mode.AUTO);
                options.setSsl(true);
                kuzzle = new Kuzzle(kuzzleHost, options, new ResponseListener<Void>() {
                    @Override
                    public void onSuccess(Void response) {
                        initSubscriptions();
                    }

                    @Override
                    public void onError(JSONObject error) {
                        Log.e("Kuzzle", "error");
                    }
                });

            } catch (Exception e) {
                Utils.caughtException(KuzzleSub.class.getSimpleName(), e);
            }

app/build.gradle dependencies

dependencies {
implementation 'io.kuzzle:sdk-android:3.0.10'
implementation 'tech.gusavila92:java-android-websocket-client:1.2.2'

Debbuging Kuzzle and gusavila92.websocketclient.WebSocketClient classes I have found that in Android 5, the websocket enabled protocols are SSLv3, TLSv1, TLSv1.1, TLSv1.2. However, in Android 7 and greater versions SSLv3 is not enabled.

Searching on the Internet, I have found multiple solutions, like disable SSLv3, enable TLSv1.2 only, create a new SSLFactory. The code below is my attempt to use another SSLFactory creating a class that extends Kuzzle.java and SSLFactory.java

public class ExtendedKuzzle extends Kuzzle {

    public ExtendedKuzzle(@NonNull String host, Options options, ResponseListener<Void> connectionCallback) throws URISyntaxException {
        super(host, options, connectionCallback);
    }

    public ExtendedKuzzle(@NonNull String host) throws URISyntaxException {
        super(host);
    }

    public ExtendedKuzzle(@NonNull String host, ResponseListener<Void> cb) throws URISyntaxException {
        super(host, cb);
    }

    public ExtendedKuzzle(@NonNull String host, Options options) throws URISyntaxException {
        super(host, options);
    }

    @Override
    protected WebSocketClient createSocket() throws URISyntaxException {
        WebSocketClient webSocketClient = super.createSocket();
        try {
//            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
//            sslContext.init(null, null, null);
            webSocketClient.setSSLSocketFactory(new TLSSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return webSocketClient;
    }
}
public class TLSSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory internalSSLSocketFactory;

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

    @Override
    public String[] getDefaultCipherSuites() {
        return internalSSLSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return internalSSLSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket() throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
    }

    @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, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        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 Socket enableTLSOnSocket(Socket socket) {
        if(socket != null && (socket instanceof SSLSocket)) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
//            List<String> enabledProtocols = new ArrayList<>(Arrays.asList(((SSLSocket)socket).getEnabledProtocols()));
//            if (enabledProtocols.size() > 1) {
//                enabledProtocols.remove("SSLv3");
//                ((SSLSocket)socket).setEnabledProtocols(enabledProtocols.toArray(new String[0]));
//            }
        }
        return socket;
    }
}

I have also tried to set an "unquestioning" TrustManager without success either:

    public static SSLSocketFactory createSslSocketFactory() throws Exception {
        TrustManager[] byPassTrustManagers = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
            public void checkClientTrusted(X509Certificate[] chain, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] chain, String authType) {
            }
        } };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, byPassTrustManagers, new java.security.SecureRandom());
        return sslContext.getSocketFactory();
    }

If anyone knows what is happening, I would appreciate it very much. Thanks a lot!

0 Answers0