Loading src/main/java/at/bitfire/cert4android/CertUtils.kt +4 −4 Original line number Diff line number Diff line Loading @@ -22,13 +22,13 @@ object CertUtils { try { val tmf = TrustManagerFactory.getInstance("X509") tmf.init(keyStore) for (trustManager in tmf.trustManagers) if (trustManager is X509TrustManager) return trustManager tmf.trustManagers .filterIsInstance<X509TrustManager>() .forEach { return it } } catch(e: GeneralSecurityException) { Constants.log.log(Level.SEVERE, "Couldn't initialize trust manager", e) } return null; return null } @JvmStatic Loading src/main/java/at/bitfire/cert4android/CustomCertManager.kt +16 −19 Original line number Diff line number Diff line Loading @@ -58,15 +58,15 @@ class CustomCertManager: X509TrustManager, Closeable { private class MessageHandler: Handler.Callback { override fun handleMessage(msg: Message): Boolean { Constants.log.fine("Received reply from CustomCertificateService: " + msg) when (msg.what) { return when (msg.what) { MSG_CERTIFICATE_DECISION -> synchronized(decisionLock) { decisions.put(msg.arg1, msg.arg2 != 0) decisionLock.notifyAll() return true true } else -> return false false } } } Loading Loading @@ -124,12 +124,10 @@ class CustomCertManager: X509TrustManager, Closeable { * @param context used to bind to {@link CustomCertService} * @param trustSystemCerts whether to trust system/user-installed CAs (default trust store) */ constructor(context: Context, trustSystemCerts: Boolean) : this(context, trustSystemCerts, null) constructor(context: Context, trustSystemCerts: Boolean): this(context, trustSystemCerts, null) override fun close() { if (serviceConnection != null) context.unbindService(serviceConnection) serviceConnection?.let(context::unbindService) } Loading @@ -151,15 +149,17 @@ class CustomCertManager: X509TrustManager, Closeable { override fun checkServerTrusted(chain: Array<X509Certificate>, authType : String) { var trusted = false if (systemTrustManager != null) systemTrustManager?.let { try { systemTrustManager.checkServerTrusted(chain, authType) it.checkServerTrusted(chain, authType) trusted = true } catch(ignored: CertificateException) { Constants.log.fine("Certificate not trusted by system") } } if (!trusted) // not trusted by system, let's check ourselves checkCustomTrusted(chain[0]) } Loading Loading @@ -193,8 +193,7 @@ class CustomCertManager: X509TrustManager, Closeable { decisionLock.wait(SERVICE_TIMEOUT) } catch(e: InterruptedException) { } val decision = decisions.get(id) if (decision != null) { decisions.get(id)?.let { decision -> decisions.delete(id) if (decision) // certificate trusted Loading @@ -205,7 +204,7 @@ class CustomCertManager: X509TrustManager, Closeable { } } // timeout occurred // timeout occurred, send cancellation msg = Message.obtain() msg.what = CustomCertService.MSG_CHECK_TRUSTED_ABORT msg.arg1 = id Loading @@ -231,9 +230,7 @@ class CustomCertManager: X509TrustManager, Closeable { // custom methods fun hostnameVerifier(defaultVerifier: HostnameVerifier?) : HostnameVerifier { return CustomHostnameVerifier(defaultVerifier) } fun hostnameVerifier(defaultVerifier: HostnameVerifier?) = CustomHostnameVerifier(defaultVerifier) fun resetCertificates() { val intent = Intent(context, CustomCertService::class.java) Loading @@ -244,7 +241,7 @@ class CustomCertManager: X509TrustManager, Closeable { // hostname verifier private inner class CustomHostnameVerifier( inner class CustomHostnameVerifier( val defaultVerifier: HostnameVerifier? ): HostnameVerifier { Loading src/main/java/at/bitfire/cert4android/CustomCertService.kt +14 −22 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ class CustomCertService: Service() { var keyStoreFile: File? = null val trustedKeyStore: KeyStore = KeyStore.getInstance(KeyStore.getDefaultType()) val trustedKeyStore = KeyStore.getInstance(KeyStore.getDefaultType())!! var customTrustManager: X509TrustManager? = null var untrustedCerts = HashSet<X509Certificate>() Loading @@ -66,9 +66,7 @@ class CustomCertService: Service() { // initialize trustedKeyStore keyStoreFile = File(getDir(KEYSTORE_DIR, Context.MODE_PRIVATE), KEYSTORE_NAME) try { FileInputStream(keyStoreFile).use { input -> trustedKeyStore.load(input, null) } FileInputStream(keyStoreFile).use { trustedKeyStore.load(it, null) } } catch(e: Exception) { Constants.log.log(Level.SEVERE, "Couldn't initialize key store, creating in-memory key store", e) try { Loading @@ -82,13 +80,12 @@ class CustomCertService: Service() { customTrustManager = CertUtils.getTrustManager(trustedKeyStore) } private fun inTrustStore(cert: X509Certificate): Boolean { private fun inTrustStore(cert: X509Certificate) = try { return trustedKeyStore.getCertificateAlias(cert) != null trustedKeyStore.getCertificateAlias(cert) != null } catch(e: KeyStoreException) { Constants.log.log(Level.WARNING, "Couldn't query custom key store", e) return false } false } Loading Loading @@ -127,16 +124,15 @@ class CustomCertService: Service() { try { trustedKeyStore.setCertificateEntry(cert.subjectDN.name, cert) saveKeyStore() } catch(e: KeyStoreException) { Constants.log.log(Level.SEVERE, "Couldn't add certificate into key store", e) } saveKeyStore() } else untrustedCerts.add(cert) // notify receivers which are waiting for a decision val receivers = pendingDecisions[cert] if (receivers != null) { pendingDecisions[cert]?.let { receivers -> for ((messenger, id) in receivers) { val message = Message.obtain() message.what = CustomCertManager.MSG_CERTIFICATE_DECISION Loading @@ -153,11 +149,9 @@ class CustomCertService: Service() { } private fun saveKeyStore() { Constants.log.fine("Saving custom certificate key store to " + keyStoreFile) Constants.log.fine("Saving custom certificate key store to $keyStoreFile") try { FileOutputStream(keyStoreFile).use { output -> trustedKeyStore.store(output, null) } FileOutputStream(keyStoreFile).use { trustedKeyStore.store(it, null) } } catch(e: Exception) { Constants.log.log(Level.SEVERE, "Couldn't save custom certificate key store", e) } Loading @@ -167,10 +161,7 @@ class CustomCertService: Service() { // bound service; Messenger for IPC val messenger = Messenger(MessageHandler(this)) override fun onBind(intent: Intent?): IBinder { return messenger.binder } override fun onBind(intent: Intent?) = messenger.binder!! private class MessageHandler( service: CustomCertService Loading @@ -184,7 +175,7 @@ class CustomCertService: Service() { return } Constants.log.info("Handling request: " + msg) Constants.log.info("Handling request: $msg") val id = msg.arg1 val data = msg.data Loading @@ -194,8 +185,7 @@ class CustomCertService: Service() { when (msg.what) { MSG_CHECK_TRUSTED -> { val reply = service.pendingDecisions[cert] if (reply != null) { service.pendingDecisions[cert]?.let { reply -> // there's already a pending decision for this certificate, just add this reply messenger reply.add(replyInfo) return Loading Loading @@ -281,6 +271,8 @@ class CustomCertService: Service() { val id: Int ) { override fun hashCode() = messenger.hashCode() xor id override fun equals(other: Any?): Boolean { return if (other is ReplyInfo) { other.messenger == messenger && other.id == id Loading src/main/java/at/bitfire/cert4android/TrustCertificateActivity.kt +6 −5 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ package at.bitfire.cert4android import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.text.TextUtils import android.view.View import android.widget.Button import android.widget.CheckBox Loading Loading @@ -97,9 +96,11 @@ class TrustCertificateActivity: AppCompatActivity() { private fun sendDecision(trusted: Boolean) { val intent = Intent(this, CustomCertService::class.java) intent.action = CustomCertService.CMD_CERTIFICATION_DECISION intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, getIntent().getSerializableExtra(EXTRA_CERTIFICATE)) intent.putExtra(CustomCertService.EXTRA_TRUSTED, trusted) with(intent) { action = CustomCertService.CMD_CERTIFICATION_DECISION putExtra(CustomCertService.EXTRA_CERTIFICATE, getIntent().getSerializableExtra(EXTRA_CERTIFICATE)) putExtra(CustomCertService.EXTRA_TRUSTED, trusted) } startService(intent) } Loading @@ -115,7 +116,7 @@ class TrustCertificateActivity: AppCompatActivity() { private fun hexString(data: ByteArray): String { val str = data.mapTo(LinkedList<String>()) { String.format("%02x", it) } return TextUtils.join(":", str) return str.joinToString(":") } } Loading
src/main/java/at/bitfire/cert4android/CertUtils.kt +4 −4 Original line number Diff line number Diff line Loading @@ -22,13 +22,13 @@ object CertUtils { try { val tmf = TrustManagerFactory.getInstance("X509") tmf.init(keyStore) for (trustManager in tmf.trustManagers) if (trustManager is X509TrustManager) return trustManager tmf.trustManagers .filterIsInstance<X509TrustManager>() .forEach { return it } } catch(e: GeneralSecurityException) { Constants.log.log(Level.SEVERE, "Couldn't initialize trust manager", e) } return null; return null } @JvmStatic Loading
src/main/java/at/bitfire/cert4android/CustomCertManager.kt +16 −19 Original line number Diff line number Diff line Loading @@ -58,15 +58,15 @@ class CustomCertManager: X509TrustManager, Closeable { private class MessageHandler: Handler.Callback { override fun handleMessage(msg: Message): Boolean { Constants.log.fine("Received reply from CustomCertificateService: " + msg) when (msg.what) { return when (msg.what) { MSG_CERTIFICATE_DECISION -> synchronized(decisionLock) { decisions.put(msg.arg1, msg.arg2 != 0) decisionLock.notifyAll() return true true } else -> return false false } } } Loading Loading @@ -124,12 +124,10 @@ class CustomCertManager: X509TrustManager, Closeable { * @param context used to bind to {@link CustomCertService} * @param trustSystemCerts whether to trust system/user-installed CAs (default trust store) */ constructor(context: Context, trustSystemCerts: Boolean) : this(context, trustSystemCerts, null) constructor(context: Context, trustSystemCerts: Boolean): this(context, trustSystemCerts, null) override fun close() { if (serviceConnection != null) context.unbindService(serviceConnection) serviceConnection?.let(context::unbindService) } Loading @@ -151,15 +149,17 @@ class CustomCertManager: X509TrustManager, Closeable { override fun checkServerTrusted(chain: Array<X509Certificate>, authType : String) { var trusted = false if (systemTrustManager != null) systemTrustManager?.let { try { systemTrustManager.checkServerTrusted(chain, authType) it.checkServerTrusted(chain, authType) trusted = true } catch(ignored: CertificateException) { Constants.log.fine("Certificate not trusted by system") } } if (!trusted) // not trusted by system, let's check ourselves checkCustomTrusted(chain[0]) } Loading Loading @@ -193,8 +193,7 @@ class CustomCertManager: X509TrustManager, Closeable { decisionLock.wait(SERVICE_TIMEOUT) } catch(e: InterruptedException) { } val decision = decisions.get(id) if (decision != null) { decisions.get(id)?.let { decision -> decisions.delete(id) if (decision) // certificate trusted Loading @@ -205,7 +204,7 @@ class CustomCertManager: X509TrustManager, Closeable { } } // timeout occurred // timeout occurred, send cancellation msg = Message.obtain() msg.what = CustomCertService.MSG_CHECK_TRUSTED_ABORT msg.arg1 = id Loading @@ -231,9 +230,7 @@ class CustomCertManager: X509TrustManager, Closeable { // custom methods fun hostnameVerifier(defaultVerifier: HostnameVerifier?) : HostnameVerifier { return CustomHostnameVerifier(defaultVerifier) } fun hostnameVerifier(defaultVerifier: HostnameVerifier?) = CustomHostnameVerifier(defaultVerifier) fun resetCertificates() { val intent = Intent(context, CustomCertService::class.java) Loading @@ -244,7 +241,7 @@ class CustomCertManager: X509TrustManager, Closeable { // hostname verifier private inner class CustomHostnameVerifier( inner class CustomHostnameVerifier( val defaultVerifier: HostnameVerifier? ): HostnameVerifier { Loading
src/main/java/at/bitfire/cert4android/CustomCertService.kt +14 −22 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ class CustomCertService: Service() { var keyStoreFile: File? = null val trustedKeyStore: KeyStore = KeyStore.getInstance(KeyStore.getDefaultType()) val trustedKeyStore = KeyStore.getInstance(KeyStore.getDefaultType())!! var customTrustManager: X509TrustManager? = null var untrustedCerts = HashSet<X509Certificate>() Loading @@ -66,9 +66,7 @@ class CustomCertService: Service() { // initialize trustedKeyStore keyStoreFile = File(getDir(KEYSTORE_DIR, Context.MODE_PRIVATE), KEYSTORE_NAME) try { FileInputStream(keyStoreFile).use { input -> trustedKeyStore.load(input, null) } FileInputStream(keyStoreFile).use { trustedKeyStore.load(it, null) } } catch(e: Exception) { Constants.log.log(Level.SEVERE, "Couldn't initialize key store, creating in-memory key store", e) try { Loading @@ -82,13 +80,12 @@ class CustomCertService: Service() { customTrustManager = CertUtils.getTrustManager(trustedKeyStore) } private fun inTrustStore(cert: X509Certificate): Boolean { private fun inTrustStore(cert: X509Certificate) = try { return trustedKeyStore.getCertificateAlias(cert) != null trustedKeyStore.getCertificateAlias(cert) != null } catch(e: KeyStoreException) { Constants.log.log(Level.WARNING, "Couldn't query custom key store", e) return false } false } Loading Loading @@ -127,16 +124,15 @@ class CustomCertService: Service() { try { trustedKeyStore.setCertificateEntry(cert.subjectDN.name, cert) saveKeyStore() } catch(e: KeyStoreException) { Constants.log.log(Level.SEVERE, "Couldn't add certificate into key store", e) } saveKeyStore() } else untrustedCerts.add(cert) // notify receivers which are waiting for a decision val receivers = pendingDecisions[cert] if (receivers != null) { pendingDecisions[cert]?.let { receivers -> for ((messenger, id) in receivers) { val message = Message.obtain() message.what = CustomCertManager.MSG_CERTIFICATE_DECISION Loading @@ -153,11 +149,9 @@ class CustomCertService: Service() { } private fun saveKeyStore() { Constants.log.fine("Saving custom certificate key store to " + keyStoreFile) Constants.log.fine("Saving custom certificate key store to $keyStoreFile") try { FileOutputStream(keyStoreFile).use { output -> trustedKeyStore.store(output, null) } FileOutputStream(keyStoreFile).use { trustedKeyStore.store(it, null) } } catch(e: Exception) { Constants.log.log(Level.SEVERE, "Couldn't save custom certificate key store", e) } Loading @@ -167,10 +161,7 @@ class CustomCertService: Service() { // bound service; Messenger for IPC val messenger = Messenger(MessageHandler(this)) override fun onBind(intent: Intent?): IBinder { return messenger.binder } override fun onBind(intent: Intent?) = messenger.binder!! private class MessageHandler( service: CustomCertService Loading @@ -184,7 +175,7 @@ class CustomCertService: Service() { return } Constants.log.info("Handling request: " + msg) Constants.log.info("Handling request: $msg") val id = msg.arg1 val data = msg.data Loading @@ -194,8 +185,7 @@ class CustomCertService: Service() { when (msg.what) { MSG_CHECK_TRUSTED -> { val reply = service.pendingDecisions[cert] if (reply != null) { service.pendingDecisions[cert]?.let { reply -> // there's already a pending decision for this certificate, just add this reply messenger reply.add(replyInfo) return Loading Loading @@ -281,6 +271,8 @@ class CustomCertService: Service() { val id: Int ) { override fun hashCode() = messenger.hashCode() xor id override fun equals(other: Any?): Boolean { return if (other is ReplyInfo) { other.messenger == messenger && other.id == id Loading
src/main/java/at/bitfire/cert4android/TrustCertificateActivity.kt +6 −5 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ package at.bitfire.cert4android import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.text.TextUtils import android.view.View import android.widget.Button import android.widget.CheckBox Loading Loading @@ -97,9 +96,11 @@ class TrustCertificateActivity: AppCompatActivity() { private fun sendDecision(trusted: Boolean) { val intent = Intent(this, CustomCertService::class.java) intent.action = CustomCertService.CMD_CERTIFICATION_DECISION intent.putExtra(CustomCertService.EXTRA_CERTIFICATE, getIntent().getSerializableExtra(EXTRA_CERTIFICATE)) intent.putExtra(CustomCertService.EXTRA_TRUSTED, trusted) with(intent) { action = CustomCertService.CMD_CERTIFICATION_DECISION putExtra(CustomCertService.EXTRA_CERTIFICATE, getIntent().getSerializableExtra(EXTRA_CERTIFICATE)) putExtra(CustomCertService.EXTRA_TRUSTED, trusted) } startService(intent) } Loading @@ -115,7 +116,7 @@ class TrustCertificateActivity: AppCompatActivity() { private fun hexString(data: ByteArray): String { val str = data.mapTo(LinkedList<String>()) { String.format("%02x", it) } return TextUtils.join(":", str) return str.joinToString(":") } }