From 65f7053c029ee9846b38693bbdc7d7017ceeb39b Mon Sep 17 00:00:00 2001 From: rfc2822 Date: Sat, 29 Mar 2014 17:02:02 +0100 Subject: [PATCH] SNI support for Android <4.2, too (see issue #9) --- README.md | 1 + .../bitfire/davdroid/webdav/TlsSniSocketFactory.java | 12 ++++++++++-- .../davdroid/webdav/test/WebDavResourceTest.java | 10 ++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 91884150..b2a75106 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Please see the [DAVdroid Web site](http://davdroid.bitfire.at). USED THIRD-PARTY LIBRARIES ========================== +* [Apache HttpClient](http://hc.apache.org) ([Apache License](http://www.apache.org/licenses/)) * [iCal4j](http://ical4j.sourceforge.net/) ([New BSD License](http://sourceforge.net/p/ical4j/ical4j/ci/default/tree/LICENSE)) * [ez-vcard](https://code.google.com/p/ez-vcard/) ([New BSD License](http://opensource.org/licenses/BSD-3-Clause)) * [Simple XML Serialization](http://simple.sourceforge.net/) ([Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)) diff --git a/src/at/bitfire/davdroid/webdav/TlsSniSocketFactory.java b/src/at/bitfire/davdroid/webdav/TlsSniSocketFactory.java index ab62d79d..c8c9e98e 100644 --- a/src/at/bitfire/davdroid/webdav/TlsSniSocketFactory.java +++ b/src/at/bitfire/davdroid/webdav/TlsSniSocketFactory.java @@ -56,10 +56,18 @@ public class TlsSniSocketFactory implements LayeredConnectionSocketFactory { // set up SNI before the handshake if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + // Android 4.2+, use documented way to set SNI host name Log.d(TAG, "Setting SNI hostname"); sslSocketFactory.setHostname(ssl, host.getHostName()); - } else - Log.i(TAG, "No SNI support below Android 4.2!"); + } else { + Log.d(TAG, "No documented SNI support on Android <4.2, trying with reflection"); + try { + java.lang.reflect.Method setHostnameMethod = ssl.getClass().getMethod("setHostname", String.class); + setHostnameMethod.invoke(ssl, host.getHostName()); + } catch (Exception e) { + Log.w(TAG, "SNI not useable", e); + } + } // verify hostname and certificate SSLSession session = ssl.getSession(); diff --git a/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java b/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java index 1b13d180..2a994b3c 100644 --- a/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java +++ b/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java @@ -166,20 +166,14 @@ public class WebDavResourceTest extends InstrumentationTestCase { public void testGetHttpsWithSni() throws URISyntaxException, HttpException, IOException, DavException { WebDavResource file = new WebDavResource(httpClient, new URI("https://sni.velox.ch"), false); - boolean sniWorking; + boolean sniWorking = false; try { file.get(); sniWorking = true; } catch (SSLPeerUnverifiedException e) { - sniWorking = false; } - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - // SNI should be available in Android 4.2+ - assertTrue(sniWorking); - } else - Log.i(TAG, "SNI not tested (only available in Android 4.2+)"); - + assertTrue(sniWorking); } public void testMultiGet() throws DavException, IOException, HttpException {