From ac3302cc40382ad28dee8bb7067f663816b0bff5 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Tue, 5 Sep 2023 18:16:58 +0600 Subject: [PATCH 1/3] 1442-Add_Null_check_on_signature_check issue: https://gitlab.e.foundation/e/os/backlog/-/issues/1442 on exttractSignature state, pgpObject can be null. To avoid NPE, we need to null check first. --- .../e/apps/data/cleanapk/ApkSignatureManager.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt b/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt index 9693d5229..5a2a44092 100644 --- a/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt +++ b/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt @@ -54,7 +54,7 @@ object ApkSignatureManager { publicKeyInputStream: InputStream ): Boolean { try { - val signature = extractSignature(apkSignatureInputStream) + val signature = extractSignature(apkSignatureInputStream) ?: return false val pgpPublicKeyRingCollection = PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(publicKeyInputStream), @@ -66,7 +66,7 @@ object ApkSignatureManager { updateSignature(apkInputStream, signature) return signature.verify() } catch (e: Exception) { - e.printStackTrace() + Timber.e(e) } finally { apkInputStream.close() apkSignatureInputStream.close() @@ -76,20 +76,21 @@ object ApkSignatureManager { return false } - private fun extractSignature(apkSignatureInputStream: InputStream): PGPSignature { + private fun extractSignature(apkSignatureInputStream: InputStream): PGPSignature? { var jcaPGPObjectFactory = JcaPGPObjectFactory(PGPUtil.getDecoderStream(apkSignatureInputStream)) val pgpSignatureList: PGPSignatureList - val pgpObject = jcaPGPObjectFactory.nextObject() + val pgpObject = jcaPGPObjectFactory.nextObject() ?: return null + if (pgpObject is PGPCompressedData) { jcaPGPObjectFactory = JcaPGPObjectFactory(pgpObject.dataStream) pgpSignatureList = jcaPGPObjectFactory.nextObject() as PGPSignatureList } else { pgpSignatureList = pgpObject as PGPSignatureList } - val signature = pgpSignatureList.get(0) - return signature + + return pgpSignatureList.get(0) } private fun updateSignature( -- GitLab From 052513409cbee8b3bf2614d0179d0ed943f49c66 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Wed, 6 Sep 2023 11:35:23 +0600 Subject: [PATCH 2/3] add packageName inside log when f-droid signature varification throw exception --- .../e/apps/data/cleanapk/ApkSignatureManager.kt | 10 ++++++---- .../foundation/e/apps/data/fdroid/FdroidRepository.kt | 2 +- .../e/apps/data/updates/UpdatesManagerImpl.kt | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt b/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt index 5a2a44092..3e0f4d20d 100644 --- a/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt +++ b/app/src/main/java/foundation/e/apps/data/cleanapk/ApkSignatureManager.kt @@ -34,13 +34,14 @@ import java.io.InputStream import java.security.Security object ApkSignatureManager { - fun verifyFdroidSignature(context: Context, apkFilePath: String, signature: String): Boolean { + fun verifyFdroidSignature(context: Context, apkFilePath: String, signature: String, packageName: String): Boolean { Security.addProvider(BouncyCastleProvider()) try { return verifyAPKSignature( BufferedInputStream(FileInputStream(apkFilePath)), signature.byteInputStream(Charsets.UTF_8), - context.assets.open("f-droid.org-signing-key.gpg") + context.assets.open("f-droid.org-signing-key.gpg"), + packageName ) } catch (e: Exception) { Timber.e(e) @@ -51,7 +52,8 @@ object ApkSignatureManager { private fun verifyAPKSignature( apkInputStream: BufferedInputStream, apkSignatureInputStream: InputStream, - publicKeyInputStream: InputStream + publicKeyInputStream: InputStream, + packageName: String ): Boolean { try { val signature = extractSignature(apkSignatureInputStream) ?: return false @@ -66,7 +68,7 @@ object ApkSignatureManager { updateSignature(apkInputStream, signature) return signature.verify() } catch (e: Exception) { - Timber.e(e) + Timber.e(e, "Signature verification failed for: $packageName") } finally { apkInputStream.close() apkSignatureInputStream.close() diff --git a/app/src/main/java/foundation/e/apps/data/fdroid/FdroidRepository.kt b/app/src/main/java/foundation/e/apps/data/fdroid/FdroidRepository.kt index fe2b08f0e..237592fae 100644 --- a/app/src/main/java/foundation/e/apps/data/fdroid/FdroidRepository.kt +++ b/app/src/main/java/foundation/e/apps/data/fdroid/FdroidRepository.kt @@ -56,7 +56,7 @@ class FdroidRepository @Inject constructor( override suspend fun isFdroidApplicationSigned(context: Context, packageName: String, apkFilePath: String, signature: String): Boolean { if (isFdroidApplication(packageName)) { - return ApkSignatureManager.verifyFdroidSignature(context, apkFilePath, signature) + return ApkSignatureManager.verifyFdroidSignature(context, apkFilePath, signature, packageName) } return false } diff --git a/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt b/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt index 764cab30a..0b16b840d 100644 --- a/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/updates/UpdatesManagerImpl.kt @@ -269,7 +269,7 @@ class UpdatesManagerImpl @Inject constructor( val fDroidUpdatablePackageNames = fDroidAppsAndSignatures.filter { // For each installed app also present on F-droid, check signature of base APK. val baseApkPath = pkgManagerModule.getBaseApkPath(it.key) - ApkSignatureManager.verifyFdroidSignature(context, baseApkPath, it.value) + ApkSignatureManager.verifyFdroidSignature(context, baseApkPath, it.value, it.key) }.map { it.key } return fDroidUpdatablePackageNames -- GitLab From 579de77c4f9a6a0f4d10ae50b82dff4fb9a32979 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Wed, 6 Sep 2023 12:04:00 +0600 Subject: [PATCH 3/3] fix lint errors --- app/src/main/java/foundation/e/apps/MainActivity.kt | 2 +- .../foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt | 3 ++- .../main/java/foundation/e/apps/data/login/LoginViewModel.kt | 2 +- .../main/java/foundation/e/apps/ui/search/SearchViewModel.kt | 4 +--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/MainActivity.kt b/app/src/main/java/foundation/e/apps/MainActivity.kt index c4d95fcea..98838bd35 100644 --- a/app/src/main/java/foundation/e/apps/MainActivity.kt +++ b/app/src/main/java/foundation/e/apps/MainActivity.kt @@ -54,12 +54,12 @@ import foundation.e.apps.ui.setup.signin.SignInViewModel import foundation.e.apps.utils.SystemInfoProvider import foundation.e.apps.utils.eventBus.AppEvent import foundation.e.apps.utils.eventBus.EventBus -import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch import timber.log.Timber +import javax.inject.Inject @AndroidEntryPoint class MainActivity : AppCompatActivity() { diff --git a/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt b/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt index b502cd756..839d7c168 100644 --- a/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt +++ b/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt @@ -45,7 +45,7 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject class GPlayHttpClient @Inject constructor( - private val cache: Cache, + private val cache: Cache, ) : IHttpClient { private val POST = "POST" @@ -174,6 +174,7 @@ class GPlayHttpClient @Inject constructor( when (e) { is UnknownHostException, is SocketTimeoutException -> handleExceptionOnGooglePlayRequest(e) + else -> handleExceptionOnGooglePlayRequest(e) } } finally { diff --git a/app/src/main/java/foundation/e/apps/data/login/LoginViewModel.kt b/app/src/main/java/foundation/e/apps/data/login/LoginViewModel.kt index 3fbf6c10e..659ed8318 100644 --- a/app/src/main/java/foundation/e/apps/data/login/LoginViewModel.kt +++ b/app/src/main/java/foundation/e/apps/data/login/LoginViewModel.kt @@ -24,8 +24,8 @@ import dagger.hilt.android.lifecycle.HiltViewModel import foundation.e.apps.data.enums.User import foundation.e.apps.ui.parentFragment.LoadingViewModel import kotlinx.coroutines.launch -import javax.inject.Inject import okhttp3.Cache +import javax.inject.Inject /** * ViewModel to handle all login related operations. diff --git a/app/src/main/java/foundation/e/apps/ui/search/SearchViewModel.kt b/app/src/main/java/foundation/e/apps/ui/search/SearchViewModel.kt index 90e07f32b..6a2e80774 100644 --- a/app/src/main/java/foundation/e/apps/ui/search/SearchViewModel.kt +++ b/app/src/main/java/foundation/e/apps/ui/search/SearchViewModel.kt @@ -19,7 +19,6 @@ package foundation.e.apps.ui.search import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.aurora.gplayapi.SearchSuggestEntry @@ -42,7 +41,6 @@ import timber.log.Timber import javax.inject.Inject import kotlin.coroutines.coroutineContext - @HiltViewModel class SearchViewModel @Inject constructor( private val fusedAPIRepository: FusedAPIRepository, @@ -159,7 +157,7 @@ class SearchViewModel @Inject constructor( val isFirstFetch = nextSubBundle == null nextSubBundle = gplaySearchResult.data?.second - //first page has less data, then fetch next page data without waiting for users' scroll + // first page has less data, then fetch next page data without waiting for users' scroll if (isFirstFetch) { CoroutineScope(coroutineContext).launch { fetchGplayData(query) -- GitLab