Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a344da7d authored by Hasib Prince's avatar Hasib Prince
Browse files

fixed crash in signature validation when download is failed

parent f29de8f0
Loading
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -127,11 +127,32 @@ class DownloadManager @Inject constructor(
        }
    }

    private fun tickerFlow(downloadId: Long, period: Duration, initialDelay: Duration = Duration.ZERO) = flow {
    private fun tickerFlow(
        downloadId: Long,
        period: Duration,
        initialDelay: Duration = Duration.ZERO
    ) = flow {
        delay(initialDelay)
        while (downloadsMaps[downloadId]!!) {
            emit(Unit)
            delay(period)
        }
    }

    fun getDownloadStatus(downloadId: Long): Int {
        try {
            downloadManager.query(downloadManagerQuery.setFilterById(downloadId))
                .use { cursor ->
                    if (cursor.moveToFirst()) {
                        val status =
                            cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
                        Timber.d("Download Failed: downloadId: $downloadId $status")
                        return status
                    }
                }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return DownloadManager.STATUS_FAILED
    }
}
+10 −5
Original line number Diff line number Diff line
@@ -35,11 +35,16 @@ import java.security.Security
object ApkSignatureManager {
    fun verifyFdroidSignature(context: Context, apkFilePath: String, signature: 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")
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }

    private fun verifyAPKSignature(
+27 −6
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package foundation.e.apps.manager.download

import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.api.DownloadManager
import foundation.e.apps.manager.database.fusedDownload.FusedDownload
import foundation.e.apps.manager.fused.FusedManagerRepository
import foundation.e.apps.utils.enums.Origin
@@ -33,11 +34,13 @@ import kotlinx.coroutines.sync.withLock
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
import android.app.DownloadManager as androidDownloadManager

@Singleton
class DownloadManagerUtils @Inject constructor(
    @ApplicationContext private val context: Context,
    private val fusedManagerRepository: FusedManagerRepository,
    @ApplicationContext private val context: Context
    private val downloadManager: DownloadManager
) {
    private val TAG = DownloadManagerUtils::class.java.simpleName
    private val mutex = Mutex()
@@ -57,11 +60,12 @@ class DownloadManagerUtils @Inject constructor(
                delay(1500) // Waiting for downloadmanager to publish the progress of last bytes
                val fusedDownload = fusedManagerRepository.getFusedDownload(downloadId)
                if (fusedDownload.id.isNotEmpty()) {
                    fusedDownload.downloadIdMap[downloadId] = true
                    fusedManagerRepository.updateFusedDownload(fusedDownload)
                    val downloaded = fusedDownload.downloadIdMap.values.filter { it }.size
                    Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $downloaded/${fusedDownload.downloadIdMap.size}")
                    if (downloaded == fusedDownload.downloadIdMap.size && checkCleanApkSignatureOK(fusedDownload)) {
                    updateDownloadIdMap(fusedDownload, downloadId)
                    val numberOfDownloadedItems =
                        fusedDownload.downloadIdMap.values.filter { it }.size
                    Timber.d("===> updateDownloadStatus: ${fusedDownload.name}: $downloadId: $numberOfDownloadedItems/${fusedDownload.downloadIdMap.size}")
                    if (validateDownload(numberOfDownloadedItems, fusedDownload, downloadId)) {
                        Timber.d("===> Download is completed for: ${fusedDownload.name}")
                        fusedManagerRepository.moveOBBFileToOBBDirectory(fusedDownload)
                        fusedDownload.status = Status.DOWNLOADED
                        fusedManagerRepository.updateFusedDownload(fusedDownload)
@@ -71,6 +75,23 @@ class DownloadManagerUtils @Inject constructor(
        }
    }

    private suspend fun validateDownload(
        numberOfDownloadedItems: Int,
        fusedDownload: FusedDownload,
        downloadId: Long
    ) = downloadManager.getDownloadStatus(downloadId) == androidDownloadManager.STATUS_SUCCESSFUL &&
        numberOfDownloadedItems == fusedDownload.downloadIdMap.size && checkCleanApkSignatureOK(
        fusedDownload
    )

    private suspend fun updateDownloadIdMap(
        fusedDownload: FusedDownload,
        downloadId: Long
    ) {
        fusedDownload.downloadIdMap[downloadId] = true
        fusedManagerRepository.updateFusedDownload(fusedDownload)
    }

    private suspend fun checkCleanApkSignatureOK(fusedDownload: FusedDownload): Boolean {
        if (fusedDownload.origin != Origin.CLEANAPK || fusedManagerRepository.isFdroidApplicationSigned(
                context,
+1 −1
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ class UpdatesWorker @AssistedInject constructor(
        val isConnectedToUnmeteredNetwork = isConnectedToUnmeteredNetwork(applicationContext)
        val authData = getAuthData()
        val appsNeededToUpdate = updatesManagerRepository.getUpdates(authData).first
        if (shouldShowNotification) {
        if (isAutoUpdate && shouldShowNotification) {
            handleNotification(appsNeededToUpdate.size, isConnectedToUnmeteredNetwork)
        }