From a4e1b29937c3b42216f7d56f8b414886c3ba0825 Mon Sep 17 00:00:00 2001 From: Stephan Ritscher Date: Wed, 30 Aug 2023 22:26:04 +0200 Subject: [PATCH] Add support for client certificates --- .gitmodules | 6 ++++++ InteractiveKeyManager | 1 + MemorizingTrustManager | 1 + app/build.gradle | 9 +++++++-- app/proguard-rules.pro | 5 ++++- app/src/main/AndroidManifest.xml | 10 +++++++++- .../patrick/grocy/web/RequestQueueSingleton.java | 16 +++++++++++++--- build.gradle | 2 +- settings.gradle | 4 +++- 9 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 .gitmodules create mode 160000 InteractiveKeyManager create mode 160000 MemorizingTrustManager diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..c60e9c01b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "InteractiveKeyManager"] + path = InteractiveKeyManager + url = https://github.com/stephanritscher/InteractiveKeyManager +[submodule "MemorizingTrustManager"] + path = MemorizingTrustManager + url = https://github.com/stephanritscher/MemorizingTrustManager.git diff --git a/InteractiveKeyManager b/InteractiveKeyManager new file mode 160000 index 000000000..904320330 --- /dev/null +++ b/InteractiveKeyManager @@ -0,0 +1 @@ +Subproject commit 9043203304a0856089eb347cad2c93bfb7d75ff9 diff --git a/MemorizingTrustManager b/MemorizingTrustManager new file mode 160000 index 000000000..de1d93345 --- /dev/null +++ b/MemorizingTrustManager @@ -0,0 +1 @@ +Subproject commit de1d9334558df60ca6ac89fa00160a43f2a11cf8 diff --git a/app/build.gradle b/app/build.gradle index 5bc9c1d14..6cc51361c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,7 +38,7 @@ android { defaultConfig { applicationId "xyz.zedler.patrick.grocy" - minSdk 21 + minSdk 23 targetSdk 34 compileSdk 34 versionCode 50 @@ -96,6 +96,11 @@ dependencies { implementation libs.webkit implementation libs.lifecycle.viewmodel.savedstate implementation libs.lifecycle.viewmodel.ktx + + // Certificate and trust management + implementation project(':InteractiveKeyManager') + implementation project(':MemorizingTrustManager') + // Navigation framework for easy navigation control using XML implementation libs.navigation.fragment implementation libs.navigation.ui @@ -126,4 +131,4 @@ dependencies { // https://github.com/journeyapps/zxing-android-embedded#option-2-desugaring-advanced // prevents bug https://github.com/patzly/grocy-android/issues/425 coreLibraryDesugaring libs.desugar -} \ No newline at end of file +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index bb3e3adb0..532953bd6 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -60,4 +60,7 @@ # This was generated automatically by the Android Gradle plugin to hide warnings # Only has effected these pre-KitKat two compatibility classes -dontwarn com.android.org.conscrypt.SSLParametersImpl --dontwarn org.apache.harmony.xnet.provider.jsse.SSLParametersImpl \ No newline at end of file +-dontwarn org.apache.harmony.xnet.provider.jsse.SSLParametersImpl + +# This is generated automatically by the Android Gradle plugin. +-dontwarn lombok.NonNull \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d63de098e..f7708a9a5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -81,6 +81,14 @@ + + + + + - \ No newline at end of file + diff --git a/app/src/main/java/xyz/zedler/patrick/grocy/web/RequestQueueSingleton.java b/app/src/main/java/xyz/zedler/patrick/grocy/web/RequestQueueSingleton.java index 46e007abc..da2abb527 100644 --- a/app/src/main/java/xyz/zedler/patrick/grocy/web/RequestQueueSingleton.java +++ b/app/src/main/java/xyz/zedler/patrick/grocy/web/RequestQueueSingleton.java @@ -28,14 +28,22 @@ import com.android.volley.toolbox.BasicNetwork; import com.android.volley.toolbox.DiskBasedCache; import com.android.volley.toolbox.HurlStack; + +import de.duenndns.ssl.MemorizingTrustManager; +import de.ritscher.ssl.InteractiveKeyManager; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + import xyz.zedler.patrick.grocy.Constants.SETTINGS.NETWORK; import xyz.zedler.patrick.grocy.Constants.SETTINGS_DEFAULT; @@ -78,7 +86,7 @@ public void newRequestQueue() { stack = new ProxyHurlStack(sharedPrefs, useTor); } else { try { - stack = new HurlStack(null, new TLSSocketFactory()); + stack = new HurlStack(null, new TLSSocketFactory(ctx)); } catch (NoSuchAlgorithmException | KeyManagementException e) { stack = new HurlStack(); } @@ -92,9 +100,11 @@ private static class TLSSocketFactory extends SSLSocketFactory { private final SSLSocketFactory internalSSLSocketFactory; - public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { + public TLSSocketFactory(Context ctx) throws KeyManagementException, NoSuchAlgorithmException { SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, null, null); + KeyManager keyManager = new InteractiveKeyManager(ctx.getApplicationContext()); + TrustManager mtm = new MemorizingTrustManager(ctx); + context.init(new KeyManager[]{keyManager}, new TrustManager[]{mtm}, new SecureRandom()); internalSSLSocketFactory = context.getSocketFactory(); } diff --git a/build.gradle b/build.gradle index ccebb013c..b46cc6545 100644 --- a/build.gradle +++ b/build.gradle @@ -21,4 +21,4 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.navigation.safeargs) apply false -} \ No newline at end of file +} diff --git a/settings.gradle b/settings.gradle index beac62cee..f45130941 100644 --- a/settings.gradle +++ b/settings.gradle @@ -35,4 +35,6 @@ dependencyResolutionManagement { } rootProject.name = "Grocy Android" -include ':app' \ No newline at end of file +include ':app' +include ':InteractiveKeyManager' +include ':MemorizingTrustManager'