Skip to content

Commit

Permalink
chore: Lint code
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed Nov 26, 2023
1 parent 50c2b39 commit a9e5966
Show file tree
Hide file tree
Showing 15 changed files with 292 additions and 207 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ publishing {
}
}
}
}
}
95 changes: 51 additions & 44 deletions src/main/kotlin/app/revanced/library/ApkSigner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ object ApkSigner {
private val logger = Logger.getLogger(app.revanced.library.ApkSigner::class.java.name)

init {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(BouncyCastleProvider())
}
}

/**
Expand All @@ -39,14 +40,15 @@ object ApkSigner {
*/
fun newPrivateKeyCertificatePair(
commonName: String = "ReVanced",
validUntil: Date = Date(System.currentTimeMillis() + 356.days.inWholeMilliseconds * 24)
validUntil: Date = Date(System.currentTimeMillis() + 356.days.inWholeMilliseconds * 24),
): PrivateKeyCertificatePair {
logger.fine("Creating certificate for $commonName")

// Generate a new key pair.
val keyPair = KeyPairGenerator.getInstance("RSA").apply {
initialize(4096)
}.generateKeyPair()
val keyPair =
KeyPairGenerator.getInstance("RSA").apply {
initialize(4096)
}.generateKeyPair()

var serialNumber: BigInteger
do serialNumber = BigInteger.valueOf(SecureRandom().nextLong())
Expand All @@ -55,22 +57,22 @@ object ApkSigner {
val name = X500Name("CN=$commonName")

// Create a new certificate.
val certificate = JcaX509CertificateConverter().getCertificate(
X509v3CertificateBuilder(
name,
serialNumber,
Date(System.currentTimeMillis()),
validUntil,
Locale.ENGLISH,
name,
SubjectPublicKeyInfo.getInstance(keyPair.public.encoded)
).build(JcaContentSignerBuilder("SHA256withRSA").build(keyPair.private))
)
val certificate =
JcaX509CertificateConverter().getCertificate(
X509v3CertificateBuilder(
name,
serialNumber,
Date(System.currentTimeMillis()),
validUntil,
Locale.ENGLISH,
name,
SubjectPublicKeyInfo.getInstance(keyPair.public.encoded),
).build(JcaContentSignerBuilder("SHA256withRSA").build(keyPair.private)),
)

return PrivateKeyCertificatePair(keyPair.private, certificate)
}


/**
* Read a [PrivateKeyCertificatePair] from a keystore entry.
*
Expand All @@ -87,16 +89,18 @@ object ApkSigner {
): PrivateKeyCertificatePair {
logger.fine("Reading key and certificate pair from keystore entry $keyStoreEntryAlias")

if (!keyStore.containsAlias(keyStoreEntryAlias))
if (!keyStore.containsAlias(keyStoreEntryAlias)) {
throw IllegalArgumentException("Keystore does not contain alias $keyStoreEntryAlias")
}

// Read the private key and certificate from the keystore.

val privateKey = try {
keyStore.getKey(keyStoreEntryAlias, keyStoreEntryPassword.toCharArray()) as PrivateKey
} catch (exception: UnrecoverableKeyException) {
throw IllegalArgumentException("Invalid password for keystore entry $keyStoreEntryAlias")
}
val privateKey =
try {
keyStore.getKey(keyStoreEntryAlias, keyStoreEntryPassword.toCharArray()) as PrivateKey
} catch (exception: UnrecoverableKeyException) {
throw IllegalArgumentException("Invalid password for keystore entry $keyStoreEntryAlias")
}

val certificate = keyStore.getCertificate(keyStoreEntryAlias) as X509Certificate

Expand All @@ -110,9 +114,7 @@ object ApkSigner {
* @return The created keystore.
* @see KeyStoreEntry
*/
fun newKeyStore(
entries: List<KeyStoreEntry>
): KeyStore {
fun newKeyStore(entries: List<KeyStoreEntry>): KeyStore {
logger.fine("Creating keystore")

return KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME).apply {
Expand All @@ -124,7 +126,7 @@ object ApkSigner {
entry.alias,
entry.privateKeyCertificatePair.privateKey,
entry.password.toCharArray(),
arrayOf(entry.privateKeyCertificatePair.certificate)
arrayOf(entry.privateKeyCertificatePair.certificate),
)
}
}
Expand All @@ -140,10 +142,10 @@ object ApkSigner {
fun newKeyStore(
keyStoreOutputStream: OutputStream,
keyStorePassword: String,
entries: List<KeyStoreEntry>
entries: List<KeyStoreEntry>,
) = newKeyStore(entries).store(
keyStoreOutputStream,
keyStorePassword.toCharArray()
keyStorePassword.toCharArray(),
) // Save the keystore.

/**
Expand All @@ -156,18 +158,19 @@ object ApkSigner {
*/
fun readKeyStore(
keyStoreInputStream: InputStream,
keyStorePassword: String?
keyStorePassword: String?,
): KeyStore {
logger.fine("Reading keystore")

return KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME).apply {
try {
load(keyStoreInputStream, keyStorePassword?.toCharArray())
} catch (exception: IOException) {
if (exception.cause is UnrecoverableKeyException)
if (exception.cause is UnrecoverableKeyException) {
throw IllegalArgumentException("Invalid keystore password")
else
} else {
throw exception
}
}
}
}
Expand All @@ -183,20 +186,21 @@ object ApkSigner {
fun newApkSignerBuilder(
privateKeyCertificatePair: PrivateKeyCertificatePair,
signer: String,
createdBy: String
createdBy: String,
): ApkSigner.Builder {
logger.fine(
"Creating new ApkSigner " +
"with $signer as signer and " +
"$createdBy as Created-By attribute in the APK's manifest"
"with $signer as signer and " +
"$createdBy as Created-By attribute in the APK's manifest",
)

// Create the signer config.
val signerConfig = ApkSigner.SignerConfig.Builder(
signer,
privateKeyCertificatePair.privateKey,
listOf(privateKeyCertificatePair.certificate)
).build()
val signerConfig =
ApkSigner.SignerConfig.Builder(
signer,
privateKeyCertificatePair.privateKey,
listOf(privateKeyCertificatePair.certificate),
).build()

// Create the signer.
return ApkSigner.Builder(listOf(signerConfig)).apply {
Expand Down Expand Up @@ -227,10 +231,13 @@ object ApkSigner {
) = newApkSignerBuilder(
readKeyCertificatePair(keyStore, keyStoreEntryAlias, keyStoreEntryPassword),
signer,
createdBy
createdBy,
)

fun ApkSigner.Builder.signApk(input: File, output: File) {
fun ApkSigner.Builder.signApk(
input: File,
output: File,
) {
logger.info("Signing ${input.name}")

setInputApk(input)
Expand All @@ -250,7 +257,7 @@ object ApkSigner {
class KeyStoreEntry(
val alias: String,
val password: String,
val privateKeyCertificatePair: PrivateKeyCertificatePair = newPrivateKeyCertificatePair()
val privateKeyCertificatePair: PrivateKeyCertificatePair = newPrivateKeyCertificatePair(),
)

/**
Expand All @@ -263,4 +270,4 @@ object ApkSigner {
val privateKey: PrivateKey,
val certificate: X509Certificate,
)
}
}
42 changes: 25 additions & 17 deletions src/main/kotlin/app/revanced/library/ApkUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,36 @@ object ApkUtils {
* @param outputFile The apk to write the new entries to.
* @param patchedEntriesSource The result of the patcher to add the patched dex files and resources.
*/
fun copyAligned(apkFile: File, outputFile: File, patchedEntriesSource: PatcherResult) {
fun copyAligned(
apkFile: File,
outputFile: File,
patchedEntriesSource: PatcherResult,
) {
logger.info("Aligning ${apkFile.name}")

outputFile.toPath().deleteIfExists()

ZipFile(outputFile).use { file ->
patchedEntriesSource.dexFiles.forEach {
file.addEntryCompressData(
ZipEntry(it.name), it.stream.readBytes()
ZipEntry(it.name),
it.stream.readBytes(),
)
}

patchedEntriesSource.resourceFile?.let {
file.copyEntriesFromFileAligned(
ZipFile(it), ZipFile.apkZipEntryAlignment
ZipFile(it),
ZipFile.apkZipEntryAlignment,
)
}

// TODO: Do not compress result.doNotCompress

// TODO: Fix copying resources that are not needed anymore.
file.copyEntriesFromFileAligned(
ZipFile(apkFile), ZipFile.apkZipEntryAlignment
ZipFile(apkFile),
ZipFile.apkZipEntryAlignment,
)
}
}
Expand All @@ -62,26 +69,27 @@ object ApkUtils {
signingOptions: SigningOptions,
) {
// Get the keystore from the file or create a new one.
val keyStore = if (signingOptions.keyStore.exists()) {
ApkSigner.readKeyStore(signingOptions.keyStore.inputStream(), signingOptions.keyStorePassword)
} else {
val entry = ApkSigner.KeyStoreEntry(signingOptions.alias, signingOptions.password)
val keyStore =
if (signingOptions.keyStore.exists()) {
ApkSigner.readKeyStore(signingOptions.keyStore.inputStream(), signingOptions.keyStorePassword)
} else {
val entry = ApkSigner.KeyStoreEntry(signingOptions.alias, signingOptions.password)

// Create a new keystore with a new keypair and saves it.
ApkSigner.newKeyStore(listOf(entry)).also { keyStore ->
keyStore.store(
signingOptions.keyStore.outputStream(),
signingOptions.keyStorePassword?.toCharArray()
)
// Create a new keystore with a new keypair and saves it.
ApkSigner.newKeyStore(listOf(entry)).also { keyStore ->
keyStore.store(
signingOptions.keyStore.outputStream(),
signingOptions.keyStorePassword?.toCharArray(),
)
}
}
}

ApkSigner.newApkSignerBuilder(
keyStore,
signingOptions.alias,
signingOptions.password,
signingOptions.signer,
signingOptions.signer
signingOptions.signer,
).signApk(apk, output)
}

Expand All @@ -101,4 +109,4 @@ object ApkUtils {
val password: String = "",
val signer: String = "ReVanced",
)
}
}
Loading

0 comments on commit a9e5966

Please sign in to comment.