From 1ce76f4bff3911e273463045e032dcdb6324fc43 Mon Sep 17 00:00:00 2001 From: Stephan Ritscher Date: Tue, 3 Mar 2020 22:15:49 +0100 Subject: [PATCH] Support client certificates This change adds support for configurations where the webserver requests a client certificate, e.g. via nginx configuration options ssl_client_certificate and ssl_verify_client. The client certificate handling is done via InteractiveKeyManager which prompts for a client certificate from a file or the devices keystore. This change is NOT about client certificate authentication to the nextcloud server instance. The regular authentication mechanisms will be used as soon as the communication on TLS level is established. The change addresses ticket #603, while not being a generic solution IMO. --- app/build.gradle | 3 ++- app/src/main/AndroidManifest.xml | 5 +++++ .../authentication/AuthenticatorActivity.java | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index baefbdcfeeee..f83a1a580404 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -210,7 +210,8 @@ dependencies { // dependencies for app building implementation 'androidx.multidex:multidex:2.0.1' // implementation project('nextcloud-android-library') - implementation ("com.github.nextcloud:android-library:$androidLibraryVersion") { + implementation 'com.github.stephanritscher:InteractiveKeyManager:0.1' + implementation ("com.github.stephanritscher:nextcloud-android-library:$androidLibraryVersion") { exclude group: 'org.ogce', module: 'xpp3' // unused in Android and brings wrong Junit version } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 013bf802104e..b65d0bf4fb00 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -484,6 +484,11 @@ android:name=".ui.preview.PreviewBitmapActivity" android:exported="false" android:theme="@style/Theme.ownCloud.OverlayGrey" /> + + + diff --git a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java index fdaf3681008c..b82afc837dad 100644 --- a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -61,9 +61,11 @@ import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.AndroidRuntimeException; +import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.EditorInfo; +import android.webkit.ClientCertRequest; import android.webkit.CookieManager; import android.webkit.CookieSyncManager; import android.webkit.WebResourceRequest; @@ -122,6 +124,7 @@ import com.owncloud.android.utils.theme.ThemeToolbarUtils; import java.io.InputStream; +import java.net.URI; import java.net.URLDecoder; import java.util.HashMap; import java.util.Locale; @@ -141,6 +144,7 @@ import de.cotech.hw.fido.ui.FidoDialogOptions; import de.cotech.hw.fido2.WebViewWebauthnBridge; import de.cotech.hw.fido2.ui.WebauthnDialogOptions; +import de.ritscher.ssl.InteractiveKeyManager; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import static com.owncloud.android.utils.PermissionUtil.PERMISSIONS_CAMERA; @@ -453,6 +457,17 @@ public void onReceivedError(WebView view, int errorCode, String description, Str if (!customError.isEmpty()) { accountSetupWebviewBinding.loginWebview.loadData(customError, "text/html; charset=UTF-8", null); } + + if (errorCode >= 400 && errorCode < 500) { + URI uri = URI.create(failingUrl); + Log_OC.w(TAG, "WebView failed with error code " + errorCode + "; remove key chain aliases"); + new InteractiveKeyManager(view.getContext()).removeKeys(uri.getHost(), uri.getPort()); + } + } + + @Override + public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) { + new InteractiveKeyManager(view.getContext()).handleWebViewClientCertRequest(request); } }); }