Loading build.gradle +3 −3 Original line number Diff line number Diff line buildscript { ext.kotlin_version = '1.2.21' ext.kotlin_version = '1.2.30' ext.dokka_version = '0.9.15' repositories { Loading Loading @@ -46,8 +46,8 @@ android { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" compile 'com.android.support:appcompat-v7:27.0.2' compile 'com.android.support:cardview-v7:27.0.2' compile 'com.android.support:appcompat-v7:27.1.0' compile 'com.android.support:cardview-v7:27.1.0' androidTestCompile 'com.android.support.test:runner:1.0.1' androidTestCompile 'com.android.support.test:rules:1.0.1' Loading src/androidTest/java/at/bitfire/cert4android/CustomCertManagerTest.javadeleted 100644 → 0 +0 −160 Original line number Diff line number Diff line /* * Copyright © Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.cert4android; import android.content.Intent; import android.os.IBinder; import android.os.Messenger; import android.support.test.rule.ServiceTestRule; import android.support.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import java.net.URL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.concurrent.TimeoutException; import javax.net.ssl.HttpsURLConnection; import static android.support.test.InstrumentationRegistry.getContext; import static android.support.test.InstrumentationRegistry.getTargetContext; import static org.junit.Assert.assertNotNull; @RunWith(AndroidJUnit4.class) public class CustomCertManagerTest { CustomCertManager certManager, paranoidCertManager; static { CustomCertManager.SERVICE_TIMEOUT = 1000; } @Rule public ServiceTestRule serviceTestRule = new ServiceTestRule(); Messenger service; private static X509Certificate[] siteCerts; static { try { siteCerts = getSiteCertificates(new URL("https://www.davdroid.com")); } catch(IOException ignored) { } assertNotNull(siteCerts); } @Before public void initCertManager() throws TimeoutException, InterruptedException { // prepare a bound and ready service for testing // loop required because of https://code.google.com/p/android/issues/detail?id=180396 IBinder binder = bindService(CustomCertService.class); assertNotNull(binder); CustomCertManager.resetCertificates(getContext()); certManager = new CustomCertManager(getContext(), false); assertNotNull(certManager); paranoidCertManager = new CustomCertManager(getContext(), false, false); assertNotNull(paranoidCertManager); } @After public void closeCertManager() { paranoidCertManager.close(); certManager.close(); } @Test(expected = CertificateException.class) public void testCheckClientCertificate() throws CertificateException { certManager.checkClientTrusted(null, null); } @Test public void testTrustedCertificate() throws CertificateException, TimeoutException { certManager.checkServerTrusted(siteCerts, "RSA"); } @Test(expected = CertificateException.class) public void testParanoidCertificate() throws CertificateException { paranoidCertManager.checkServerTrusted(siteCerts, "RSA"); } @Test public void testAddCustomCertificate() throws CertificateException, TimeoutException, InterruptedException { addCustomCertificate(); paranoidCertManager.checkServerTrusted(siteCerts, "RSA"); } // fails randomly for unknown reason: @Test(expected = CertificateException.class) public void testRemoveCustomCertificate() throws CertificateException, TimeoutException, InterruptedException { addCustomCertificate(); // remove certificate and check again // should now be rejected for the whole session, i.e. no timeout anymore Intent intent = new Intent(getContext(), CustomCertService.class); intent.setAction(CustomCertService.CMD_CERTIFICATION_DECISION); intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts[0].getEncoded()); intent.putExtra(CustomCertService.EXTRA_TRUSTED, false); startService(intent, CustomCertService.class); paranoidCertManager.checkServerTrusted(siteCerts, "RSA"); } private void addCustomCertificate() throws CertificateException, TimeoutException, InterruptedException { // add certificate and check again Intent intent = new Intent(getContext(), CustomCertService.class); intent.setAction(CustomCertService.CMD_CERTIFICATION_DECISION); intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts[0].getEncoded()); intent.putExtra(CustomCertService.EXTRA_TRUSTED, true); startService(intent, CustomCertService.class); } private IBinder bindService(Class clazz) throws TimeoutException, InterruptedException { IBinder binder = null; int it = 0; while ((binder = serviceTestRule.bindService(new Intent(getTargetContext(), clazz))) == null && it++ <100) { System.err.println("Waiting for ServiceTestRule.bindService"); Thread.sleep(50); } if (binder == null) throw new IllegalStateException("Couldn't bind to service"); return binder; } private void startService(Intent intent, Class clazz) throws TimeoutException, InterruptedException { serviceTestRule.startService(intent); bindService(clazz); } private static X509Certificate[] getSiteCertificates(URL url) throws IOException { HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); try { conn.getInputStream().read(); Certificate[] certs = conn.getServerCertificates(); X509Certificate[] x509 = new X509Certificate[certs.length]; System.arraycopy(certs, 0, x509, 0, certs.length); return x509; } finally { conn.disconnect(); } } } src/androidTest/java/at/bitfire/cert4android/CustomCertManagerTest.kt 0 → 100644 +153 −0 Original line number Diff line number Diff line /* * Copyright © Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.cert4android import android.app.Service import android.content.Intent import android.os.IBinder import android.support.test.InstrumentationRegistry.getContext import android.support.test.InstrumentationRegistry.getTargetContext import android.support.test.rule.ServiceTestRule import org.junit.After import org.junit.Assert.assertNotNull import org.junit.Assume.assumeNotNull import org.junit.Before import org.junit.Rule import org.junit.Test import java.io.IOException import java.net.URL import java.security.cert.CertificateException import java.security.cert.X509Certificate import javax.net.ssl.HttpsURLConnection class CustomCertManagerTest { companion object { private fun getSiteCertificates(url: URL): List<X509Certificate> { val conn = url.openConnection() as HttpsURLConnection try { conn.inputStream.read() val certs = mutableListOf<X509Certificate>() conn.serverCertificates.forEach { certs += it as X509Certificate } return certs } finally { conn.disconnect() } } } lateinit var certManager: CustomCertManager lateinit var paranoidCertManager: CustomCertManager init { CustomCertManager.SERVICE_TIMEOUT = 1000 } @JvmField @Rule val serviceTestRule = ServiceTestRule() var siteCerts: List<X509Certificate>? = null init { try { siteCerts = getSiteCertificates(URL("https://www.davdroid.com")) } catch(e: IOException) { } assumeNotNull(siteCerts) } @Before fun initCertManager() { // prepare a bound and ready service for testing // loop required because of https://code.google.com/p/android/issues/detail?id=180396 val binder = bindService(CustomCertService::class.java) assertNotNull(binder) CustomCertManager.resetCertificates(getContext()) certManager = CustomCertManager(getContext(), false) assertNotNull(certManager) paranoidCertManager = CustomCertManager(getContext(), false, false) assertNotNull(paranoidCertManager) } @After fun closeCertManager() { paranoidCertManager.close() certManager.close() } @Test(expected = CertificateException::class) fun testCheckClientCertificate() { certManager.checkClientTrusted(null, null) } @Test fun testTrustedCertificate() { certManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } @Test(expected = CertificateException::class) fun testParanoidCertificate() { paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } @Test fun testAddCustomCertificate() { addCustomCertificate() paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } // fails randomly for unknown reason: @Test(expected = CertificateException::class) fun testRemoveCustomCertificate() { addCustomCertificate() // remove certificate and check again // should now be rejected for the whole session, i.e. no timeout anymore val intent = Intent(getContext(), CustomCertService::class.java) intent.action = CustomCertService.CMD_CERTIFICATION_DECISION intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts!!.first().encoded) intent.putExtra(CustomCertService.EXTRA_TRUSTED, false) startService(intent, CustomCertService::class.java) paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } private fun addCustomCertificate() { // add certificate and check again val intent = Intent(getContext(), CustomCertService::class.java) intent.action = CustomCertService.CMD_CERTIFICATION_DECISION intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts!!.first().encoded) intent.putExtra(CustomCertService.EXTRA_TRUSTED, true) startService(intent, CustomCertService::class.java) } private fun bindService(clazz: Class<out Service>): IBinder { var binder = serviceTestRule.bindService(Intent(getTargetContext(), clazz)) var it = 0 while (binder == null && it++ <100) { binder = serviceTestRule.bindService(Intent(getTargetContext(), clazz)) System.err.println("Waiting for ServiceTestRule.bindService") Thread.sleep(50) } if (binder == null) throw IllegalStateException("Couldn't bind to service") return binder } private fun startService(intent: Intent, clazz: Class<out Service>) { serviceTestRule.startService(intent) bindService(clazz) } } src/main/java/at/bitfire/cert4android/CertUtils.kt +0 −2 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ import javax.net.ssl.X509TrustManager object CertUtils { @JvmStatic fun getTrustManager(keyStore: KeyStore?): X509TrustManager? { try { val tmf = TrustManagerFactory.getInstance("X509") Loading @@ -31,7 +30,6 @@ object CertUtils { return null } @JvmStatic fun getTag(cert: X509Certificate): String { val str = StringBuilder() for (b in cert.signature) Loading src/main/java/at/bitfire/cert4android/Constants.kt +2 −4 Original line number Diff line number Diff line Loading @@ -14,9 +14,8 @@ import java.util.logging.Logger object Constants { val TAG = "cert4android" const val TAG = "cert4android" @JvmField var log: Logger = Logger.getLogger(TAG) init { log.level = if (Log.isLoggable(TAG, Log.VERBOSE)) Loading @@ -25,7 +24,6 @@ object Constants { Level.INFO } @JvmField val NOTIFICATION_CERT_DECISION = 88809 const val NOTIFICATION_CERT_DECISION = 88809 } Loading
build.gradle +3 −3 Original line number Diff line number Diff line buildscript { ext.kotlin_version = '1.2.21' ext.kotlin_version = '1.2.30' ext.dokka_version = '0.9.15' repositories { Loading Loading @@ -46,8 +46,8 @@ android { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" compile 'com.android.support:appcompat-v7:27.0.2' compile 'com.android.support:cardview-v7:27.0.2' compile 'com.android.support:appcompat-v7:27.1.0' compile 'com.android.support:cardview-v7:27.1.0' androidTestCompile 'com.android.support.test:runner:1.0.1' androidTestCompile 'com.android.support.test:rules:1.0.1' Loading
src/androidTest/java/at/bitfire/cert4android/CustomCertManagerTest.javadeleted 100644 → 0 +0 −160 Original line number Diff line number Diff line /* * Copyright © Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.cert4android; import android.content.Intent; import android.os.IBinder; import android.os.Messenger; import android.support.test.rule.ServiceTestRule; import android.support.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import java.net.URL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.concurrent.TimeoutException; import javax.net.ssl.HttpsURLConnection; import static android.support.test.InstrumentationRegistry.getContext; import static android.support.test.InstrumentationRegistry.getTargetContext; import static org.junit.Assert.assertNotNull; @RunWith(AndroidJUnit4.class) public class CustomCertManagerTest { CustomCertManager certManager, paranoidCertManager; static { CustomCertManager.SERVICE_TIMEOUT = 1000; } @Rule public ServiceTestRule serviceTestRule = new ServiceTestRule(); Messenger service; private static X509Certificate[] siteCerts; static { try { siteCerts = getSiteCertificates(new URL("https://www.davdroid.com")); } catch(IOException ignored) { } assertNotNull(siteCerts); } @Before public void initCertManager() throws TimeoutException, InterruptedException { // prepare a bound and ready service for testing // loop required because of https://code.google.com/p/android/issues/detail?id=180396 IBinder binder = bindService(CustomCertService.class); assertNotNull(binder); CustomCertManager.resetCertificates(getContext()); certManager = new CustomCertManager(getContext(), false); assertNotNull(certManager); paranoidCertManager = new CustomCertManager(getContext(), false, false); assertNotNull(paranoidCertManager); } @After public void closeCertManager() { paranoidCertManager.close(); certManager.close(); } @Test(expected = CertificateException.class) public void testCheckClientCertificate() throws CertificateException { certManager.checkClientTrusted(null, null); } @Test public void testTrustedCertificate() throws CertificateException, TimeoutException { certManager.checkServerTrusted(siteCerts, "RSA"); } @Test(expected = CertificateException.class) public void testParanoidCertificate() throws CertificateException { paranoidCertManager.checkServerTrusted(siteCerts, "RSA"); } @Test public void testAddCustomCertificate() throws CertificateException, TimeoutException, InterruptedException { addCustomCertificate(); paranoidCertManager.checkServerTrusted(siteCerts, "RSA"); } // fails randomly for unknown reason: @Test(expected = CertificateException.class) public void testRemoveCustomCertificate() throws CertificateException, TimeoutException, InterruptedException { addCustomCertificate(); // remove certificate and check again // should now be rejected for the whole session, i.e. no timeout anymore Intent intent = new Intent(getContext(), CustomCertService.class); intent.setAction(CustomCertService.CMD_CERTIFICATION_DECISION); intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts[0].getEncoded()); intent.putExtra(CustomCertService.EXTRA_TRUSTED, false); startService(intent, CustomCertService.class); paranoidCertManager.checkServerTrusted(siteCerts, "RSA"); } private void addCustomCertificate() throws CertificateException, TimeoutException, InterruptedException { // add certificate and check again Intent intent = new Intent(getContext(), CustomCertService.class); intent.setAction(CustomCertService.CMD_CERTIFICATION_DECISION); intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts[0].getEncoded()); intent.putExtra(CustomCertService.EXTRA_TRUSTED, true); startService(intent, CustomCertService.class); } private IBinder bindService(Class clazz) throws TimeoutException, InterruptedException { IBinder binder = null; int it = 0; while ((binder = serviceTestRule.bindService(new Intent(getTargetContext(), clazz))) == null && it++ <100) { System.err.println("Waiting for ServiceTestRule.bindService"); Thread.sleep(50); } if (binder == null) throw new IllegalStateException("Couldn't bind to service"); return binder; } private void startService(Intent intent, Class clazz) throws TimeoutException, InterruptedException { serviceTestRule.startService(intent); bindService(clazz); } private static X509Certificate[] getSiteCertificates(URL url) throws IOException { HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); try { conn.getInputStream().read(); Certificate[] certs = conn.getServerCertificates(); X509Certificate[] x509 = new X509Certificate[certs.length]; System.arraycopy(certs, 0, x509, 0, certs.length); return x509; } finally { conn.disconnect(); } } }
src/androidTest/java/at/bitfire/cert4android/CustomCertManagerTest.kt 0 → 100644 +153 −0 Original line number Diff line number Diff line /* * Copyright © Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.cert4android import android.app.Service import android.content.Intent import android.os.IBinder import android.support.test.InstrumentationRegistry.getContext import android.support.test.InstrumentationRegistry.getTargetContext import android.support.test.rule.ServiceTestRule import org.junit.After import org.junit.Assert.assertNotNull import org.junit.Assume.assumeNotNull import org.junit.Before import org.junit.Rule import org.junit.Test import java.io.IOException import java.net.URL import java.security.cert.CertificateException import java.security.cert.X509Certificate import javax.net.ssl.HttpsURLConnection class CustomCertManagerTest { companion object { private fun getSiteCertificates(url: URL): List<X509Certificate> { val conn = url.openConnection() as HttpsURLConnection try { conn.inputStream.read() val certs = mutableListOf<X509Certificate>() conn.serverCertificates.forEach { certs += it as X509Certificate } return certs } finally { conn.disconnect() } } } lateinit var certManager: CustomCertManager lateinit var paranoidCertManager: CustomCertManager init { CustomCertManager.SERVICE_TIMEOUT = 1000 } @JvmField @Rule val serviceTestRule = ServiceTestRule() var siteCerts: List<X509Certificate>? = null init { try { siteCerts = getSiteCertificates(URL("https://www.davdroid.com")) } catch(e: IOException) { } assumeNotNull(siteCerts) } @Before fun initCertManager() { // prepare a bound and ready service for testing // loop required because of https://code.google.com/p/android/issues/detail?id=180396 val binder = bindService(CustomCertService::class.java) assertNotNull(binder) CustomCertManager.resetCertificates(getContext()) certManager = CustomCertManager(getContext(), false) assertNotNull(certManager) paranoidCertManager = CustomCertManager(getContext(), false, false) assertNotNull(paranoidCertManager) } @After fun closeCertManager() { paranoidCertManager.close() certManager.close() } @Test(expected = CertificateException::class) fun testCheckClientCertificate() { certManager.checkClientTrusted(null, null) } @Test fun testTrustedCertificate() { certManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } @Test(expected = CertificateException::class) fun testParanoidCertificate() { paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } @Test fun testAddCustomCertificate() { addCustomCertificate() paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } // fails randomly for unknown reason: @Test(expected = CertificateException::class) fun testRemoveCustomCertificate() { addCustomCertificate() // remove certificate and check again // should now be rejected for the whole session, i.e. no timeout anymore val intent = Intent(getContext(), CustomCertService::class.java) intent.action = CustomCertService.CMD_CERTIFICATION_DECISION intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts!!.first().encoded) intent.putExtra(CustomCertService.EXTRA_TRUSTED, false) startService(intent, CustomCertService::class.java) paranoidCertManager.checkServerTrusted(siteCerts!!.toTypedArray(), "RSA") } private fun addCustomCertificate() { // add certificate and check again val intent = Intent(getContext(), CustomCertService::class.java) intent.action = CustomCertService.CMD_CERTIFICATION_DECISION intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, siteCerts!!.first().encoded) intent.putExtra(CustomCertService.EXTRA_TRUSTED, true) startService(intent, CustomCertService::class.java) } private fun bindService(clazz: Class<out Service>): IBinder { var binder = serviceTestRule.bindService(Intent(getTargetContext(), clazz)) var it = 0 while (binder == null && it++ <100) { binder = serviceTestRule.bindService(Intent(getTargetContext(), clazz)) System.err.println("Waiting for ServiceTestRule.bindService") Thread.sleep(50) } if (binder == null) throw IllegalStateException("Couldn't bind to service") return binder } private fun startService(intent: Intent, clazz: Class<out Service>) { serviceTestRule.startService(intent) bindService(clazz) } }
src/main/java/at/bitfire/cert4android/CertUtils.kt +0 −2 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ import javax.net.ssl.X509TrustManager object CertUtils { @JvmStatic fun getTrustManager(keyStore: KeyStore?): X509TrustManager? { try { val tmf = TrustManagerFactory.getInstance("X509") Loading @@ -31,7 +30,6 @@ object CertUtils { return null } @JvmStatic fun getTag(cert: X509Certificate): String { val str = StringBuilder() for (b in cert.signature) Loading
src/main/java/at/bitfire/cert4android/Constants.kt +2 −4 Original line number Diff line number Diff line Loading @@ -14,9 +14,8 @@ import java.util.logging.Logger object Constants { val TAG = "cert4android" const val TAG = "cert4android" @JvmField var log: Logger = Logger.getLogger(TAG) init { log.level = if (Log.isLoggable(TAG, Log.VERBOSE)) Loading @@ -25,7 +24,6 @@ object Constants { Level.INFO } @JvmField val NOTIFICATION_CERT_DECISION = 88809 const val NOTIFICATION_CERT_DECISION = 88809 }