Our application has tabs and one of the fragments can contain a webviewclient. Users are now reporting an issue where the webviewclient is unable to load the page. We’ve confirmed that the server is up and running, we’ve also identified that the issue happens in v4.3 and all earlier versions. We have also confirmed that it works fine in v5.0; right now we’ve not been able to test whether it works in 4.4 or not (I guess that information only helps if someone knows of a change that occurred in 4.4 and newer that would cause something to fail in all earlier versions).
So the actual problem is we create the webviewclient and load it into the fragment, the web page (Connected to via HTTPS) loads perfectly everytime in this scenario for all versions. For v5.0 we can then click a different tab and come back to the tab with the webviewclient; we can see the fragment being created and everything works as expected, the web page loads as expected. But for v4.3 and earlier we see the fragment being created, but the webviewclient fires onReceivedError with an -11 error code (couldn’t establish a secure connection). Looking further in the debug log we get a handshake error, here is the log for the call. Interestingly the website we are connecting to can accept TLS1.2; we can see that when we go to the URL using Firefox and use dev tools, etc. so that error is pretty interesting too.
04-24 14:38:52.415: W/chromium(15434): external/chromium/net/http/http_stream_factory_impl_job.cc:865: [0424/143852:WARNING:http_stream_factory_impl_job.cc(865)] Falling back to SSLv3 because host is TLS intolerant: 04-24 14:38:52.446: V/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:310: [0424/143852:INFO:ssl_client_socket_openssl.cc(310)] ssl_ctx_ is used 04-24 14:38:52.469: E/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:899: [0424/143852:ERROR:ssl_client_socket_openssl.cc(899)] handshake failed; returned 0, SSL error code 5, net_error -107 04-24 14:38:52.469: V/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:508: [0424/143852:INFO:ssl_client_socket_openssl.cc(508)] ~SSLClientSocketOpenSSL() 04-24 14:38:52.469: I/GATE(15434): <GATE-M>DEV_ACTION_ERROR</GATE-M> 04-24 14:38:52.477: V/webkit(15434): reportError errorCode(-11) desc(Couldn't establish a secure connection.) 04-24 14:38:52.532: I/GATE(15434): <GATE-M>DEV_ACTION_COMPLETED</GATE-M>
Digging around it looks like we might need to override the SSLProtocolFactory; but that seemed to be for self signed certificates, etc. We are connecting to a well know 3rd party and there doesn’t appear to be anything wrong with their certificate. As always with these things, it probably feels like something we’re missing for earlier versions of Android; or a work around for something that has been fixed in newer versions but not really sure where to look next.
This appears to be a bug in Android v4.3 and earlier, which now Google are not maintaining will not be patched. The website we are connecting to is running TLS but has recently switched off SSLv3. It’s a payment provider and PCI compliance is forcing providers to disable both SSLv3 and earlier versions of TLS in the coming year to stay compliant. We’ve also identified that whilst Chrome on that version of Android is able to communicate with the site properly, the native Android browser can not (So duplicates what we see in WebViewClient). Frustratingly this means there does not appear to be a secure solution to this problem. It might be possible to override the SSLProviderFactory but this looks like it is a sledgehammer to crack a nut, opening up other potential security issues.
UPDATE: In the end this was resolved by the 3rd party we were connecting too. There was nothing we could do in the Android side of things, but I think it was a bios update that sorted something on the server which meant it started communicating in a way that Android could handle (we couldn’t get much detail from the 3rd party as to what they did).