From cf916cb1bbb629056689430842a33cfe91d19c00 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 bbeeaaf0c1c5..171edde29d7f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -225,7 +225,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 5b76a0609564..106dd221eeeb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -496,6 +496,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 cfbeb9bc6079..8d84021169d3 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; @@ -126,6 +128,7 @@ import com.owncloud.android.utils.theme.ViewThemeUtils; import java.io.InputStream; +import java.net.URI; import java.net.URLDecoder; import java.util.HashMap; import java.util.Locale; @@ -147,6 +150,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; @@ -464,6 +468,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); } }); }