From 2a30845f61d5f77ded7a72ee3d6ab55b4c512d52 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 12 Mar 2024 15:44:59 +0100 Subject: [PATCH 1/9] fix: Support mounting even when Magisk is not installed --- .../kotlin/app/revanced/library/adb/Constants.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/app/revanced/library/adb/Constants.kt b/src/main/kotlin/app/revanced/library/adb/Constants.kt index ada0a2f..fcf4971 100644 --- a/src/main/kotlin/app/revanced/library/adb/Constants.kt +++ b/src/main/kotlin/app/revanced/library/adb/Constants.kt @@ -29,13 +29,17 @@ internal object Constants { internal val MOUNT_SCRIPT = """ #!/system/bin/sh - MAGISKTMP="$( magisk --path )" || MAGISKTMP=/sbin - MIRROR="${'$'}MAGISKTMP/.magisk/mirror" + + # Use Magisk mirror, if possible. + if command -v magisk &> /dev/null; then + MIRROR="${'$'}(magisk --path)/.magisk/mirror" + fi + # Wait for the system to boot. until [ "$( getprop sys.boot_completed )" = 1 ]; do sleep 3; done until [ -d "/sdcard/Android" ]; do sleep 1; done - # Unmount any existing mount as a safety measure + # Unmount any existing mount as a safety measure. $UMOUNT base_path="$PATCHED_APK_PATH" @@ -44,7 +48,7 @@ internal object Constants { chcon u:object_r:apk_data_file:s0 ${'$'}base_path mount -o bind ${'$'}MIRROR${'$'}base_path ${'$'}stock_path - # Kill the app to force it to restart the mounted APK in case it's already running + # Kill the app to force it to restart the mounted APK in case it's currently running. $KILL """.trimIndent() } From f2959b610a3ca7360607e73f628da9fedd79b65d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 12 Mar 2024 14:46:49 +0000 Subject: [PATCH 2/9] chore(release): 2.2.2-dev.1 [skip ci] ## [2.2.2-dev.1](https://github.com/ReVanced/revanced-library/compare/v2.2.1...v2.2.2-dev.1) (2024-03-12) ### Bug Fixes * Support mounting even when Magisk is not installed ([2a30845](https://github.com/ReVanced/revanced-library/commit/2a30845f61d5f77ded7a72ee3d6ab55b4c512d52)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e44c7d..3964852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [2.2.2-dev.1](https://github.com/ReVanced/revanced-library/compare/v2.2.1...v2.2.2-dev.1) (2024-03-12) + + +### Bug Fixes + +* Support mounting even when Magisk is not installed ([2a30845](https://github.com/ReVanced/revanced-library/commit/2a30845f61d5f77ded7a72ee3d6ab55b4c512d52)) + ## [2.2.1](https://github.com/ReVanced/revanced-library/compare/v2.2.0...v2.2.1) (2024-03-09) diff --git a/gradle.properties b/gradle.properties index 19e248d..3c10f19 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 2.2.1 +version = 2.2.2-dev.1 From 2df3484b68ed72338a52e76fb4b7ceb9c9c644ed Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 13 Mar 2024 23:04:35 +0100 Subject: [PATCH 3/9] feat: Add utility function around key certificate pairs --- api/revanced-library.api | 23 +- .../kotlin/app/revanced/library/ApkSigner.kt | 219 ++++++++++-------- .../kotlin/app/revanced/library/ApkUtils.kt | 156 ++++++++++--- 3 files changed, 259 insertions(+), 139 deletions(-) diff --git a/api/revanced-library.api b/api/revanced-library.api index 91e2553..8c40200 100644 --- a/api/revanced-library.api +++ b/api/revanced-library.api @@ -7,14 +7,13 @@ public final class app/revanced/library/ApkSigner { public final fun newKeyStore (Ljava/io/OutputStream;Ljava/lang/String;Ljava/util/Set;)V public final fun newKeyStore (Ljava/util/Set;)Ljava/security/KeyStore; public final fun newPrivateKeyCertificatePair (Ljava/lang/String;Ljava/util/Date;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair; - public static synthetic fun newPrivateKeyCertificatePair$default (Lapp/revanced/library/ApkSigner;Ljava/lang/String;Ljava/util/Date;ILjava/lang/Object;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair; public final fun readKeyCertificatePair (Ljava/security/KeyStore;Ljava/lang/String;Ljava/lang/String;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair; public final fun readKeyStore (Ljava/io/InputStream;Ljava/lang/String;)Ljava/security/KeyStore; + public final fun readPrivateKeyCertificatePair (Ljava/security/KeyStore;Ljava/lang/String;Ljava/lang/String;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair; } public final class app/revanced/library/ApkSigner$KeyStoreEntry { public fun (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun getAlias ()Ljava/lang/String; public final fun getPassword ()Ljava/lang/String; public final fun getPrivateKeyCertificatePair ()Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair; @@ -35,8 +34,28 @@ public final class app/revanced/library/ApkSigner$Signer { public final class app/revanced/library/ApkUtils { public static final field INSTANCE Lapp/revanced/library/ApkUtils; public final fun applyTo (Lapp/revanced/patcher/PatcherResult;Ljava/io/File;)V + public final fun newPrivateKeyCertificatePair (Lapp/revanced/library/ApkUtils$PrivateKeyCertificatePairDetails;Lapp/revanced/library/ApkUtils$KeyStoreDetails;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair; + public final fun readPrivateKeyCertificatePairFromKeyStore (Lapp/revanced/library/ApkUtils$KeyStoreDetails;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair; public final fun sign (Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V public final fun sign (Ljava/io/File;Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V + public final fun sign (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;)V +} + +public final class app/revanced/library/ApkUtils$KeyStoreDetails { + public fun (Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getAlias ()Ljava/lang/String; + public final fun getKeyStore ()Ljava/io/File; + public final fun getKeyStorePassword ()Ljava/lang/String; + public final fun getPassword ()Ljava/lang/String; +} + +public final class app/revanced/library/ApkUtils$PrivateKeyCertificatePairDetails { + public fun ()V + public fun (Ljava/lang/String;Ljava/util/Date;)V + public synthetic fun (Ljava/lang/String;Ljava/util/Date;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getCommonName ()Ljava/lang/String; + public final fun getValidUntil ()Ljava/util/Date; } public final class app/revanced/library/ApkUtils$SigningOptions { diff --git a/src/main/kotlin/app/revanced/library/ApkSigner.kt b/src/main/kotlin/app/revanced/library/ApkSigner.kt index 7faea77..35d2091 100644 --- a/src/main/kotlin/app/revanced/library/ApkSigner.kt +++ b/src/main/kotlin/app/revanced/library/ApkSigner.kt @@ -19,7 +19,6 @@ import java.security.* import java.security.cert.X509Certificate import java.util.* import java.util.logging.Logger -import kotlin.time.Duration.Companion.days /** * Utility class for reading or writing keystore files and entries as well as signing APK files. @@ -34,17 +33,80 @@ object ApkSigner { } } + private fun newKeyStoreInstance() = KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME) + /** - * Create a new [PrivateKeyCertificatePair]. + * Create a new keystore with a new keypair. + * + * @param entries The entries to add to the keystore. + * + * @return The created keystore. + * + * @see KeyStoreEntry + * @see KeyStore + */ + fun newKeyStore(entries: Set): KeyStore { + logger.fine("Creating keystore") + + return newKeyStoreInstance().apply { + load(null) + + entries.forEach { entry -> + // Add all entries to the keystore. + setKeyEntry( + entry.alias, + entry.privateKeyCertificatePair.privateKey, + entry.password.toCharArray(), + arrayOf(entry.privateKeyCertificatePair.certificate), + ) + } + } + } + + /** + * Read a keystore from the given [keyStoreInputStream]. + * + * @param keyStoreInputStream The stream to read the keystore from. + * @param keyStorePassword The password for the keystore. + * + * @return The keystore. + * + * @throws IllegalArgumentException If the keystore password is invalid. + * + * @see KeyStore + */ + fun readKeyStore( + keyStoreInputStream: InputStream, + keyStorePassword: String?, + ): KeyStore { + logger.fine("Reading keystore") + + return newKeyStoreInstance().apply { + try { + load(keyStoreInputStream, keyStorePassword?.toCharArray()) + } catch (exception: IOException) { + if (exception.cause is UnrecoverableKeyException) { + throw IllegalArgumentException("Invalid keystore password") + } else { + throw exception + } + } + } + } + + /** + * Create a new private key and certificate pair. * * @param commonName The common name of the certificate. - * @param validUntil The date until the certificate is valid. + * @param validUntil The date until which the certificate is valid. * - * @return The created [PrivateKeyCertificatePair]. + * @return The newly created private key and certificate pair. + * + * @see PrivateKeyCertificatePair */ fun newPrivateKeyCertificatePair( - commonName: String = "ReVanced", - validUntil: Date = Date(System.currentTimeMillis() + (365.days * 8).inWholeMilliseconds * 24), + commonName: String, + validUntil: Date, ): PrivateKeyCertificatePair { logger.fine("Creating certificate for $commonName") @@ -80,8 +142,11 @@ object ApkSigner { * @return The read [PrivateKeyCertificatePair]. * * @throws IllegalArgumentException If the keystore does not contain the given alias or the password is invalid. + * + * @see PrivateKeyCertificatePair + * @see KeyStore */ - fun readKeyCertificatePair( + fun readPrivateKeyCertificatePair( keyStore: KeyStore, keyStoreEntryAlias: String, keyStoreEntryPassword: String, @@ -106,80 +171,6 @@ object ApkSigner { return PrivateKeyCertificatePair(privateKey, certificate) } - /** - * Create a new keystore with a new keypair. - * - * @param entries The entries to add to the keystore. - * - * @return The created keystore. - * - * @see KeyStoreEntry - */ - fun newKeyStore(entries: Set): KeyStore { - logger.fine("Creating keystore") - - return newKeyStoreInstance().apply { - load(null) - - entries.forEach { entry -> - // Add all entries to the keystore. - setKeyEntry( - entry.alias, - entry.privateKeyCertificatePair.privateKey, - entry.password.toCharArray(), - arrayOf(entry.privateKeyCertificatePair.certificate), - ) - } - } - } - - private fun newKeyStoreInstance() = KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME) - - /** - * Create a new keystore with a new keypair and saves it to the given [keyStoreOutputStream]. - * - * @param keyStoreOutputStream The stream to write the keystore to. - * @param keyStorePassword The password for the keystore. - * @param entries The entries to add to the keystore. - */ - fun newKeyStore( - keyStoreOutputStream: OutputStream, - keyStorePassword: String, - entries: Set, - ) = newKeyStore(entries).store( - keyStoreOutputStream, - keyStorePassword.toCharArray(), - ) - - /** - * Read a keystore from the given [keyStoreInputStream]. - * - * @param keyStoreInputStream The stream to read the keystore from. - * @param keyStorePassword The password for the keystore. - * - * @return The keystore. - * - * @throws IllegalArgumentException If the keystore password is invalid. - */ - fun readKeyStore( - keyStoreInputStream: InputStream, - keyStorePassword: String?, - ): KeyStore { - logger.fine("Reading keystore") - - return newKeyStoreInstance().apply { - try { - load(keyStoreInputStream, keyStorePassword?.toCharArray()) - } catch (exception: IOException) { - if (exception.cause is UnrecoverableKeyException) { - throw IllegalArgumentException("Invalid keystore password") - } else { - throw exception - } - } - } - } - /** * Create a new [Signer]. * @@ -206,6 +197,41 @@ object ApkSigner { ), ) + /** + * Read a [PrivateKeyCertificatePair] from a keystore entry. + * + * @param keyStore The keystore to read the entry from. + * @param keyStoreEntryAlias The alias of the key store entry to read. + * @param keyStoreEntryPassword The password for recovering the signing key. + * + * @return The read [PrivateKeyCertificatePair]. + * + * @throws IllegalArgumentException If the keystore does not contain the given alias or the password is invalid. + */ + @Deprecated("This method will be removed in the future.") + fun readKeyCertificatePair( + keyStore: KeyStore, + keyStoreEntryAlias: String, + keyStoreEntryPassword: String, + ) = readPrivateKeyCertificatePair(keyStore, keyStoreEntryAlias, keyStoreEntryPassword) + + /** + * Create a new keystore with a new keypair and saves it to the given [keyStoreOutputStream]. + * + * @param keyStoreOutputStream The stream to write the keystore to. + * @param keyStorePassword The password for the keystore. + * @param entries The entries to add to the keystore. + */ + @Deprecated("This method will be removed in the future.") + fun newKeyStore( + keyStoreOutputStream: OutputStream, + keyStorePassword: String?, + entries: Set, + ) = newKeyStore(entries).store( + keyStoreOutputStream, + keyStorePassword?.toCharArray(), + ) + /** * Create a new [Signer]. * @@ -216,13 +242,7 @@ object ApkSigner { * @see PrivateKeyCertificatePair * @see Signer */ - @Suppress("DEPRECATION") - @Deprecated( - "This method will be removed in the future.", - ReplaceWith( - "newApkSigner(\"ReVanced\", privateKeyCertificatePair)", - ), - ) + @Deprecated("This method will be removed in the future.") fun newApkSigner(privateKeyCertificatePair: PrivateKeyCertificatePair) = Signer( SigningExtension( @@ -249,6 +269,7 @@ object ApkSigner { * @see KeyStore * @see Signer */ + @Deprecated("This method will be removed in the future.") fun newApkSigner( signer: String, keyStore: KeyStore, @@ -268,13 +289,7 @@ object ApkSigner { * @see KeyStore * @see Signer */ - @Deprecated( - "This method will be removed in the future.", - ReplaceWith( - "newApkSigner(\"ReVanced\", readKeyCertificatePair(keyStore, keyStoreEntryAlias, keyStoreEntryPassword))", - "app.revanced.library.ApkSigner.newApkSigner", - ), - ) + @Deprecated("This method will be removed in the future.") fun newApkSigner( keyStore: KeyStore, keyStoreEntryAlias: String, @@ -293,7 +308,7 @@ object ApkSigner { class KeyStoreEntry( val alias: String, val password: String, - val privateKeyCertificatePair: PrivateKeyCertificatePair = newPrivateKeyCertificatePair(), + val privateKeyCertificatePair: PrivateKeyCertificatePair, ) /** @@ -316,6 +331,12 @@ object ApkSigner { signingExtension = null } + fun signApk(inputApkFile: File, outputApkFile: File) { + logger.info("Signing APK") + + signerBuilder?.setInputApk(inputApkFile)?.setOutputApk(outputApkFile)?.build()?.sign() + } + @Deprecated("This constructor will be removed in the future.") internal constructor(signingExtension: SigningExtension) { signerBuilder = null @@ -344,11 +365,5 @@ object ApkSigner { signingExtension?.register(apkZFile) } - - fun signApk(inputApkFile: File, outputApkFile: File) { - logger.info("Signing APK") - - signerBuilder?.setInputApk(inputApkFile)?.setOutputApk(outputApkFile)?.build()?.sign() - } } } diff --git a/src/main/kotlin/app/revanced/library/ApkUtils.kt b/src/main/kotlin/app/revanced/library/ApkUtils.kt index ab73bc3..d098779 100644 --- a/src/main/kotlin/app/revanced/library/ApkUtils.kt +++ b/src/main/kotlin/app/revanced/library/ApkUtils.kt @@ -1,12 +1,15 @@ package app.revanced.library +import app.revanced.library.ApkSigner.newPrivateKeyCertificatePair import app.revanced.patcher.PatcherResult import com.android.tools.build.apkzlib.zip.AlignmentRules import com.android.tools.build.apkzlib.zip.StoredEntry import com.android.tools.build.apkzlib.zip.ZFile import com.android.tools.build.apkzlib.zip.ZFileOptions import java.io.File +import java.util.* import java.util.logging.Logger +import kotlin.time.Duration.Companion.days /** * Utility functions to work with APK files. @@ -93,24 +96,89 @@ object ApkUtils { } /** - * Reads an existing or creates a new keystore. + * Creates a new private key and certificate pair and saves it to the keystore in [keyStoreDetails]. * - * @param signingOptions The options to use for signing. + * @param privateKeyCertificatePairDetails The details for the private key and certificate pair. + * @param keyStoreDetails The details for the keystore. + * + * @return The newly created private key and certificate pair. */ - private fun readOrNewKeyStore(signingOptions: SigningOptions) = if (signingOptions.keyStore.exists()) { - ApkSigner.readKeyStore( - signingOptions.keyStore.inputStream(), - signingOptions.keyStorePassword ?: "", + fun newPrivateKeyCertificatePair( + privateKeyCertificatePairDetails: PrivateKeyCertificatePairDetails, + keyStoreDetails: KeyStoreDetails, + ) = newPrivateKeyCertificatePair( + privateKeyCertificatePairDetails.commonName, + privateKeyCertificatePairDetails.validUntil, + ).also { privateKeyCertificatePair -> + ApkSigner.newKeyStore( + setOf( + ApkSigner.KeyStoreEntry( + keyStoreDetails.alias, + keyStoreDetails.password, + privateKeyCertificatePair, + ), + ), + ).store( + keyStoreDetails.keyStore.outputStream(), + keyStoreDetails.keyStorePassword?.toCharArray(), ) - } else { - val entry = ApkSigner.KeyStoreEntry(signingOptions.alias, signingOptions.password) + } - // Create a new keystore with a new keypair and saves it. - ApkSigner.newKeyStore(setOf(entry)).apply { - store( - signingOptions.keyStore.outputStream(), - signingOptions.keyStorePassword?.toCharArray(), - ) + /** + * Reads the private key and certificate pair from an existing keystore. + * + * @param keyStoreDetails The details for the keystore. + * + * @return The private key and certificate pair. + */ + fun readPrivateKeyCertificatePairFromKeyStore( + keyStoreDetails: KeyStoreDetails, + ) = ApkSigner.readKeyCertificatePair( + ApkSigner.readKeyStore( + keyStoreDetails.keyStore.inputStream(), + keyStoreDetails.keyStorePassword, + ), + keyStoreDetails.alias, + keyStoreDetails.password, + ) + + /** + * Signs [inputApkFile] with the given options and saves the signed apk to [outputApkFile]. + * + * @param inputApkFile The apk file to sign. + * @param outputApkFile The file to save the signed apk to. + * @param signer The name of the signer. + * @param privateKeyCertificatePair The private key and certificate pair to use for signing. + */ + fun sign( + inputApkFile: File, + outputApkFile: File, + signer: String, + privateKeyCertificatePair: ApkSigner.PrivateKeyCertificatePair, + ) = ApkSigner.newApkSigner( + signer, + privateKeyCertificatePair, + ).signApk(inputApkFile, outputApkFile) + + @Deprecated("This method will be removed in the future.") + private fun readOrNewPrivateKeyCertificatePair( + signingOptions: SigningOptions, + ): ApkSigner.PrivateKeyCertificatePair { + val privateKeyCertificatePairDetails = PrivateKeyCertificatePairDetails( + signingOptions.alias, + PrivateKeyCertificatePairDetails().validUntil, + ) + val keyStoreDetails = KeyStoreDetails( + signingOptions.keyStore, + signingOptions.keyStorePassword, + signingOptions.alias, + signingOptions.password, + ) + + return if (keyStoreDetails.keyStore.exists()) { + readPrivateKeyCertificatePairFromKeyStore(keyStoreDetails) + } else { + newPrivateKeyCertificatePair(privateKeyCertificatePairDetails, keyStoreDetails) } } @@ -119,17 +187,11 @@ object ApkUtils { * * @param signingOptions The options to use for signing. */ - @Deprecated("Use sign(File, File, SigningOptions) instead.") - fun File.sign(signingOptions: SigningOptions) { - val keyStore = readOrNewKeyStore(signingOptions) - - @Suppress("DEPRECATION") - ApkSigner.newApkSigner( - keyStore, - signingOptions.alias, - signingOptions.password, - ).signApk(this) - } + @Deprecated("This method will be removed in the future.") + fun File.sign(signingOptions: SigningOptions) = ApkSigner.newApkSigner( + signingOptions.signer, + readOrNewPrivateKeyCertificatePair(signingOptions), + ).signApk(this) /** * Signs [inputApkFile] with the given options and saves the signed apk to [outputApkFile]. @@ -138,16 +200,13 @@ object ApkUtils { * @param outputApkFile The file to save the signed apk to. * @param signingOptions The options to use for signing. */ - fun sign(inputApkFile: File, outputApkFile: File, signingOptions: SigningOptions) { - val keyStore = readOrNewKeyStore(signingOptions) - - ApkSigner.newApkSigner( - signingOptions.signer, - keyStore, - signingOptions.alias, - signingOptions.password, - ).signApk(inputApkFile, outputApkFile) - } + @Deprecated("This method will be removed in the future.") + fun sign(inputApkFile: File, outputApkFile: File, signingOptions: SigningOptions) = sign( + inputApkFile, + outputApkFile, + signingOptions.signer, + readOrNewPrivateKeyCertificatePair(signingOptions), + ) /** * Options for signing an apk. @@ -158,6 +217,7 @@ object ApkUtils { * @param password The password for recovering the signing key. * @param signer The name of the signer. */ + @Deprecated("This class will be removed in the future.") class SigningOptions( val keyStore: File, val keyStorePassword: String?, @@ -165,4 +225,30 @@ object ApkUtils { val password: String = "", val signer: String = "ReVanced", ) + + /** + * Details for a keystore. + * + * @param keyStore The file to save the keystore to. + * @param keyStorePassword The password for the keystore. + * @param alias The alias of the key store entry to use for signing. + * @param password The password for recovering the signing key. + */ + class KeyStoreDetails( + val keyStore: File, + val keyStorePassword: String? = null, + val alias: String = "ReVanced Key", + val password: String = "", + ) + + /** + * Details for a private key and certificate pair. + * + * @param commonName The common name for the certificate saved in the keystore. + * @param validUntil The date until which the certificate is valid. + */ + class PrivateKeyCertificatePairDetails( + val commonName: String = "ReVanced", + val validUntil: Date = Date(System.currentTimeMillis() + (365.days * 8).inWholeMilliseconds * 24), + ) } From 13b6a846d78cc46437b1b63e0835ba334759745b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 13 Mar 2024 22:06:34 +0000 Subject: [PATCH 4/9] chore(release): 2.3.0-dev.1 [skip ci] # [2.3.0-dev.1](https://github.com/ReVanced/revanced-library/compare/v2.2.2-dev.1...v2.3.0-dev.1) (2024-03-13) ### Features * Add utility function around key certificate pairs ([2df3484](https://github.com/ReVanced/revanced-library/commit/2df3484b68ed72338a52e76fb4b7ceb9c9c644ed)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3964852..5a3e6c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.3.0-dev.1](https://github.com/ReVanced/revanced-library/compare/v2.2.2-dev.1...v2.3.0-dev.1) (2024-03-13) + + +### Features + +* Add utility function around key certificate pairs ([2df3484](https://github.com/ReVanced/revanced-library/commit/2df3484b68ed72338a52e76fb4b7ceb9c9c644ed)) + ## [2.2.2-dev.1](https://github.com/ReVanced/revanced-library/compare/v2.2.1...v2.2.2-dev.1) (2024-03-12) diff --git a/gradle.properties b/gradle.properties index 3c10f19..927372f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 2.2.2-dev.1 +version = 2.3.0-dev.1 From 80e35270c4af1d3de72e3162e8f6e6d1e28c34f5 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 14 Mar 2024 12:21:47 +0100 Subject: [PATCH 5/9] build: Publish sources --- build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 25048b2..0de3754 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -54,6 +54,8 @@ kotlin { java { targetCompatibility = JavaVersion.VERSION_11 + + withSourcesJar() } publishing { From 4c6a6360cf83659d1f5c3a7c5710ac54426e9235 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 14 Mar 2024 12:39:01 +0100 Subject: [PATCH 6/9] feat: Simplify signing utility API --- api/revanced-library.api | 1 + .../kotlin/app/revanced/library/ApkUtils.kt | 37 ++++++++++++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/api/revanced-library.api b/api/revanced-library.api index 8c40200..54f5e86 100644 --- a/api/revanced-library.api +++ b/api/revanced-library.api @@ -39,6 +39,7 @@ public final class app/revanced/library/ApkUtils { public final fun sign (Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V public final fun sign (Ljava/io/File;Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V public final fun sign (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;)V + public final fun signApk (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkUtils$KeyStoreDetails;)V } public final class app/revanced/library/ApkUtils$KeyStoreDetails { diff --git a/src/main/kotlin/app/revanced/library/ApkUtils.kt b/src/main/kotlin/app/revanced/library/ApkUtils.kt index d098779..b56c62c 100644 --- a/src/main/kotlin/app/revanced/library/ApkUtils.kt +++ b/src/main/kotlin/app/revanced/library/ApkUtils.kt @@ -103,6 +103,7 @@ object ApkUtils { * * @return The newly created private key and certificate pair. */ + @Deprecated("This method will be removed in the future.") fun newPrivateKeyCertificatePair( privateKeyCertificatePairDetails: PrivateKeyCertificatePairDetails, keyStoreDetails: KeyStoreDetails, @@ -131,9 +132,10 @@ object ApkUtils { * * @return The private key and certificate pair. */ + @Deprecated("This method will be removed in the future.") fun readPrivateKeyCertificatePairFromKeyStore( keyStoreDetails: KeyStoreDetails, - ) = ApkSigner.readKeyCertificatePair( + ) = ApkSigner.readPrivateKeyCertificatePair( ApkSigner.readKeyStore( keyStoreDetails.keyStore.inputStream(), keyStoreDetails.keyStorePassword, @@ -144,20 +146,26 @@ object ApkUtils { /** * Signs [inputApkFile] with the given options and saves the signed apk to [outputApkFile]. + * If [KeyStoreDetails.keyStore] does not exist, + * a new private key and certificate pair will be created and saved to the keystore. * * @param inputApkFile The apk file to sign. * @param outputApkFile The file to save the signed apk to. * @param signer The name of the signer. - * @param privateKeyCertificatePair The private key and certificate pair to use for signing. + * @param keyStoreDetails The details for the keystore. */ - fun sign( + fun signApk( inputApkFile: File, outputApkFile: File, signer: String, - privateKeyCertificatePair: ApkSigner.PrivateKeyCertificatePair, + keyStoreDetails: KeyStoreDetails, ) = ApkSigner.newApkSigner( signer, - privateKeyCertificatePair, + if (keyStoreDetails.keyStore.exists()) { + readPrivateKeyCertificatePairFromKeyStore(keyStoreDetails) + } else { + newPrivateKeyCertificatePair(PrivateKeyCertificatePairDetails(), keyStoreDetails) + }, ).signApk(inputApkFile, outputApkFile) @Deprecated("This method will be removed in the future.") @@ -182,6 +190,25 @@ object ApkUtils { } } + /** + * Signs [inputApkFile] with the given options and saves the signed apk to [outputApkFile]. + * + * @param inputApkFile The apk file to sign. + * @param outputApkFile The file to save the signed apk to. + * @param signer The name of the signer. + * @param privateKeyCertificatePair The private key and certificate pair to use for signing. + */ + @Deprecated("This method will be removed in the future.") + fun sign( + inputApkFile: File, + outputApkFile: File, + signer: String, + privateKeyCertificatePair: ApkSigner.PrivateKeyCertificatePair, + ) = ApkSigner.newApkSigner( + signer, + privateKeyCertificatePair, + ).signApk(inputApkFile, outputApkFile) + /** * Signs the apk file with the given options. * From af0aba4a8e53060a8ffa79d1d96dfb53d5ca03c9 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 14 Mar 2024 11:40:37 +0000 Subject: [PATCH 7/9] chore(release): 2.3.0-dev.2 [skip ci] # [2.3.0-dev.2](https://github.com/ReVanced/revanced-library/compare/v2.3.0-dev.1...v2.3.0-dev.2) (2024-03-14) ### Features * Simplify signing utility API ([4c6a636](https://github.com/ReVanced/revanced-library/commit/4c6a6360cf83659d1f5c3a7c5710ac54426e9235)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a3e6c3..dea250d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.3.0-dev.2](https://github.com/ReVanced/revanced-library/compare/v2.3.0-dev.1...v2.3.0-dev.2) (2024-03-14) + + +### Features + +* Simplify signing utility API ([4c6a636](https://github.com/ReVanced/revanced-library/commit/4c6a6360cf83659d1f5c3a7c5710ac54426e9235)) + # [2.3.0-dev.1](https://github.com/ReVanced/revanced-library/compare/v2.2.2-dev.1...v2.3.0-dev.1) (2024-03-13) diff --git a/gradle.properties b/gradle.properties index 927372f..4c738eb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 2.3.0-dev.1 +version = 2.3.0-dev.2 From b15efa41f8dc7d73865d0eab15be274b9ee3d7a3 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 14 Mar 2024 12:45:36 +0100 Subject: [PATCH 8/9] feat: Improve exception message --- src/main/kotlin/app/revanced/library/ApkSigner.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/library/ApkSigner.kt b/src/main/kotlin/app/revanced/library/ApkSigner.kt index 35d2091..b653fe4 100644 --- a/src/main/kotlin/app/revanced/library/ApkSigner.kt +++ b/src/main/kotlin/app/revanced/library/ApkSigner.kt @@ -154,7 +154,7 @@ object ApkSigner { logger.fine("Reading key and certificate pair from keystore entry $keyStoreEntryAlias") if (!keyStore.containsAlias(keyStoreEntryAlias)) { - throw IllegalArgumentException("Keystore does not contain alias $keyStoreEntryAlias") + throw IllegalArgumentException("Keystore does not contain entry with alias $keyStoreEntryAlias") } // Read the private key and certificate from the keystore. From 8e4d5765e17b14f9316c5c158912e91cfdb698c1 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 14 Mar 2024 11:51:48 +0000 Subject: [PATCH 9/9] chore(release): 2.3.0-dev.3 [skip ci] # [2.3.0-dev.3](https://github.com/ReVanced/revanced-library/compare/v2.3.0-dev.2...v2.3.0-dev.3) (2024-03-14) ### Features * Improve exception message ([b15efa4](https://github.com/ReVanced/revanced-library/commit/b15efa41f8dc7d73865d0eab15be274b9ee3d7a3)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dea250d..7beca88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [2.3.0-dev.3](https://github.com/ReVanced/revanced-library/compare/v2.3.0-dev.2...v2.3.0-dev.3) (2024-03-14) + + +### Features + +* Improve exception message ([b15efa4](https://github.com/ReVanced/revanced-library/commit/b15efa41f8dc7d73865d0eab15be274b9ee3d7a3)) + # [2.3.0-dev.2](https://github.com/ReVanced/revanced-library/compare/v2.3.0-dev.1...v2.3.0-dev.2) (2024-03-14) diff --git a/gradle.properties b/gradle.properties index 4c738eb..16e087b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 2.3.0-dev.2 +version = 2.3.0-dev.3