feat: add option to specify keystore file path

This commit is contained in:
oSumAtrIX 2022-06-22 13:45:52 +02:00
parent 07f6bdf330
commit 9331594706
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
4 changed files with 30 additions and 13 deletions

View File

@ -2,6 +2,7 @@ package app.revanced.cli.command
import app.revanced.cli.patcher.Patcher
import app.revanced.cli.signing.Signing
import app.revanced.cli.signing.SigningOptions
import app.revanced.patcher.PatcherOptions
import app.revanced.patcher.extensions.PatchExtensions.description
import app.revanced.patcher.extensions.PatchExtensions.patchName
@ -11,6 +12,8 @@ import picocli.CommandLine.*
import java.io.File
import java.nio.file.Files
import java.util.logging.Logger
import kotlin.io.path.Path
import kotlin.io.path.name
@Command(
name = "ReVanced-CLI", version = ["1.0.0"], mixinStandardHelpOptions = true
@ -62,6 +65,9 @@ internal object MainCommand : Runnable {
@Option(names = ["--cn"], description = ["Overwrite the default CN for the signed file"])
var cn = "ReVanced"
@Option(names = ["--keystore"], description = ["File path to your keystore"])
var keystorePath: String? = null
@Option(names = ["-p", "--password"], description = ["Overwrite the default password for the signed file"])
var password = "ReVanced"
@ -111,10 +117,12 @@ internal object MainCommand : Runnable {
if (!args.mount) {
Signing.start(
patchedFile,
outputFile,
patchedFile, outputFile, SigningOptions(
args.cn,
args.password,
args.keystorePath
?: Path(outputFile.parent).resolve("${outputFile.nameWithoutExtension}.keystore").name
)
)
}

View File

@ -7,7 +7,7 @@ import app.revanced.utils.signing.align.ZipAligner
import java.io.File
object Signing {
fun start(inputFile: File, outputFile: File, cn: String, password: String) {
fun start(inputFile: File, outputFile: File, signingOptions: SigningOptions) {
val cacheDirectory = File(args.pArgs!!.cacheDirectory)
val alignedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk")
val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk")
@ -22,7 +22,7 @@ object Signing {
// sign the alignedOutput and write to signedOutput
// the reason is, in case the signer fails
// it does not damage the output file
val keyStore = Signer(cn, password).signApk(alignedOutput, signedOutput)
val keyStore = Signer(signingOptions).signApk(alignedOutput, signedOutput)
// afterwards copy over the file and the keystore to the output
signedOutput.copyTo(outputFile, true)

View File

@ -0,0 +1,7 @@
package app.revanced.cli.signing
data class SigningOptions(
val cn: String,
val password: String,
val keyStoreFilePath: String
)

View File

@ -1,5 +1,7 @@
package app.revanced.utils.signing
import app.revanced.cli.command.MainCommand.logger
import app.revanced.cli.signing.SigningOptions
import com.android.apksig.ApkSigner
import org.bouncycastle.asn1.x500.X500Name
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
@ -17,9 +19,9 @@ import java.security.cert.X509Certificate
import java.util.*
internal class Signer(
private val cn: String, password: String
private val signingOptions: SigningOptions
) {
private val passwordCharArray = password.toCharArray()
private val passwordCharArray = signingOptions.password.toCharArray()
private fun newKeystore(out: File) {
val (publicKey, privateKey) = createKey()
val privateKS = KeyStore.getInstance("BKS", "BC")
@ -34,7 +36,7 @@ internal class Signer(
val pair = gen.generateKeyPair()
var serialNumber: BigInteger
do serialNumber = BigInteger.valueOf(SecureRandom().nextLong()) while (serialNumber < BigInteger.ZERO)
val x500Name = X500Name("CN=$cn")
val x500Name = X500Name("CN=${signingOptions.cn}")
val builder = X509v3CertificateBuilder(
x500Name,
serialNumber,
@ -52,21 +54,21 @@ internal class Signer(
Security.addProvider(BouncyCastleProvider())
// TODO: keystore should be saved securely
val ks = File(input.parent, "${output.nameWithoutExtension}.keystore")
if (!ks.exists()) newKeystore(ks)
val ks = File(signingOptions.keyStoreFilePath)
if (!ks.exists()) newKeystore(ks) else logger.info("Found existing keystore ${ks.nameWithoutExtension}")
val keyStore = KeyStore.getInstance("BKS", "BC")
FileInputStream(ks).use { fis -> keyStore.load(fis, null) }
val alias = keyStore.aliases().nextElement()
val config = ApkSigner.SignerConfig.Builder(
cn,
signingOptions.cn,
keyStore.getKey(alias, passwordCharArray) as PrivateKey,
listOf(keyStore.getCertificate(alias) as X509Certificate)
).build()
val signer = ApkSigner.Builder(listOf(config))
signer.setCreatedBy(cn)
signer.setCreatedBy(signingOptions.cn)
signer.setInputApk(input)
signer.setOutputApk(output)