Skip to content

Commit f390dd0

Browse files
committed
feat: Support customize signing levels
1 parent fe3e1c9 commit f390dd0

File tree

4 files changed

+62
-2
lines changed

4 files changed

+62
-2
lines changed

api/android/revanced-library.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,20 @@ public final class app/revanced/library/ApkSigner$Signer {
2929
public final fun signApk (Lcom/android/tools/build/apkzlib/zip/ZFile;)V
3030
public final fun signApk (Ljava/io/File;)V
3131
public final fun signApk (Ljava/io/File;Ljava/io/File;)V
32+
public final fun signApk (Ljava/io/File;Ljava/io/File;Ljava/util/Set;)V
3233
}
3334

3435
public final class app/revanced/library/ApkUtils {
3536
public static final field INSTANCE Lapp/revanced/library/ApkUtils;
3637
public final fun applyTo (Lapp/revanced/patcher/PatcherResult;Ljava/io/File;)V
3738
public final fun newPrivateKeyCertificatePair (Lapp/revanced/library/ApkUtils$PrivateKeyCertificatePairDetails;Lapp/revanced/library/ApkUtils$KeyStoreDetails;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;
3839
public final fun readPrivateKeyCertificatePairFromKeyStore (Lapp/revanced/library/ApkUtils$KeyStoreDetails;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;
40+
public final fun readSigningLevels (Ljava/io/File;)Ljava/util/Set;
3941
public final fun sign (Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V
4042
public final fun sign (Ljava/io/File;Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V
4143
public final fun sign (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;)V
4244
public final fun signApk (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkUtils$KeyStoreDetails;)V
45+
public final fun signApk (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkUtils$KeyStoreDetails;Ljava/util/Set;)V
4346
}
4447

4548
public final class app/revanced/library/ApkUtils$KeyStoreDetails {

api/jvm/revanced-library.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,20 @@ public final class app/revanced/library/ApkSigner$Signer {
2929
public final fun signApk (Lcom/android/tools/build/apkzlib/zip/ZFile;)V
3030
public final fun signApk (Ljava/io/File;)V
3131
public final fun signApk (Ljava/io/File;Ljava/io/File;)V
32+
public final fun signApk (Ljava/io/File;Ljava/io/File;Ljava/util/Set;)V
3233
}
3334

3435
public final class app/revanced/library/ApkUtils {
3536
public static final field INSTANCE Lapp/revanced/library/ApkUtils;
3637
public final fun applyTo (Lapp/revanced/patcher/PatcherResult;Ljava/io/File;)V
3738
public final fun newPrivateKeyCertificatePair (Lapp/revanced/library/ApkUtils$PrivateKeyCertificatePairDetails;Lapp/revanced/library/ApkUtils$KeyStoreDetails;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;
3839
public final fun readPrivateKeyCertificatePairFromKeyStore (Lapp/revanced/library/ApkUtils$KeyStoreDetails;)Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;
40+
public final fun readSigningLevels (Ljava/io/File;)Ljava/util/Set;
3941
public final fun sign (Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V
4042
public final fun sign (Ljava/io/File;Ljava/io/File;Lapp/revanced/library/ApkUtils$SigningOptions;)V
4143
public final fun sign (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkSigner$PrivateKeyCertificatePair;)V
4244
public final fun signApk (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkUtils$KeyStoreDetails;)V
45+
public final fun signApk (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Lapp/revanced/library/ApkUtils$KeyStoreDetails;Ljava/util/Set;)V
4346
}
4447

4548
public final class app/revanced/library/ApkUtils$KeyStoreDetails {

src/commonMain/kotlin/app/revanced/library/ApkSigner.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,24 @@ object ApkSigner {
331331
signingExtension = null
332332
}
333333

334-
fun signApk(inputApkFile: File, outputApkFile: File) {
334+
fun signApk(inputApkFile: File, outputApkFile: File, signingLevels: Set<Int>) {
335335
logger.info("Signing APK")
336336

337+
if (signingLevels.isNotEmpty() && signerBuilder != null) {
338+
signerBuilder.setV1SigningEnabled(signingLevels.contains(1))
339+
signerBuilder.setV2SigningEnabled(signingLevels.contains(2))
340+
signerBuilder.setV3SigningEnabled(signingLevels.contains(3))
341+
signerBuilder.setV4SigningEnabled(signingLevels.contains(4))
342+
}
343+
337344
signerBuilder?.setInputApk(inputApkFile)?.setOutputApk(outputApkFile)?.build()?.sign()
338345
}
339346

347+
@Deprecated("This constructor will be removed in the future.")
348+
fun signApk(inputApkFile: File, outputApkFile: File) {
349+
signApk(inputApkFile, outputApkFile, setOf())
350+
}
351+
340352
@Deprecated("This constructor will be removed in the future.")
341353
internal constructor(signingExtension: SigningExtension) {
342354
signerBuilder = null

src/commonMain/kotlin/app/revanced/library/ApkUtils.kt

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package app.revanced.library
22

33
import app.revanced.library.ApkSigner.newPrivateKeyCertificatePair
44
import app.revanced.patcher.PatcherResult
5+
import com.android.apksig.ApkVerifier
56
import com.android.tools.build.apkzlib.zip.AlignmentRules
67
import com.android.tools.build.apkzlib.zip.StoredEntry
78
import com.android.tools.build.apkzlib.zip.ZFile
@@ -153,20 +154,40 @@ object ApkUtils {
153154
* @param outputApkFile The file to save the signed apk to.
154155
* @param signer The name of the signer.
155156
* @param keyStoreDetails The details for the keystore.
157+
* @param signingLevels Signature levels, empty to default.
156158
*/
157159
fun signApk(
158160
inputApkFile: File,
159161
outputApkFile: File,
160162
signer: String,
161163
keyStoreDetails: KeyStoreDetails,
164+
signingLevels: Set<Int>,
162165
) = ApkSigner.newApkSigner(
163166
signer,
164167
if (keyStoreDetails.keyStore.exists()) {
165168
readPrivateKeyCertificatePairFromKeyStore(keyStoreDetails)
166169
} else {
167170
newPrivateKeyCertificatePair(PrivateKeyCertificatePairDetails(), keyStoreDetails)
168171
},
169-
).signApk(inputApkFile, outputApkFile)
172+
).signApk(inputApkFile, outputApkFile, signingLevels)
173+
174+
/**
175+
* Signs [inputApkFile] with the given options and saves the signed apk to [outputApkFile].
176+
* If [KeyStoreDetails.keyStore] does not exist,
177+
* a new private key and certificate pair will be created and saved to the keystore.
178+
*
179+
* @param inputApkFile The apk file to sign.
180+
* @param outputApkFile The file to save the signed apk to.
181+
* @param signer The name of the signer.
182+
* @param keyStoreDetails The details for the keystore.
183+
*/
184+
@Deprecated("This method will be removed in the future.")
185+
fun signApk(
186+
inputApkFile: File,
187+
outputApkFile: File,
188+
signer: String,
189+
keyStoreDetails: KeyStoreDetails,
190+
) = signApk(inputApkFile, outputApkFile, signer, keyStoreDetails, setOf())
170191

171192
@Deprecated("This method will be removed in the future.")
172193
private fun readOrNewPrivateKeyCertificatePair(
@@ -235,6 +256,27 @@ object ApkUtils {
235256
readOrNewPrivateKeyCertificatePair(signingOptions),
236257
)
237258

259+
/**
260+
* Read apk signature levels.
261+
*
262+
* Note: a well-signed apk is required.
263+
*/
264+
fun readSigningLevels(apkFile: File): Set<Int> {
265+
val verify = ApkVerifier.Builder(apkFile).build().verify()
266+
if (!verify.isVerified)
267+
return setOf()
268+
val result = mutableSetOf<Int>()
269+
if (verify.v1SchemeSigners.isNotEmpty())
270+
result.add(1)
271+
if (verify.v2SchemeSigners.isNotEmpty())
272+
result.add(2)
273+
if (verify.v3SchemeSigners.isNotEmpty())
274+
result.add(3)
275+
if (verify.v4SchemeSigners.isNotEmpty())
276+
result.add(4)
277+
return result
278+
}
279+
238280
/**
239281
* Options for signing an apk.
240282
*

0 commit comments

Comments
 (0)