diff --git a/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt b/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt index eb8652ac9..061e714be 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt @@ -82,7 +82,7 @@ object HideAPK { // Write apk changes jar.getOutputStream(je).use { it.write(xml.bytes) } - val keys = Keygen(context) + val keys = Keygen() SignApk.sign(keys.cert, keys.key, jar, out) return true } @@ -104,6 +104,7 @@ object HideAPK { activity.finish() } + @Suppress("BlockingMethodInNonBlockingContext") private suspend fun patchAndHide(activity: Activity, label: String, onFailure: Runnable): Boolean { val stub = File(activity.cacheDir, "stub.apk") try { @@ -130,7 +131,7 @@ object HideAPK { } val cmd = "adb_pm_install $repack ${activity.applicationInfo.uid}" - if (Shell.su(cmd).exec().isSuccess) return true + if (Shell.cmd(cmd).exec().isSuccess) return true try { session.install(activity, repack) @@ -178,7 +179,7 @@ object HideAPK { dialog.dismiss() } val cmd = "adb_pm_install $apk ${activity.applicationInfo.uid}" - if (Shell.su(cmd).await().isSuccess) return + if (Shell.cmd(cmd).await().isSuccess) return val success = withContext(Dispatchers.IO) { try { session.install(activity, apk) diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt index 7fba0f5d6..9d8091961 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt @@ -1,23 +1,16 @@ package com.topjohnwu.magisk.core.utils -import android.content.Context -import android.content.pm.PackageManager import android.util.Base64 import android.util.Base64OutputStream import com.topjohnwu.magisk.core.Config -import com.topjohnwu.magisk.signing.CryptoUtils.readCertificate -import com.topjohnwu.magisk.signing.CryptoUtils.readPrivateKey -import com.topjohnwu.magisk.signing.KeyData import org.bouncycastle.asn1.x500.X500Name import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder -import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.math.BigInteger import java.security.KeyPairGenerator import java.security.KeyStore -import java.security.MessageDigest import java.security.PrivateKey import java.security.cert.X509Certificate import java.util.* @@ -29,13 +22,11 @@ private interface CertKeyProvider { val key: PrivateKey } -@Suppress("DEPRECATION") -class Keygen(context: Context) : CertKeyProvider { +class Keygen : CertKeyProvider { companion object { private const val ALIAS = "magisk" private val PASSWORD get() = "magisk".toCharArray() - private const val TESTKEY_CERT = "61ed377e85d386a8dfee6b864bd85b0bfaa5af81" private const val DNAME = "C=US,ST=California,L=Mountain View,O=Google Inc.,OU=Android,CN=Android" private const val BASE64_FLAG = Base64.NO_PADDING or Base64.NO_WRAP } @@ -43,49 +34,9 @@ class Keygen(context: Context) : CertKeyProvider { private val start = Calendar.getInstance().apply { add(Calendar.MONTH, -3) } private val end = (start.clone() as Calendar).apply { add(Calendar.YEAR, 30) } - override val cert get() = provider.cert - override val key get() = provider.key - - private val provider: CertKeyProvider - - inner class KeyStoreProvider : - CertKeyProvider { - private val ks by lazy { init() } - override val cert by lazy { ks.getCertificate(ALIAS) as X509Certificate } - override val key by lazy { ks.getKey( - ALIAS, - PASSWORD - ) as PrivateKey } - } - - class TestProvider : CertKeyProvider { - override val cert by lazy { - readCertificate(ByteArrayInputStream(KeyData.testCert())) - } - override val key by lazy { - readPrivateKey(ByteArrayInputStream(KeyData.testKey())) - } - } - - init { - val pm = context.packageManager - val info = pm.getPackageInfo(context.packageName, PackageManager.GET_SIGNATURES) - val sig = info.signatures[0] - val digest = MessageDigest.getInstance("SHA1") - val chksum = digest.digest(sig.toByteArray()) - - val sb = StringBuilder() - for (b in chksum) { - sb.append("%02x".format(0xFF and b.toInt())) - } - - provider = if (sb.toString() == TESTKEY_CERT) { - // The app was signed by the test key, continue to use it (legacy mode) - TestProvider() - } else { - KeyStoreProvider() - } - } + private val ks = init() + override val cert = ks.getCertificate(ALIAS) as X509Certificate + override val key = ks.getKey(ALIAS, PASSWORD) as PrivateKey private fun init(): KeyStore { val raw = Config.keyStoreRaw @@ -93,12 +44,8 @@ class Keygen(context: Context) : CertKeyProvider { if (raw.isEmpty()) { ks.load(null) } else { - GZIPInputStream(Base64.decode(raw, - BASE64_FLAG - ).inputStream()).use { - ks.load(it, - PASSWORD - ) + GZIPInputStream(Base64.decode(raw, BASE64_FLAG).inputStream()).use { + ks.load(it, PASSWORD) } } @@ -115,16 +62,10 @@ class Keygen(context: Context) : CertKeyProvider { val cert = JcaX509CertificateConverter().getCertificate(builder.build(signer)) // Store them into keystore - ks.setKeyEntry( - ALIAS, kp.private, - PASSWORD, arrayOf(cert)) + ks.setKeyEntry(ALIAS, kp.private, PASSWORD, arrayOf(cert)) val bytes = ByteArrayOutputStream() - GZIPOutputStream(Base64OutputStream(bytes, - BASE64_FLAG - )).use { - ks.store(it, - PASSWORD - ) + GZIPOutputStream(Base64OutputStream(bytes, BASE64_FLAG)).use { + ks.store(it, PASSWORD) } Config.keyStoreRaw = bytes.toString("UTF-8")