Skip to content

Commit

Permalink
feat: add option to specify keystore file path
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed Jun 22, 2022
1 parent 07f6bdf commit 9331594
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 13 deletions.
16 changes: 12 additions & 4 deletions src/main/kotlin/app/revanced/cli/command/MainCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -111,10 +117,12 @@ internal object MainCommand : Runnable {

if (!args.mount) {
Signing.start(
patchedFile,
outputFile,
args.cn,
args.password,
patchedFile, outputFile, SigningOptions(
args.cn,
args.password,
args.keystorePath
?: Path(outputFile.parent).resolve("${outputFile.nameWithoutExtension}.keystore").name
)
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/app/revanced/cli/signing/Signing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions src/main/kotlin/app/revanced/cli/signing/SigningOptions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package app.revanced.cli.signing

data class SigningOptions(
val cn: String,
val password: String,
val keyStoreFilePath: String
)
16 changes: 9 additions & 7 deletions src/main/kotlin/app/revanced/utils/signing/Signer.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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")
Expand All @@ -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,
Expand All @@ -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)

Expand Down

0 comments on commit 9331594

Please sign in to comment.