-1

I'm trying to open a secure websocket connection from a Xamarin Android application to an IIS server. It works fine and dandy on every device I've ever used except Samsung Tab E. Even other Samsung devices work fine.

I'm using the Websockets.PCL library and the regular code:

var _webSocket = WebSocketFactory.Create();
_webSocket.OnOpened += _webSocket_Opened;
_webSocket.OnError += _webSocket_Error;
_webSocket.Open("wss://server.name.here/path/also/");

In this case the error handler is called with:

[websockets] javax.net.ssl.SSLException
[websockets] javax.net.ssl.SSLException: Error occured in delegated task:javax.net.ssl.SSLException: Unexpected exception

The device has no issues with SSL connections via Chrome or other apps, not to this server or others. It also has no issues connecting via SignalR to the same IIS server from this application.

It does have an issue when another third party library is trying to check license from a separate website and an error is logged:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x803b3b28: Failure in SSL library, usually a protocol error

I don't know which address it's trying to contact so can't check what is happening there. But this also works from other devices.

This leads me to believe the Android in the Tab E (v4.4.4, latest available) has something wrong with its SSL implementation since these two connection attempts through javax.net.ssl are failing. But the unexpected exception isn't giving much information.

How to get around this? I wouldn't mind using the websockets implementation SignalR uses (since it works), but as far as I know it's not really exposed as a general use system ready to use.

Additional info

The server does talk TLS1 nicely and sends the whole certificate path as far as I know it, so that shouldn't be the issue, unless the root isn't known (and I would expect to get the handshake failure if that was the case). Testing with openssl shows:

Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=our.domain.com
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root

No client certificate CA names sent
Server Temp Key: ECDH, P-256, 256 bits

New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit

Unfortunately openssl doesn't support the ´-ssl2` flag anymore. Online tools say that SSL2 is disabled, SSL3, TLS1, TLS1.1 and TLS1.2 are enabled.

I could try the custom SSLSocketFactory route but have to see how it would go through Xamarin and Websockets.PCL.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • Possible duplicate of [SSLHandshakeException on Android 4.4 and lower](http://stackoverflow.com/questions/37222696/sslhandshakeexception-on-android-4-4-and-lower) – SushiHangover Oct 13 '16 at 23:15
  • Most likely not an issue of old Android version since works fine on 4.2 devices also – Sami Kuhmonen Oct 14 '16 at 03:45
  • I would *assume* a few things; the CA certificates are different and you would need to handle the client cert yourself via your own `TrustManager` or you are using a self-signed cert thus a custom TrustManager would solved it. 4.2 is a different ABI release than 4.4, and there are a number of issues with certs under KitKat vs JB or ICS.... Plus that device (Tab-E) is a weird Samsung-KitKat-variant due to performance issues... Does your server support only TLS1.1? TLS1.2?..., etc... – SushiHangover Oct 14 '16 at 05:29
  • The certificate is from Comodo and the server gives the full path with it. I have to make sure what the server supports, it shouldn't be restricted to current best practices even but support also a bit earlier SSL/TLS, but I'll add that when I'm connected to it. It's also just that device, other 4.4s and others from 4.2 to 6.0 work fine, so I'm thinking Samsung messed up. More info in a couple of hours. – Sami Kuhmonen Oct 14 '16 at 05:51
  • Some quick tests you are can do are: openssl s_client -connect google.com:80 -tls1 openssl s_client -connect google.com:80 -tls1 (substitute your FQDN) You can change the `-tls1` with `-ssl3`, `-ssl2`, `-tls2`, etc... You can also confirm that your server is sending the Comodo intermediate cert, etc... – SushiHangover Oct 14 '16 at 06:08
  • @SushiHangover Thanks, I tested but openssl doesn't support ssl2 anymore. Used online tools to check. So everything should be ok regards the server and cert path since it goes through the intermediates all the way to the root and support for TLS1 is enabled. – Sami Kuhmonen Oct 14 '16 at 07:13
  • You can always pull the `cacerts.bks` from the device to verify the roots on a KitKAt device, but have you tried using the device's browser to open a web page hosted on that server? – SushiHangover Oct 14 '16 at 07:26
  • @SushiHangover Yes, Chrome works fine on that site. No issues. No other default browser seems to be installed for some reason so can't test with that. – Sami Kuhmonen Oct 14 '16 at 07:28
  • @SushiHangover Thank you for the help, I found a solution by injecting a newer OpenSSL library which doesn't seem to have this issue. – Sami Kuhmonen Oct 14 '16 at 11:29

1 Answers1

1

I found a solution for my case after searching for SSL issues in Android. Florian Krauthan has written about these things and talks about using the SSLSocketFactory on Android 4.1+ to allow use of TLS1.1 etc.

This led me to another post where he explains how Google Play Services can be used to inject a newer OpenSSL library into the whole application. This method also worked for my issue.

The only thing that needs to be done is to add the following code to the beginning of the main activity's OnCreate() method:

Android.Gms.Security.ProviderInstaller.InstallIfNeeded(this);

After this the application will use Google Play Services' OpenSSL library so all connections work without issues and possible known bugs in the built-in Android OpenSSL library get mitigated since a newer version is used.

Of course this might not be a solution for anyone not already using Google Play Services since it increases the application size tremendously.

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74