diff --git a/buildSrc/src/main/java/Codegen.kt b/buildSrc/src/main/java/Codegen.kt index 7e9eae7bc..b8ac6171a 100644 --- a/buildSrc/src/main/java/Codegen.kt +++ b/buildSrc/src/main/java/Codegen.kt @@ -64,8 +64,6 @@ fun genKeyData(keysDir: File, outSrc: File) { it.println("package com.topjohnwu.magisk.signing;") it.println("public final class KeyData {") - it.byteField("testCert", File(keysDir, "testkey.x509.pem").readBytes()) - it.byteField("testKey", File(keysDir, "testkey.pk8").readBytes()) it.byteField("verityCert", File(keysDir, "verity.x509.pem").readBytes()) it.byteField("verityKey", File(keysDir, "verity.pk8").readBytes()) diff --git a/buildSrc/src/main/java/Setup.kt b/buildSrc/src/main/java/Setup.kt index a4ade9b3e..f1b11f23c 100644 --- a/buildSrc/src/main/java/Setup.kt +++ b/buildSrc/src/main/java/Setup.kt @@ -1,6 +1,11 @@ - import com.android.build.gradle.BaseExtension import com.android.build.gradle.internal.dsl.BaseAppModuleExtension +import com.android.builder.internal.packaging.IncrementalPackager +import com.android.builder.model.SigningConfig +import com.android.tools.build.apkzlib.sign.SigningExtension +import com.android.tools.build.apkzlib.sign.SigningOptions +import com.android.tools.build.apkzlib.zfile.ZFiles +import com.android.tools.build.apkzlib.zip.ZFileOptions import org.apache.tools.ant.filters.FixCrLfFilter import org.gradle.api.Action import org.gradle.api.JavaVersion @@ -16,6 +21,8 @@ import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File import java.io.PrintStream +import java.security.KeyStore +import java.security.cert.X509Certificate import java.util.* import java.util.zip.* @@ -55,6 +62,37 @@ fun Project.setupCommon() { } } +private fun SigningConfig.getPrivateKey(): KeyStore.PrivateKeyEntry { + val keyStore = KeyStore.getInstance(storeType ?: KeyStore.getDefaultType()) + storeFile!!.inputStream().use { + keyStore.load(it, storePassword!!.toCharArray()) + } + val keyPwdArray = keyPassword!!.toCharArray() + val entry = keyStore.getEntry(keyAlias!!, KeyStore.PasswordProtection(keyPwdArray)) + return entry as KeyStore.PrivateKeyEntry +} + +private fun addComment(apkPath: File, signConfig: SigningConfig, minSdk: Int, eocdComment: String) { + val privateKey = signConfig.getPrivateKey() + val signingOptions = SigningOptions.builder() + .setMinSdkVersion(minSdk) + .setV1SigningEnabled(true) + .setV2SigningEnabled(true) + .setKey(privateKey.privateKey) + .setCertificates(privateKey.certificate as X509Certificate) + .setValidation(SigningOptions.Validation.ASSUME_INVALID) + .build() + val options = ZFileOptions().apply { + noTimestamps = true + autoSortFiles = true + } + ZFiles.apk(apkPath, options).use { + SigningExtension(signingOptions).register(it) + it.eocdComment = eocdComment.toByteArray() + it.get(IncrementalPackager.APP_METADATA_ENTRY_PATH)?.delete() + } +} + private fun Project.setupAppCommon() { setupCommon() @@ -91,6 +129,19 @@ private fun Project.setupAppCommon() { includeInApk = false } } + + android.applicationVariants.all { + val projectName = project.name.toLowerCase(Locale.ROOT) + val variantCapped = name.capitalize(Locale.ROOT) + val variant = name.toLowerCase(Locale.ROOT) + tasks.getByPath(":$projectName:package$variantCapped").doLast { + val apkDir = if (properties["android.injected.invoked.from.ide"] == "true") + "intermediates" else "outputs" + val apk = File(buildDir, "${apkDir}/apk/${variant}/$projectName-${variant}.apk") + val comment = "${Config.versionCode}" + addComment(apk, signingConfig, android.defaultConfig.minSdk!!, comment) + } + } } fun Project.setupApp() { diff --git a/tools/keys/testkey.pk8 b/tools/keys/testkey.pk8 deleted file mode 100644 index 586c1bd5c..000000000 Binary files a/tools/keys/testkey.pk8 and /dev/null differ diff --git a/tools/keys/testkey.x509.pem b/tools/keys/testkey.x509.pem deleted file mode 100644 index e242d83e2..000000000 --- a/tools/keys/testkey.x509.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEqDCCA5CgAwIBAgIJAJNurL4H8gHfMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD -VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g -VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE -AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe -Fw0wODAyMjkwMTMzNDZaFw0zNTA3MTcwMTMzNDZaMIGUMQswCQYDVQQGEwJVUzET -MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G -A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p -ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI -hvcNAQEBBQADggENADCCAQgCggEBANaTGQTexgskse3HYuDZ2CU+Ps1s6x3i/waM -qOi8qM1r03hupwqnbOYOuw+ZNVn/2T53qUPn6D1LZLjk/qLT5lbx4meoG7+yMLV4 -wgRDvkxyGLhG9SEVhvA4oU6Jwr44f46+z4/Kw9oe4zDJ6pPQp8PcSvNQIg1QCAcy -4ICXF+5qBTNZ5qaU7Cyz8oSgpGbIepTYOzEJOmc3Li9kEsBubULxWBjf/gOBzAzU -RNps3cO4JFgZSAGzJWQTT7/emMkod0jb9WdqVA2BVMi7yge54kdVMxHEa5r3b97s -zI5p58ii0I54JiCUP5lyfTwE/nKZHZnfm644oLIXf6MdW2r+6R8CAQOjgfwwgfkw -HQYDVR0OBBYEFEhZAFY9JyxGrhGGBaR0GawJyowRMIHJBgNVHSMEgcEwgb6AFEhZ -AFY9JyxGrhGGBaR0GawJyowRoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE -CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH -QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG -CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAJNurL4H8gHfMAwGA1Ud -EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHqvlozrUMRBBVEY0NqrrwFbinZa -J6cVosK0TyIUFf/azgMJWr+kLfcHCHJsIGnlw27drgQAvilFLAhLwn62oX6snb4Y -LCBOsVMR9FXYJLZW2+TcIkCRLXWG/oiVHQGo/rWuWkJgU134NDEFJCJGjDbiLCpe -+ZTWHdcwauTJ9pUbo8EvHRkU3cYfGmLaLfgn9gP+pWA7LFQNvXwBnDa6sppCccEX -31I828XzgXpJ4O+mDL1/dBd+ek8ZPUP0IgdyZm5MTYPhvVqGCHzzTy3sIeJFymwr -sBbmg2OAUNLEMO6nwmocSdN2ClirfxqCzJOLSDE4QyS9BAH6EhY6UFcOaE0= ------END CERTIFICATE-----