From 46978f2f6fe22ed5a4433d963ddddd74fb586f18 Mon Sep 17 00:00:00 2001 From: Xinto Date: Fri, 2 Oct 2020 18:43:16 +0400 Subject: [PATCH] new signature checking method --- .../com/vanced/manager/model/DataModel.kt | 9 ++- .../manager/ui/fragments/URLChangeFragment.kt | 1 - .../java/com/vanced/manager/utils/AppUtils.kt | 55 +++++++++++++++++++ 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/vanced/manager/model/DataModel.kt b/app/src/main/java/com/vanced/manager/model/DataModel.kt index ae3a5b36..25ef56e4 100644 --- a/app/src/main/java/com/vanced/manager/model/DataModel.kt +++ b/app/src/main/java/com/vanced/manager/model/DataModel.kt @@ -1,7 +1,6 @@ package com.vanced.manager.model import android.content.Context -import android.content.pm.PackageManager import android.graphics.drawable.Drawable import android.os.Build import androidx.core.content.ContextCompat @@ -11,6 +10,7 @@ import androidx.databinding.ObservableInt import com.beust.klaxon.JsonObject import com.vanced.manager.BuildConfig.ENABLE_SIGNATURE_CHECK import com.vanced.manager.R +import com.vanced.manager.utils.AppUtils.doSignaturesMatch import com.vanced.manager.utils.AppUtils.managerPkg import com.vanced.manager.utils.AppUtils.vancedRootPkg import com.vanced.manager.utils.PackageHelper.isPackageInstalled @@ -37,9 +37,9 @@ open class DataModel( fun fetch() = CoroutineScope(Dispatchers.IO).launch { isAppInstalled.set(isPackageInstalled(appPkg, context.packageManager)) + isOfficial.set(doSignaturesMatch(managerPkg, appPkg, context)) versionName.set(jsonObject.get()?.string("version")?.removeSuffix("-vanced") ?: context.getString(R.string.unavailable)) installedVersionName.set(getPkgVersionName(isAppInstalled.get(), appPkg)) - isOfficial.set(doSignaturesMatch(managerPkg, appPkg)) versionCode.set(jsonObject.get()?.int("versionCode") ?: 0) installedVersionCode.set(getPkgVersionCode(isAppInstalled.get(), appPkg)) buttonTxt.set(compareInt(installedVersionCode.get(), versionCode.get())) @@ -55,7 +55,7 @@ open class DataModel( val pm = context.packageManager return if (toCheck) { if (ENABLE_SIGNATURE_CHECK) { - if (doSignaturesMatch(managerPkg, pkg) || appPkg == vancedRootPkg) + if (isOfficial.get() || appPkg == vancedRootPkg) pm.getPackageInfo(pkg, 0).versionName.removeSuffix("-vanced") else pm.getPackageInfo(pkg, 0).versionName.removeSuffix("-vanced") + " (${context.getString(R.string.unofficial)})" @@ -66,12 +66,15 @@ open class DataModel( } } + /* private fun doSignaturesMatch(pkg1: String, pkg2: String): Boolean = if (isPackageInstalled(pkg2, context.packageManager)) context.packageManager.checkSignatures(pkg1, pkg2) == PackageManager.SIGNATURE_MATCH else true + */ + @Suppress("DEPRECATION") private fun getPkgVersionCode(toCheck: Boolean, pkg: String): Int { return if (toCheck) { diff --git a/app/src/main/java/com/vanced/manager/ui/fragments/URLChangeFragment.kt b/app/src/main/java/com/vanced/manager/ui/fragments/URLChangeFragment.kt index 4eaf0275..3edf1d4a 100644 --- a/app/src/main/java/com/vanced/manager/ui/fragments/URLChangeFragment.kt +++ b/app/src/main/java/com/vanced/manager/ui/fragments/URLChangeFragment.kt @@ -1,6 +1,5 @@ package com.vanced.manager.ui.fragments -import android.content.Context import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.os.Bundle diff --git a/app/src/main/java/com/vanced/manager/utils/AppUtils.kt b/app/src/main/java/com/vanced/manager/utils/AppUtils.kt index 503d8e0b..2609f0bb 100644 --- a/app/src/main/java/com/vanced/manager/utils/AppUtils.kt +++ b/app/src/main/java/com/vanced/manager/utils/AppUtils.kt @@ -1,8 +1,11 @@ package com.vanced.manager.utils +import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.content.pm.PackageInstaller +import android.content.pm.PackageManager +import android.os.Build import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.localbroadcastmanager.content.LocalBroadcastManager @@ -13,6 +16,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import java.security.MessageDigest object AppUtils { @@ -55,6 +59,57 @@ object AppUtils { } } + fun doSignaturesMatch(pkg1: String, pkg2: String, context: Context): Boolean { + val apk1sig = getApplicationSignature(pkg1, context) + val apk2sig = getApplicationSignature(pkg2, context) + return apk2sig.containsAll(apk1sig) + } + + @SuppressLint("PackageManagerGetSignatures") + fun getApplicationSignature(packageName: String, context: Context): List { + val signatureList: List + return try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + val sig = context.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES).signingInfo + signatureList = if (sig.hasMultipleSigners()) { + sig.apkContentsSigners.map { + val msgDigest = MessageDigest.getInstance("SHA") + msgDigest.update(it.toByteArray()) + bytesToHex(msgDigest.digest()) + } + } else { + sig.signingCertificateHistory.map { + val msgDigest = MessageDigest.getInstance("SHA") + msgDigest.update(it.toByteArray()) + bytesToHex(msgDigest.digest()) + } + } + } else { + val sig = context.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures + signatureList = sig.map { + val msgDigest = MessageDigest.getInstance("SHA") + msgDigest.update(it.toByteArray()) + bytesToHex(msgDigest.digest()) + } + } + signatureList + } catch (e: Exception) { + emptyList() + } + } + + private fun bytesToHex(bytes: ByteArray): String { + val hexArray = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F') + val hexChars = CharArray(bytes.size * 2) + var v: Int + for (j in bytes.indices) { + v = bytes[j].toInt() and 0xFF + hexChars[j * 2] = hexArray[v.ushr(4)] + hexChars[j * 2 + 1] = hexArray[v and 0x0F] + } + return String(hexChars) + } + private fun getErrorMessage(status: String, context: Context): String { return when { status.contains("INSTALL_FAILED_ABORTED") -> context.getString(R.string.installation_aborted)