Skip to content
This repository was archived by the owner on Mar 6, 2018. It is now read-only.

Java WebSockets and SocketIO SSL seem incompatible on android #60

Open
z4ce opened this issue Jun 30, 2013 · 12 comments
Open

Java WebSockets and SocketIO SSL seem incompatible on android #60

z4ce opened this issue Jun 30, 2013 · 12 comments

Comments

@z4ce
Copy link

z4ce commented Jun 30, 2013

I was getting silent failures whenever using SSL on android. I ended up install the source for this project and the Java WebSockets project and debugged where the exception was occuring. This was the exception causing it to not work

"org.apache.harmony.xnet.provider.jsse.OpenSSLSessionImpl cannot be cast to org.apache.harmony.xnet.provider.jsse.SSLSessionImpl"

It turns out for some reason the SSLContext SSLContext.getDefault works great for socket.io and it can negotiate just fine. But when it calls the parent "transport" it does not work because the parent needs the "HarmonyJSSE" provider and not the OpenSSL provider. I don't have enough knowledge of how android SSL works to really make sense of why this is, but it definitely is the case.

I was able to get the negotiation and transport working by doing the following:

    SocketIO.setDefaultSSLSocketFactory(SSLContext.getDefault());

Then I had to edit the WebsocketTransport as follows:

   public WebsocketTransport(URI uri, IOConnection connection) {
        super(uri);
        this.connection = connection;
        SSLContext context = null;
        try {
            context = SSLContext.getInstance("TLS", "HarmonyJSSE");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } 
        try {
            context.init(null, null, null);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        if("wss".equals(uri.getScheme()) && context != null) {
            this.setWebSocketFactory(new DefaultSSLWebSocketClientFactory(context));
        }
    }

This problem might require some coordination with the upstream library.

@kushdilip
Copy link

Thanks a lot for the solution. I was struggling for weeks because of this issue.

@jarrodrobins
Copy link

Brilliant! Thanks @z4ce, I had the same issue and this appears to have solved it.

@z4ce
Copy link
Author

z4ce commented Sep 27, 2013

An important note this solution: It only works on Android 4.2+ I'm not really sure why. If someone figures this out, let me know, please.

markslemko pushed a commit to Grantoo/socket.io-java-client that referenced this issue Jan 4, 2014
@sambengtson
Copy link

Did we ever figure out a fix for why this wasn't working on anything less than Android 4.2+? I would like to help find a solution to this if possible.

@mbilbao
Copy link

mbilbao commented May 6, 2014

Dude, thank you a lot! It works like a charm!!

@EtienneBruines
Copy link

It worked for me as well. Perhaps this fix for WebsocketTransport.java should be inside the GitHub repo as well? Saves some time downloading / editing the source files.

Thank you! Been working on this for the past six hours.

@solorchid
Copy link

it doesn't work for me, I'm using android 4.4.4. Is there any change in the Android 4.4?

@robertoandrade
Copy link

+1 for 4.4.4.

@robertoandrade
Copy link

I was able to work around it by updating to the latest Java-WebSocket and switching the this.setWebSocketFactory to the new this.setSocket building a new socket from the socket context's factory.

I later found out that this solution is also referenced in #106 and #103.

@jp-at-work
Copy link

I found that updating the Java-WebSocket to the latest and making the modifications suggested in robertoandrade's comment worked for Android 5.0.1+ devices (LG Nexus 5, Asus Nexus 7), but crashed with an NPE on earlier versions of Android (Samsung Galaxy S4 - v4.4.2, Samsung Galaxy Nexus - v4.2.1, Samsung Nexus S - v4.0.4, Samsung GT-I5500 - v2.3.7).

The only workaround that I could find at this time is to replace this.setSocket(context.getSocketFactory().createSocket()); with this.setSocket(SSLSocketFactory.getDefault().createSocket());

@richardleggett
Copy link

Just a small update on this. HarmonyJSSE only looks to be supported up to API level 19, so not Lollipop and above. To confirm, on a Nexus 4 Lollipop:

SSLContext.getInstance("TLS", "HarmonyJSSE"); // returns null

Update: There appear to be another issue with the java-websocket library dependency with API 21 that has possibly been fixed in 1.3. See: TooTallNate/Java-WebSocket#293

@ChandanShankar
Copy link

Hi, I'm new to android, I'm getting the the following error,

06-04 12:13:33.040: W/System.err(17338): SocketIOException: Error while handshaking

at .IOConnection.handshake(IOConnection.java:327)
at .IOConnection.access$7(IOConnection.java:290)
at .IOConnection$ConnectThread.run(IOConnection.java:198)
Caused by: java.lang.NullPointerException
at .IOConnection.handshake(IOConnection.java:307)
... 2 more,

As suggested i'm using socketIO server version 0.9.16, and folk of /Grantoo/socket.io-java-client

The same code is working for http domain, but its not working for https and SSL protocols.

Please help solving this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests