|
@@ -3,14 +3,19 @@ package com.owncloud.android.ui
|
|
|
import android.annotation.SuppressLint
|
|
|
import android.net.http.SslCertificate
|
|
|
import android.net.http.SslError
|
|
|
+import android.webkit.ClientCertRequest
|
|
|
import android.webkit.SslErrorHandler
|
|
|
+import android.webkit.WebResourceRequest
|
|
|
+import android.webkit.WebResourceResponse
|
|
|
import android.webkit.WebView
|
|
|
import android.webkit.WebViewClient
|
|
|
import androidx.fragment.app.FragmentManager
|
|
|
import com.owncloud.android.authentication.AuthenticatorActivity
|
|
|
+import com.owncloud.android.lib.common.network.AdvancedX509KeyManager
|
|
|
import com.owncloud.android.lib.common.network.NetworkUtils
|
|
|
import com.owncloud.android.lib.common.utils.Log_OC
|
|
|
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog
|
|
|
+import org.apache.commons.httpclient.HttpStatus
|
|
|
import java.io.ByteArrayInputStream
|
|
|
import java.security.cert.CertificateException
|
|
|
import java.security.cert.CertificateFactory
|
|
@@ -78,4 +83,39 @@ open class NextcloudWebViewClient(val supportFragmentManager: FragmentManager) :
|
|
|
ft.addToBackStack(null)
|
|
|
dialog.show(ft, AuthenticatorActivity.UNTRUSTED_CERT_DIALOG_TAG)
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Handle request for a TLS client certificate.
|
|
|
+ */
|
|
|
+ override fun onReceivedClientCertRequest(view: WebView?, request: ClientCertRequest?) {
|
|
|
+ if (view == null || request == null) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ AdvancedX509KeyManager(view.context).handleWebViewClientCertRequest(request)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Handle HTTP errors.
|
|
|
+ *
|
|
|
+ * We might receive an HTTP status code 400 (bad request), which probably tells us that our certificate
|
|
|
+ * is not valid (anymore), e.g. because it expired. In that case we forget the selected client certificate,
|
|
|
+ * so it can be re-selected.
|
|
|
+ */
|
|
|
+ override fun onReceivedHttpError(
|
|
|
+ view: WebView?,
|
|
|
+ request: WebResourceRequest?,
|
|
|
+ errorResponse: WebResourceResponse?
|
|
|
+ ) {
|
|
|
+ val errorCode = errorResponse?.statusCode ?: return
|
|
|
+ if (errorCode == HttpStatus.SC_BAD_REQUEST) {
|
|
|
+ // chosen client certificate alias does not seem to work -> discard it
|
|
|
+ val failingUrl = request?.url
|
|
|
+ val context = view?.context
|
|
|
+ if (failingUrl == null || context == null) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ Log_OC.w(tag, "WebView failed with error code $errorCode; remove key chain aliases")
|
|
|
+ AdvancedX509KeyManager(context).removeKeys(failingUrl)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|