From fbeee2300cfe64628f795ac818e9ae93eb8f890a Mon Sep 17 00:00:00 2001 From: Rahul Patel Date: Mon, 16 Dec 2024 21:16:58 +0530 Subject: [PATCH] CertifitacePinning: Add toggle to enable/disable - Enabled by default - Could be useful for people using VPN based ad blockers - Option to make app usable, if at all Google's root certs gets changed/updated --- .../store/data/network/OkHttpClientModule.kt | 49 ++++++++++++++----- .../java/com/aurora/store/util/Preferences.kt | 1 + .../view/ui/onboarding/OnboardingFragment.kt | 3 ++ app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/preferences_network.xml | 6 +++ 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt b/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt index a04e93312..ba79cddee 100644 --- a/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt +++ b/app/src/main/java/com/aurora/store/data/network/OkHttpClientModule.kt @@ -26,6 +26,7 @@ import com.aurora.store.R import com.aurora.store.data.model.Algorithm import com.aurora.store.data.model.ProxyInfo import com.aurora.store.util.Preferences +import com.aurora.store.util.Preferences.PREFERENCE_CERTIFICATE_PINNING_ENABLED import com.aurora.store.util.Preferences.PREFERENCE_PROXY_ENABLED import com.aurora.store.util.Preferences.PREFERENCE_PROXY_INFO import com.google.gson.Gson @@ -34,10 +35,10 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent -import java.io.ByteArrayInputStream -import java.io.InputStream import okhttp3.CertificatePinner import okhttp3.OkHttpClient +import java.io.ByteArrayInputStream +import java.io.InputStream import java.net.Authenticator import java.net.InetSocketAddress import java.net.PasswordAuthentication @@ -59,17 +60,33 @@ object OkHttpClientModule { @Provides @Singleton - fun providesOkHttpClientInstance(certPinner: CertificatePinner, proxy: Proxy?): OkHttpClient { - return OkHttpClient().newBuilder() + fun providesOkHttpClientInstance( + @ApplicationContext context: Context, + certPinner: CertificatePinner, + proxy: Proxy? + ): OkHttpClient { + val isCertPinningEnabled = Preferences.getBoolean( + context, + PREFERENCE_CERTIFICATE_PINNING_ENABLED, + true + ) + + val builder = OkHttpClient().newBuilder() .proxy(proxy) - .certificatePinner(certPinner) .connectTimeout(25, TimeUnit.SECONDS) .readTimeout(25, TimeUnit.SECONDS) .writeTimeout(25, TimeUnit.SECONDS) .retryOnConnectionFailure(true) .followRedirects(true) .followSslRedirects(true) - .build() + + if (isCertPinningEnabled) { + builder.certificatePinner(certPinner) + } else { + Log.i(TAG, "Certificate pinning is disabled") + } + + return builder.build() } @Provides @@ -79,12 +96,21 @@ object OkHttpClientModule { val googleRootCerts = getGoogleRootCertHashes(context).map { "sha256/$it" } .toTypedArray() - return CertificatePinner.Builder() + return CertificatePinner.Builder() .add("*.googleapis.com", *googleRootCerts) .add("*.google.com", *googleRootCerts) - .add("auroraoss.com", "sha256/mEflZT5enoR1FuXLgYYGqnVEoZvmf9c2bVBpiOjYQ0c=") // GTS Root R4 - .add("*.exodus-privacy.eu.org", "sha256/C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=") // ISRG Root X1 - .add("gitlab.com", "sha256/x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=") // USERTrust RSA Certification Authority + .add( + "auroraoss.com", + "sha256/mEflZT5enoR1FuXLgYYGqnVEoZvmf9c2bVBpiOjYQ0c=" + ) // GTS Root R4 + .add( + "*.exodus-privacy.eu.org", + "sha256/C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=" + ) // ISRG Root X1 + .add( + "gitlab.com", + "sha256/x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=" + ) // USERTrust RSA Certification Authority .build() } @@ -121,7 +147,8 @@ object OkHttpClientModule { private fun getGoogleRootCertHashes(context: Context): List { return try { - val certs = getX509Certificates(context.resources.openRawResource(R.raw.google_roots_ca)) + val certs = + getX509Certificates(context.resources.openRawResource(R.raw.google_roots_ca)) certs.map { val messageDigest = MessageDigest.getInstance(Algorithm.SHA256.value) messageDigest.update(it.publicKey.encoded) diff --git a/app/src/main/java/com/aurora/store/util/Preferences.kt b/app/src/main/java/com/aurora/store/util/Preferences.kt index 0026bae7c..c00d3ffc8 100644 --- a/app/src/main/java/com/aurora/store/util/Preferences.kt +++ b/app/src/main/java/com/aurora/store/util/Preferences.kt @@ -47,6 +47,7 @@ object Preferences { const val PREFERENCE_PROXY_URL = "PREFERENCE_PROXY_URL" const val PREFERENCE_PROXY_INFO = "PREFERENCE_PROXY_INFO" const val PREFERENCE_PROXY_ENABLED = "PREFERENCE_PROXY_ENABLED" + const val PREFERENCE_CERTIFICATE_PINNING_ENABLED = "PREFERENCE_CERTIFICATE_PINNING_ENABLED" const val PREFERENCE_DISPENSER_URLS = "PREFERENCE_DISPENSER_URLS" const val PREFERENCE_VENDING_VERSION = "PREFERENCE_VENDING_VERSION" diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt index 43d458aa8..33b5aa97d 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt @@ -31,6 +31,7 @@ import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback import com.aurora.Constants import com.aurora.extensions.areNotificationsEnabled import com.aurora.extensions.isIgnoringBatteryOptimizations +import com.aurora.store.BuildConfig import com.aurora.store.R import com.aurora.store.data.helper.UpdateHelper import com.aurora.store.data.model.UpdateMode @@ -40,6 +41,7 @@ import com.aurora.store.util.CertUtil import com.aurora.store.util.PackageUtil import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_AUTO_DELETE +import com.aurora.store.util.Preferences.PREFERENCE_CERTIFICATE_PINNING_ENABLED import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT_SELECTED_TAB import com.aurora.store.util.Preferences.PREFERENCE_DISPENSER_URLS @@ -169,6 +171,7 @@ class OnboardingFragment : BaseFragment() { if (!CertUtil.isAppGalleryApp(requireContext(), requireContext().packageName)) { save(PREFERENCE_DISPENSER_URLS, setOf(Constants.URL_DISPENSER)) } + save(PREFERENCE_CERTIFICATE_PINNING_ENABLED, !BuildConfig.DEBUG) save(PREFERENCE_VENDING_VERSION, 0) /*Customization*/ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 72d6baf6b..83c1a8697 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -231,6 +231,8 @@ Proxy "Enable proxy" "Allow all traffic from app to go through the proxy" + "Enable certificate pinning" + "Locks the app to trust only specific server certificates, preventing connections to untrusted or compromised servers." "Proxy URL" Enter a valid proxy URL to pass all data through the proxy. "Customization" diff --git a/app/src/main/res/xml/preferences_network.xml b/app/src/main/res/xml/preferences_network.xml index e0f4856d7..8feabd5d3 100644 --- a/app/src/main/res/xml/preferences_network.xml +++ b/app/src/main/res/xml/preferences_network.xml @@ -44,6 +44,12 @@ app:singleLineTitle="false" app:title="@string/pref_common_extra" /> + +