From ad8e5b631aed6c8a78caaf238747b3d24302531b Mon Sep 17 00:00:00 2001 From: Tad Date: Sun, 9 Jul 2023 14:49:49 -0400 Subject: [PATCH] 16.0+17.1: Extra July ASB backport from @MSe1969 Signed-off-by: Tad --- .../360973-backport-prereq.patch | 53 + .../360973-backport.patch | 1447 +++++++++++++++++ .../360973-backport-prereq.patch | 53 + .../360973-backport.patch | 125 +- Scripts/LineageOS-16.0/Patch.sh | 5 + Scripts/LineageOS-17.1/Patch.sh | 7 +- 6 files changed, 1620 insertions(+), 70 deletions(-) create mode 100644 Patches/LineageOS-16.0/android_tools_apksig/360973-backport-prereq.patch create mode 100644 Patches/LineageOS-16.0/android_tools_apksig/360973-backport.patch create mode 100644 Patches/LineageOS-17.1/android_tools_apksig/360973-backport-prereq.patch diff --git a/Patches/LineageOS-16.0/android_tools_apksig/360973-backport-prereq.patch b/Patches/LineageOS-16.0/android_tools_apksig/360973-backport-prereq.patch new file mode 100644 index 00000000..5194e448 --- /dev/null +++ b/Patches/LineageOS-16.0/android_tools_apksig/360973-backport-prereq.patch @@ -0,0 +1,53 @@ +From 011adec1a494974102930bf65a8d2fdfa8b375b5 Mon Sep 17 00:00:00 2001 +From: Khaled Abdelmohsen +Date: Mon, 24 Feb 2020 16:59:21 +0000 +Subject: [PATCH 1/2] Create source stamp verifier + +Bug: 148005911 +Test: gradlew test +Change-Id: I7008c9567ad5e8b63e7f6ba192d38b10c5c9a2dc +Merged-In: I7008c9567ad5e8b63e7f6ba192d38b10c5c9a2dc +(cherry picked from commit a3970357d65d59b70c6ccf2c5c55000cb4310953) +--- + .../internal/apk/ApkSigningBlockUtils.java | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java b/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java +index 2330f6d..f15597b 100644 +--- a/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java ++++ b/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java +@@ -998,6 +998,20 @@ public class ApkSigningBlockUtils { + return false; + } + ++ public boolean containsWarnings() { ++ if (!mWarnings.isEmpty()) { ++ return true; ++ } ++ if (!signers.isEmpty()) { ++ for (SignerInfo signer : signers) { ++ if (signer.containsWarnings()) { ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ + public void addError(ApkVerifier.Issue msg, Object... parameters) { + mErrors.add(new ApkVerifier.IssueWithParams(msg, parameters)); + } +@@ -1042,6 +1056,10 @@ public class ApkSigningBlockUtils { + return !mErrors.isEmpty(); + } + ++ public boolean containsWarnings() { ++ return !mWarnings.isEmpty(); ++ } ++ + public List getErrors() { + return mErrors; + } +-- +2.30.2 + diff --git a/Patches/LineageOS-16.0/android_tools_apksig/360973-backport.patch b/Patches/LineageOS-16.0/android_tools_apksig/360973-backport.patch new file mode 100644 index 00000000..ef02af06 --- /dev/null +++ b/Patches/LineageOS-16.0/android_tools_apksig/360973-backport.patch @@ -0,0 +1,1447 @@ +From 9a80527425030dae7f962ab95eda500a720cde47 Mon Sep 17 00:00:00 2001 +From: Michael Groover +Date: Fri, 31 Mar 2023 14:30:21 -0500 +Subject: [PATCH 2/2] Limit the number of supported v1 and v2 signers + +The v1 and v2 APK Signature Schemes support multiple signers; this +was intended to allow multiple entities to sign an APK. Previously, +there were no limits placed on the number of signers that could +sign an APK, but this commit sets a hard limit of 10 supported +signers for these signature schemes to ensure a large number of +signers does not place undue burden on the platform. + +Bug: 266580022 +Test: gradlew test +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ea0632935646f2f6bf5822a5e9c97885269780bd) +Merged-In: I77f4218599511ff4f9f3790e4942a329d5a18da4 +Change-Id: I77f4218599511ff4f9f3790e4942a329d5a18da4 + +Change-Id: I604ce656e6dcd750e664adcb814c5c66f7b80ce1 +--- + .../java/com/android/apksig/ApkVerifier.java | 29 +++++ + .../internal/apk/v1/V1SchemeSigner.java | 7 ++ + .../internal/apk/v1/V1SchemeVerifier.java | 7 ++ + .../internal/apk/v2/V2SchemeSigner.java | 6 ++ + .../internal/apk/v2/V2SchemeVerifier.java | 4 + + .../com/android/apksig/ApkSignerTest.java | 100 ++++++++++++++++++ + .../com/android/apksig/ApkVerifierTest.java | 31 ++++++ + .../com/android/apksig/v1-only-10-signers.apk | Bin 0 -> 18389 bytes + .../com/android/apksig/v1-only-11-signers.apk | Bin 0 -> 22297 bytes + .../com/android/apksig/v2-only-10-signers.apk | Bin 0 -> 20688 bytes + .../com/android/apksig/v2-only-11-signers.apk | Bin 0 -> 24784 bytes + 11 files changed, 184 insertions(+) + create mode 100644 src/test/resources/com/android/apksig/v1-only-10-signers.apk + create mode 100644 src/test/resources/com/android/apksig/v1-only-11-signers.apk + create mode 100644 src/test/resources/com/android/apksig/v2-only-10-signers.apk + create mode 100644 src/test/resources/com/android/apksig/v2-only-11-signers.apk + +diff --git a/src/main/java/com/android/apksig/ApkVerifier.java b/src/main/java/com/android/apksig/ApkVerifier.java +index 5e458ef..62b132a 100644 +--- a/src/main/java/com/android/apksig/ApkVerifier.java ++++ b/src/main/java/com/android/apksig/ApkVerifier.java +@@ -620,6 +620,15 @@ public class ApkVerifier { + } + + private void mergeFrom(ApkSigningBlockUtils.Result source) { ++ if (source == null) { ++ return; ++ } ++ if (source.containsErrors()) { ++ mErrors.addAll(source.getErrors()); ++ } ++ if (source.containsWarnings()) { ++ mWarnings.addAll(source.getWarnings()); ++ } + switch (source.signatureSchemeVersion) { + case ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V2: + mVerifiedUsingV2Scheme = source.verified; +@@ -897,6 +906,16 @@ public class ApkVerifier { + */ + JAR_SIG_NO_SIGNATURES("No JAR signatures"), + ++ /** ++ * APK signature scheme v1 has exceeded the maximum number of jar signers. ++ *
    ++ *
  • Parameter 1: maximum allowed signers ({@code Integer})
  • ++ *
  • Parameter 2: total number of signers ({@code Integer})
  • ++ *
++ */ ++ JAR_SIG_MAX_SIGNATURES_EXCEEDED( ++ "APK Signature Scheme v1 only supports a maximum of %1$d signers, found %2$d"), ++ + /** + * APK does not contain any entries covered by JAR signatures. + */ +@@ -1325,6 +1344,16 @@ public class ApkVerifier { + "APK Signature Scheme v2 signature %1$s indicates the APK is signed using %2$s but " + + "no such signature was found. Signature stripped?"), + ++ /** ++ * APK signature scheme v2 has exceeded the maximum number of signers. ++ *
    ++ *
  • Parameter 1: maximum allowed signers ({@code Integer})
  • ++ *
  • Parameter 2: total number of signers ({@code Integer})
  • ++ *
++ */ ++ V2_SIG_MAX_SIGNATURES_EXCEEDED( ++ "APK Signature Scheme V2 only supports a maximum of %1$d signers, found %2$d"), ++ + /** + * APK Signature Scheme v2 signature contains no signers. + */ +diff --git a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java +index f900211..05721ed 100644 +--- a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java ++++ b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java +@@ -246,9 +246,16 @@ public abstract class V1SchemeSigner { + String createdBy) + throws NoSuchAlgorithmException, ApkFormatException, InvalidKeyException, + CertificateException, SignatureException { ++ ++ int MAX_APK_SIGNERS = 10; + if (signerConfigs.isEmpty()) { + throw new IllegalArgumentException("At least one signer config must be provided"); + } ++ if (signerConfigs.size() > MAX_APK_SIGNERS) { ++ throw new IllegalArgumentException( ++ "APK Signature Scheme v1 only supports a maximum of " + MAX_APK_SIGNERS + ", " ++ + signerConfigs.size() + " provided"); ++ } + OutputManifestFile manifest = + generateManifestFile( + jarEntryDigestAlgorithm, jarEntryDigests, sourceManifestBytes); +diff --git a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java +index a828bcc..8e49dd3 100644 +--- a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java ++++ b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java +@@ -16,6 +16,7 @@ + + package com.android.apksig.internal.apk.v1; + ++ + import com.android.apksig.ApkVerifier.Issue; + import com.android.apksig.ApkVerifier.IssueWithParams; + import com.android.apksig.apk.ApkFormatException; +@@ -249,6 +250,7 @@ public abstract class V1SchemeVerifier { + // * All JAR entries listed in JAR manifest are present in the APK. + + // Identify signers ++ int MAX_APK_SIGNERS = 10; + List signers = new ArrayList<>(sigBlockEntries.size()); + for (CentralDirectoryRecord sigBlockEntry : sigBlockEntries) { + String sigBlockEntryName = sigBlockEntry.getName(); +@@ -277,6 +279,11 @@ public abstract class V1SchemeVerifier { + result.addError(Issue.JAR_SIG_NO_SIGNATURES); + return; + } ++ if (signers.size() > MAX_APK_SIGNERS) { ++ result.addError(Issue.JAR_SIG_MAX_SIGNATURES_EXCEEDED, MAX_APK_SIGNERS, ++ signers.size()); ++ return; ++ } + + // Verify each signer's signature block file .(RSA|DSA|EC) against the corresponding + // signature file .SF. Any error encountered for any signer terminates verification, to +diff --git a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java +index 6d001e7..375ff91 100644 +--- a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java ++++ b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java +@@ -161,6 +161,12 @@ public abstract class V2SchemeSigner { + throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { + // FORMAT: + // * length-prefixed sequence of length-prefixed signer blocks. ++ int MAX_APK_SIGNERS = 10; ++ if (signerConfigs.size() > MAX_APK_SIGNERS) { ++ throw new IllegalArgumentException( ++ "APK Signature Scheme v2 only supports a maximum of " + MAX_APK_SIGNERS + ", " ++ + signerConfigs.size() + " provided"); ++ } + + List signerBlocks = new ArrayList<>(signerConfigs.size()); + int signerNumber = 0; +diff --git a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java +index e1be06e..39b205b 100644 +--- a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java ++++ b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java +@@ -180,6 +180,7 @@ public abstract class V2SchemeVerifier { + int maxSdkVersion, + ApkSigningBlockUtils.Result result) throws NoSuchAlgorithmException { + ByteBuffer signers; ++ int MAX_APK_SIGNERS = 10; + try { + signers = ApkSigningBlockUtils.getLengthPrefixedSlice(apkSignatureSchemeV2Block); + } catch (ApkFormatException e) { +@@ -221,6 +222,9 @@ public abstract class V2SchemeVerifier { + return; + } + } ++ if (signerCount > MAX_APK_SIGNERS) { ++ result.addError(Issue.V2_SIG_MAX_SIGNATURES_EXCEEDED, MAX_APK_SIGNERS, signerCount); ++ } + } + + /** +diff --git a/src/test/java/com/android/apksig/ApkSignerTest.java b/src/test/java/com/android/apksig/ApkSignerTest.java +index 80f35ba..ccdb02a 100644 +--- a/src/test/java/com/android/apksig/ApkSignerTest.java ++++ b/src/test/java/com/android/apksig/ApkSignerTest.java +@@ -339,6 +339,106 @@ public class ApkSignerTest { + } catch (ApkFormatException expected) {} + } + ++ @Test ++ public void testV1SigningAllowedWithMaximumNumberOfSigners() throws Exception { ++ // The APK Signature Scheme v1 supports a maximum of 10 signers; this test verifies a ++ // signing config with the maximum number of signers is allowed to sign the APK. ++ List signers = List.of( ++ getDefaultSignerConfigFromResources("dsa-1024"), ++ getDefaultSignerConfigFromResources("dsa-2048"), ++ getDefaultSignerConfigFromResources("dsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-1024"), ++ getDefaultSignerConfigFromResources("rsa-2048"), ++ getDefaultSignerConfigFromResources("rsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-4096"), ++ getDefaultSignerConfigFromResources("rsa-8192"), ++ getDefaultSignerConfigFromResources("ec-p256"), ++ getDefaultSignerConfigFromResources("ec-p384") ++ ); ++ sign("original.apk", ++ new ApkSigner.Builder(signers) ++ .setV1SigningEnabled(true) ++ .setV2SigningEnabled(false) ++ .setV3SigningEnabled(false) ++ .setV4SigningEnabled(false)); ++ } ++ ++ @Test ++ public void testV1SigningRejectedWithMoreThanMaximumNumberOfSigners() throws Exception { ++ // This test ensures a v1 signing config with more than the maximum supported number ++ // of signers will fail to sign. ++ List signers = List.of( ++ getDefaultSignerConfigFromResources("dsa-1024"), ++ getDefaultSignerConfigFromResources("dsa-2048"), ++ getDefaultSignerConfigFromResources("dsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-1024"), ++ getDefaultSignerConfigFromResources("rsa-2048"), ++ getDefaultSignerConfigFromResources("rsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-4096"), ++ getDefaultSignerConfigFromResources("rsa-8192"), ++ getDefaultSignerConfigFromResources("ec-p256"), ++ getDefaultSignerConfigFromResources("ec-p384"), ++ getDefaultSignerConfigFromResources("ec-p521") ++ ); ++ assertThrows(IllegalArgumentException.class, () -> ++ sign("original.apk", ++ new ApkSigner.Builder(signers) ++ .setV1SigningEnabled(true) ++ .setV2SigningEnabled(false) ++ .setV3SigningEnabled(false) ++ .setV4SigningEnabled(false))); ++ } ++ ++ @Test ++ public void testV2SigningAllowedWithMaximumNumberOfSigners() throws Exception { ++ // The APK Signature Scheme v2 supports a maximum of 10 signers; this test verifies a ++ // signing config with the maximum number of signers is allowed to sign the APK. ++ List signers = List.of( ++ getDefaultSignerConfigFromResources("dsa-1024"), ++ getDefaultSignerConfigFromResources("dsa-2048"), ++ getDefaultSignerConfigFromResources("dsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-1024"), ++ getDefaultSignerConfigFromResources("rsa-2048"), ++ getDefaultSignerConfigFromResources("rsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-4096"), ++ getDefaultSignerConfigFromResources("rsa-8192"), ++ getDefaultSignerConfigFromResources("ec-p256"), ++ getDefaultSignerConfigFromResources("ec-p384") ++ ); ++ sign("original.apk", ++ new ApkSigner.Builder(signers) ++ .setV1SigningEnabled(false) ++ .setV2SigningEnabled(true) ++ .setV3SigningEnabled(false) ++ .setV4SigningEnabled(false)); ++ } ++ ++ @Test ++ public void testV2SigningRejectedWithMoreThanMaximumNumberOfSigners() throws Exception { ++ // This test ensures a v2 signing config with more than the maximum supported number ++ // of signers will fail to sign. ++ List signers = List.of( ++ getDefaultSignerConfigFromResources("dsa-1024"), ++ getDefaultSignerConfigFromResources("dsa-2048"), ++ getDefaultSignerConfigFromResources("dsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-1024"), ++ getDefaultSignerConfigFromResources("rsa-2048"), ++ getDefaultSignerConfigFromResources("rsa-3072"), ++ getDefaultSignerConfigFromResources("rsa-4096"), ++ getDefaultSignerConfigFromResources("rsa-8192"), ++ getDefaultSignerConfigFromResources("ec-p256"), ++ getDefaultSignerConfigFromResources("ec-p384"), ++ getDefaultSignerConfigFromResources("ec-p521") ++ ); ++ assertThrows(IllegalArgumentException.class, () -> ++ sign("original.apk", ++ new ApkSigner.Builder(signers) ++ .setV1SigningEnabled(false) ++ .setV2SigningEnabled(true) ++ .setV3SigningEnabled(false) ++ .setV4SigningEnabled(false))); ++ } ++ + @Test + public void testWeirdZipCompressionMethod() throws Exception { + // Any ZIP compression method other than STORED is treated as DEFLATED by Android. +diff --git a/src/test/java/com/android/apksig/ApkVerifierTest.java b/src/test/java/com/android/apksig/ApkVerifierTest.java +index 6f6c04d..0546f0f 100644 +--- a/src/test/java/com/android/apksig/ApkVerifierTest.java ++++ b/src/test/java/com/android/apksig/ApkVerifierTest.java +@@ -239,6 +239,20 @@ public class ApkVerifierTest { + "v1-only-with-dsa-sha256-2.16.840.1.101.3.4.3.2-%s.apk", DSA_KEY_NAMES); + } + ++ @Test ++ public void testV1MaxSupportedSignersAccepted() throws Exception { ++ // The APK Signature Scheme V1 supports a maximum of 10 signers; this test ensures an ++ // APK signed with that many signers successfully verifies. ++ assertVerified(verify("v1-only-10-signers.apk")); ++ } ++ ++ @Test ++ public void testV1MoreThanMaxSupportedSignersRejected() throws Exception { ++ // This test ensure an APK signed with more than the supported number of signers fails ++ // to verify. ++ assertVerificationFailure("v1-only-11-signers.apk", Issue.JAR_SIG_MAX_SIGNATURES_EXCEEDED); ++ } ++ + @Test + public void testV2StrippedRejected() throws Exception { + // APK signed with v1 and v2 schemes, but v2 signature was stripped from the file (by using +@@ -471,6 +485,23 @@ public class ApkVerifierTest { + Issue.V2_SIG_NO_SUPPORTED_SIGNATURES); + } + ++ @Test ++ public void testV2MaxSupportedSignersAccepted() throws Exception { ++ // The APK Signature Scheme v2 supports a maximum of 10 signers; this test ensures an ++ // APK signed with that many signers successfully verifies. ++ assertVerified(verifyForMinSdkVersion("v2-only-10-signers.apk", AndroidSdkVersion.N)); ++ } ++ ++ @Test ++ public void testV2MoreThanMaxSupportedSignersRejected() throws Exception { ++ // This test ensure an APK signed with more than the supported number of signers fails ++ // to verify. ++ assertVerificationFailure( ++ verifyForMinSdkVersion("v2-only-11-signers.apk", AndroidSdkVersion.N), ++ Issue.V2_SIG_MAX_SIGNATURES_EXCEEDED); ++ } ++ ++ + @Test + public void testCorrectCertUsedFromPkcs7SignedDataCertsSet() throws Exception { + // Obtained by prepending the rsa-1024 certificate to the PKCS#7 SignedData certificates set +diff --git a/src/test/resources/com/android/apksig/v1-only-10-signers.apk b/src/test/resources/com/android/apksig/v1-only-10-signers.apk +new file mode 100644 +index 0000000000000000000000000000000000000000..198beeb651079d24338984de7f32e8e0c7b4ff78 +GIT binary patch +literal 18389 +zcmeIabyQr-5-&VB!9s#da0$WP-9mssa0%}2?(P=c-Q9x+_rcwQ1ef3rZ*nxrJ?DJq +ze($fh*6mrnT4wfd*RI{w)m>FR(&7-1Z~y=-0F($h2tN);c|rgH-!c*a5@4-oV_|2l +zqh~{-Wo@JLFaQ960}y`s77X-zFaR!~0#t&2{A&VrzWluoDp5dL5R{RT<&4ao2>2~6 +z3G^+j2?XV20R+^l-C3Pwot2#}1f71Jt(~m|Js&#jx?>4C1G=-iGYBlq^$2VoEC_53 +zt@ZTO00ew%o)K%FW#53-JWD_gf?qp8pg*)hH~66qy4kPoZ*+kZfOUZb03M*K7Qh^! +z3$O-Q0E|E-4XAAi`q%*U06G9WP`?qt7T^Tx*8!C_pwbr9V-D*1^>^RE{@+dnpmzmg +z1wal|etVbS(zo}?1S-Gv|B^soko;Z;l`x2ftpt|MCpo>A}FT?bo@b%1<`2XAce2@R_8U6`h%UVg`{|5gXPozQeiVA>*{dQkMj_=XF +zNgKbpuC;}cuB4W^k-nadEsdj@X_#D-ISM~2cT+N(KS>Xtw@xotFe)sC3HVC_Ar$cE +zuf4#9;5c+rG__Jgc~9 +zjNnItmF|v*EztbP!{M@O@oXf}P3Km^l{7qXMTj1NhYZt2zQ%bReI<yZX7jzat(dIt3q2LBw{RHDL6tCdzd{E$f8q6F0uQl- +zaX|r-Xy%Ll`fY~-?!0-IqAg3qJ5N{>-Etd@HE8o)iZaUTffbX*^7T4_SKGzb5p`*4 +z9~=$dnC-IE5W8qQrAFT^vz2Oj%2Pgc){G=Xpz4wRfXw$Y`PWF>e{xHxbDn +z3>eCk7#2(VDcpr+d*h--rhDO84x#WYj&?Pq#bICpC+b@EpfMW={ZGRd9yDxq +zOtoxmKuShe&oL}U(hxLUdsoc$S&fowqt)cdp8*DS|(Uq1_f%?i|%Ka=kAA%OLMBemAf${9_D7@M?FZ*kG` +z*qrK?=)`WoGtX;@px}YVW6(nG6XIY_>*naNzVJrds)R|7{RtT#7GN_!oQ&V?2GLWE +z;GSL=ZLC`f;uHSa=Uk`*!Wu|wQJl_p?D_bY@A;RBSE9HHJ*xvF76tGKEF#li!vJ@L +z8Tw!ufZ52@huHWnx50Jh{TASV5#$x9rwQ4_>#?TUApG9$%13z2#$sI0qA$?FdE +zX&qM)?{2qae8!4mrpjf04G{O0 +zJ1{;~FBu7ej7oYu=e@H?zB8%q;1g`e=Bdncp}x`>){1YqgEUm$#?7bNid{?*9@N{5 +z8D1(H#9$bm*}i$^%AhiKwlCAegATGPE+k`1du+0%lL7D#wj +zha@Szd_HVAdMOmj=TKRsCeyI7jPSYW=-mk64v87nQjF&JWX8_dt>0z~CtVVHms>@R +zvBLzuL?%gPkGJW?d4o~F?c$hm)MrIUyNbU#0(fE@^&ICIci_eAo0{E?s-dlzIiM4b +zYaSIIGSB*rrkqjb+Gl0>-b`_Ezx7TZN2TLD$@f`nSpl_&F`1%gkUR60jLJAUXXvFa +z^=WXqfpMK-c2Euxc^XY`;+~8h!nmw_YEmSbO;jTbZ-ZQ>3x7a%D$^9CEw~hD$;9`^ +zb|&(2)?mt5#*r+z?3ES(K6B9!7gvKJqnj9~1-8XSItfXQPnTY_ZsE-bfc(t)&@bwyH$ +zQ^cY}e%Rh0aLwCgB3DuBUo{T9YDD->DAsCHtacvth}w=EHpbhPv+rBt>r1oUp46OY~05J~q)WC@Qwy6DKp$iXUY{ +z!G|m_jPLzN&%~gpprGhgjX^3}k>hM^=oHg^KEEw0r36G@L@30oxdcJw1Sd9`U=%w< +z#83%@jV>p|VT8~yL`2E3Awg%=i0ANtpFul`KPsA_Su0g_TiS3@iJ* +zVb0HZxnwYeAA)OmqY18eM(s~apImPF&AG9o4Y*|P$8)YPlmx)nn@@SL?sX01M%OKB +z2RiD0U3EW9^;cwAFe#}wce8!@==wQVv8r~W4ktl9J+3xwIHER1gGX#V>7=~$DF5hn +z+HmsMR-l!?WO(F;D^~uvBqH9aGu8k#?Gnq%2+6=G&qC_u)#7HNlUwlt_Bfm`EBagZ +z;mKKPk~TjNS^MRIpqXp$L+Fhgw98!zp&_-?DalLM)bQNbW3E%{qVNq&Xn3hyS4&p< +z={0>lg(J%^!reBSxXK(fa7P-WWpCflxU!=UFwt7pPR-FW3N)#r)3mgn33V+6=J%S_ +zt0pfdRZOlO`qnPYJla23ztK(a%qnOOS+Hpe%VXzqb>+(sX{huA+YVhL7LSv>+TU?q +zG#THmORYS_j;(g_-B>5_JEBf5vN>9aMR-b?TnAD2$YamStQgYfmQrwkC7U)^x3Rb^ +zrWNgwo=$f>`lw0?IbK$EF>=zNkIaxCVo-Lz{G^uMg~4T?H+5quvF*{V=s0KQ^iU{& +zzoC_spD4eSkKM9;EoT!=l}zK2%GK1$(<|MJijG6?TB%D(=;o=a)!745>_`ks!i|E( +zz3D|mkpaR6|M&pab7*bES+uX7sIb))*mR5x529~0hi(v{IV6ZqyikJm&F=1aPbqH& +z-)h}!7ZT%cB?#@3La-dP5K)oN;2l`Y)xXcM7g#Xrl=0El++~selr#`2ORuskYMGd* +zgr#)GHx13)+t6l!%FWi`y4z(UUS5gaYksKrJgDOB1Z?XaeHl$29SL!}s=q~a9OQ3{ +z&)-GoA7>y2IwrRN%|QQV1~L)~7TEx8eW;=SVg~w!jla%7Q@TIQK=K0_LGq#hFawD< +z^P`9}Av02I>TBz2ujwk~$J>74o95<(c*|m+(P4v5H3Z$^?+txtI+RH@#Dz=I9n>fS +zO@CM1I6hoZIJbSu#_O1Rh!)^!z*MjKO~7ThBX*Y;9(@hrN> +zpyBEU0x5A%<5Q{D8aDMvD&=>I%vM^u*0r8yDzSu=%H$k-4QXQ79BWtzttSr)QuB}K;pKKYdnD5jj +zx9L$DX!?il4n`=-%HzGiZCv|WL-t@RnYM|P__|bq{Q7!Ee%X2nNa^@2Uv^S?+L~*Y +z`qN?Y>b^mJgvtEK6`G+Mv3-ENQFYnDAjCyHE&ims{cAz4dxyPKp=%`n5~$kJ51%ZxD<`TxLu5U@w}@GCf9NZhM_aSybUw(wkj&~e?Ag=gh4 +zIv`sh>o&E2y$9xcgu0P8Fp=IKSg*g&5mTcm-D4vbua*4(OxpHWMFhvUWrHw9xR6S9 +zbGO;fN$+PcQCl#uaA7|-?~cPS-mFxAt(xbo-M_0(JtnK*j<^?(5B%IfW%Tu=n_45n +zEdXJvXh3)%(%Z_KU-#u>y8la`VV% +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 +z_DLu*e2MNaKG( +z^lyY{*tuAK7bHYnAR+p}to{cZf03dp%^#&`0whJT|0G43ASt3jhNt~aind{wC|!&u +z$mIWx6rn?J`uF&6lKJO-GscJzl!3*V5NN;DB>;?dKAA$X&_y;P80tY{i4S^a48};z +zS&ae_QZhmjmsLBlGS}=h(lpLuB>t%~Sbu%kDYxA~!~JsJIbG|rY(ExkMCEz8&C$E~ +zx6fnMif;`)o}ViFRY4~fHPF0y`kOdW$NVBrg(;4*$wBK8;+Kkblt)qzk6Bh6G|PN= +zB&9<{S_IPs*21$)ItDdfhV@YbtHpR*k7FeUZ!y2OTq1$%KZS-+B!fC1n!>3c;ys(n +zIq7Q@8~mWB_=q^3XqV&?Uw67U!x(`D%Rs^K{>>FNC2iWN&22d(@UZQb|0%aJ2Jd}S +zq}CiSMQPY6?+~NuKE2^SWKWnESDmGBICyA*j~^~2LT8eVKx2C+nc2@=N{ePks^k8zoO$2(E&OCuKf3xB#8!{ +zCSl?zVI~PSD4oY(!B$lINa|_p>P(sIYDsIq)z)lqCu*?GZ!ukkj6R$u4jG|)yKFw_ +zG`6;s#dtEJ3*<1qdt*HE=p?DEr2B;yQC@Xo?i^@lXFnluo@RzD@z7RmCn(h0HnS{c +zK5~8hFt{teYb}cwZq|0<5HDPQU)4XvsNH&8@*Y?7vjG9TZ3q>92xds%Wi=1H2JS)h +z6i|(AsYBmK@3Q?i5&DF{NDuu9L?!e-oFgBcud)(i0v6UIaR8DHnGZj9G-2oC^?c=? +zszIL}US$3KM1~?0yWM!0xIIprS>*z-XszC&NPj5RZ4jSU-X*{Dd|0K-AFAMs_BM2W +zZYYuJtng+`5tcZK`}IBjvZ1lZ(Pm#qZT-q(>;A&xR;Q~==Sm?DG+GBy{c}VdMI5Fw +zKufYr+Va3Y5w8C`^e@#UqX+epoP6{b%1P7WP+VOmeJ+~X|_X16UG;=XV#OP +zR`le@p^cCGL87gkSa|AY=N#)(g-sp*pbr0IF~rP3|37W`Z?qwv#7Dn8ketGRyrX}~ +z#b0DqU;hVXxC4^a2^f%XK+qjRodxL2^0Y@zADv7@0UE;GSD*(DW#6V9cMgT8;U$tR`S%VgDej*jU2f%PJF)1zA%E24@gtN-kRJ>&O^d +zobCD45vion@NT`CV8$B-ro(Ak|&mWB8`C;aK=Z@^)$Ohg^;4!{sIi +z4koKRZ2eV>rqLaGKKW54<5U_Qcm?#kkhC9JjfPq +zlRX_f{oVb-{2AFm{k;vw;A#N5A_+}dTwhUz+tD!#^_w>~sd0mk)mZr^dFqz~;>N*E +zcIq6pySxxZ50V1+eaDjC1*B4Hygw;4B=CNj_WZGOb>tg#QaRPk#^Ct@=ohs{&_eI=SPP^lEXPR!Cu$$!P1eD +zkFr9$+2>OukEav|>bLZ}=Jf;eE_Iv(r*RsL>MY%wH`t09=~QZEM;5&5`Hm-R7yG@5 +z`?+E1Zo(w2<;(wmYe;Yf&^`zmR1mw941mz!W%YU#DQ~_-{jed-s$OXktrNBg2 +zQ(KFG9B5*wuW4#(XsB&$u8l+^8s#5fqC@UCVc2Y6O|<11+s=-44KogAR_t{H3S#9+tgwTzq2t +zqvMgiq-p035fPSh`pg>k4YzxIk6lhqMODvku^$Ru%u+Nt0*s=cOKBbTJGAXx2ixDY +zP^sH{TsIQ$I6QK+m_N4(VMRw%&Ck!z@#rnG%i`=s)#z!#lSN+~d(Twcq1mk{h7^Xd +zHTTNN4+Y6lx!m2-!>HN0*2!@yLMj3dh2gm}IfMGwfxtQSv4hwy0$SaQgOJD-=*|z6?Iz +zNyjb&BW99PUGXkb8j9&NR}(vz`&;|uWSn#wQrE35GDIK7q?W@HvuAJ1ZmR9{xjbwg +zHN!*j`uBxa7g<{NfGt63ULm?L!E* +z!4k!WC6cAO2W2f&R!w`Yd(`Jbfld6L2I^!7eZ^&`LdX65i!3yc7I>DTjRE=Na~t48 +z<>NLPG%$>I3XbgXOc_T#C#TxHnld8E>i$w??{lZeIwg7Ez2m`@jrn>_&CVuc-BEQ> +zigArOFdNuPEh&zejM?I~1ALJni-1~@r%;3Il@cvIK_`wv?DNF}`tqUhfq!en$~4_- +zRZHi-`_oP?x)E7^8(WKQI#$sau8Fq`yc?U~QELt81J8`$eWTSEB(z+5HWM(8Gk4oX +zJAEWfkX$z-rdVt53(plxU1YDYm%)e2lRaWscx1&K`v=!`Uev4+J-or|pIzd@ML~M?3UiBWzH+2S +zOx#ogWqETr!Af}MDB$8`nWCIkt!(Jdalm}3ClAe-^u>sK8rL@cdi&Ak%{!Xu=sXis +z*$Zx>N2@V4?#tX%cv2kwT}X?MH%!N!-O_nIb9)g=D&4)tGa`jhs)NlSkF+Dfe=|EX +z(Xs!}9Qd#HSy}oaY#gAF{XkIukJ?B8`pPsInNCC3=3^sT#2nF +z42?{1>@G4$3$le_jTMW-U&BtJ7mnKXa_knp$}%je@n<%bi^&2`56@@Fuifno0rwy5 +zZ?9=^n +z77i75#;?czq=qN3J!8zd(O>D_#QM1sf?*)bRnuK-5V-99c_eT?Bb#S+oi +zW;Erlep78mTpK1Qt`^2frV*LTAqi}R!5Vt#K;ckhs8FGGFv)-uJNzOXZ?;UZ#qxv? +zocHX#>*%bOa&A+~4v#l&=2}?J>HbhMwxFf)8o{RV(&|gGCxVIk-X}w!p=acaRrfLz +zje4-k6(WV{gU9A)gI|cEHkYTl9x)$973xRWNwkzDG0dBNnS8}a5i}R7zl&g*(mmIRYXKG9O+$j6IYun=ZS +zWj7)`^rHuUk$z`o7#OL>Ht~x@gYjybtyO*-pJh!t-P(KiCg3YiWYRI}i?r)sEiMNp +zlB#ei+P$6vpgFknI3R$zsXi2ioko^kTL%?$T8z9^F$u=rGCex+e>3A$aZ#C~qdFj^ +z7-Ld6zb^VR_kog)O}t8@t9pr2B-_mt_%%XFt9b3)LZ$9w*BtLrMHAq35b?D!h*%;V3xg +zD74&sNcaa50{GYPbr|mR(#6;OjlQh+qas$Pp@mJX1t(@D(0x8t8%OY6ZBL{&7{#_lM +zxGd4z%<-*ie3y=M;nooRGc3vpDbQ?SyQ-olN-+y!R@$j>)6`$=BK4l=(zL@h3mSTf+>+W +zn6@z&+?SYVeyno!g^!3KRznxn+wed52!@72ZgOoIuA|9_jJ+y`%4OzZd-^~+_MVHk +zw&aVcN!hW|GxN^;phUMFl^iCwUF@;8N|Oc`M)$di}UD=w*VO<|H>bC?Vvc?-j-Fa@4b=HbnYTtK#6V|cp +z8|6Hd4er{_zaVu;KTWS%R6^6c37JcRjL)`GM6P4G3BG$zm!;*LYH5*FgO;u(7bj25 +z!?P9ZMSUJAtH$v_tT0$h;$`xsk#LWT+C0;TlDGmJ)tihO{rFGu3G7TStKNz9ol3B2>j +zYU>V#fh%c!ebAU-o6MI%)zXYbI)pY?IJ*&$9b-6i_XD5@JsB$XR;Y!RDM_GL9|D79~WK(%)rw*xD2u9){B5YYmr*erTT)yIjG>lddNfB +zJbhV76KGCj+oLQZ=C?Q)OcV(5DQjHuyjOmL7msnFw~lkksn`FVEEco1F>shS?LOY& +z(xlajIVIX|;Bt#j=lRham=n8fGY68L +z6VoI-YTC+OPiO~@a2-OLneHCzFoD$hfKob%a#hTiF#fuNcv3$R1Ruu_Y3L@sA4o-# +zDiL~E5J;T`^$KHxs+fYY$kXy|IJV9??wyYATU`ztF5U5k_=zG_ZKKUT_{jj^)L%bS +z^?#`i&Ib5A8i{HhB2|UR2mQ>F4*^>24h9mA;xmU3m?9zEVm-1igyj|bEPO8DA>2LY +z2xD21fS|HJy4}oY^z|qd*qh*V_B|8N0Er8}S0^%TIaK|Px=`&*>?@5;fDbZr+EV1Y)=BQ6%yAsLx5QoCzY0HFquez&9oahEoomIj +zPreA1Z3Je3FMi1n=w(?9jUe`BA0{$8Q3h{_1M1-K(mJ9X;;?_dCrVh6;k)Ow3(5B; +zOfByYgX)Hc-_#@b!b}xpSyxbbE1IMpy3>{}|HgHH{)ludE3PPN4pTlf`7nlri0P$i^J-2NUfmtIJM#TJc*zrdpO3FLLv-)mOd)=SGR+1p1Np2s;|*a?kmf}dy{o5ySpWgWz?7)w9j +z^T=v?^3y_h3KIfUf(BoF2$D8{F0wWj`-pfg`wf-H&BdXu;h9C=-AgA4nh(>wxnDS~W(xf`i&7mX@brTki^n@S +zqnjNl-{9DU3)P5gyM~$o(dxfe+T(@#if-uyFit}?x}A_U5O2aja#%k@FXKAGd9B(V +z&DI5BFqhCyNi!8L)+x@8;ajx0_aQ7lm^P`(#!Nv5&wy*kZl8@iYL?*a4IUy23CXe` +zRce-{lH9G2=!%YDH&jk!s@m#Y@4`|K+SEx)&_Ds|ImdLLJaqrC6~+Vynw7LDV|)-I +z*WKq=T@%Bi`mYZQc8p+g%YVQEO?2z}YIGauj5(-+oumR7za +zO)Ov@*F}*oK1t*c6RRhTMrwrDA*OH7o^Ss$Gi^rv3Po~G7#B*y_|uaKPt#czEjFpt +z&3&~IJncPR6UEAkY30eN`Yh&80twDWAv2Lb;+G3!g@@#{dA=r)K$-?-`Nx| +z4CG$C(bsvxx1mYAE@y8l+3#BKoej88Zd^CzfXcZLtaaalUE%0|WDd;$JW)-oAK60; +zmscMF16Hi%b3Z2W6M*>~uSgzUAchKwJFMPSsLLPa&+lic{G*bhD{{NDox^DBfM28o^lm7%#kf7*`5kpoXpDb0Hw? +z#V)?1j|?=sD_uVkUI}v3t+A)$;vJLqdUGH9}iNWs00w&~R=-7F)5AV5!pp +zP{JxswSB^;lpSVhgV{Y-E;xb|nOgBRH>HiiNoP3rc2Mx^!*HiiXQzPs9@i16Q)oyw +zLNdxG-M7tH%hh`rNkX+T6oPz<_^^+B7Sxi)RRLaMFT@Uotw+?l2d= +zT4;O2>bxg-h=Gde0qRGUDKus_dJhWrc?a^g|DZA@`QM6(2+PXRNQ&qUNs9aO0X$cm +zK6`vsqH-^7Y!rauWieJ}Mx<`)`Ygdxz{tRuw@^Mp^m29&{wNyYy@HHk?1$MKa}`{O +zRfS3q3F&R@_<)qA-#i~49K;vusopSvY3Q6I6cZK$R_Q)dMIugt8Cebq$q=k{LTNHM +zIyk^?mso*+!TDGUu?AW_c3OBTz(>JF#^#RE0VLJf< +zd^SU%LeoEiI&%vIW9J=Fr$!>FE7jKVb!y>~bN=wjH3TV5RWkCC7;DW|dpH=pCt2K% +z_u1w3x*JJeg7?sVFgm%{q50dLmjl@^#-1;VET{NOEk)db*aZd-2l)FxX8`f;yY!!b +z)$r|lR1jRGNyIqF%JZKH{~tvBI1n6gzk~QQ`0i&KevUNz +zlZKWTe*qvY_%p!Yzl$dP{{;9Jy7V)`&v80`k^oNlR|x-1!;f6RBmN2D*VvAqN%%RC +z;ZG8DN&W)hzoB4&>?eRzm_Vu=2)5dJG7*x7%A_#46edGGQk +w5uTv`>G**YzwcyzevY42;-3(veBVKQry!-pp+HkF0DuYlkbr8*{NGyt2buzz&Hw-a + +literal 0 +HcmV?d00001 + +diff --git a/src/test/resources/com/android/apksig/v1-only-11-signers.apk b/src/test/resources/com/android/apksig/v1-only-11-signers.apk +new file mode 100644 +index 0000000000000000000000000000000000000000..95e6c61e2f6f1b75c0941c21a8e728d60821894a +GIT binary patch +literal 22297 +zcmeIaWpo@#5-uv1EV3*nTMQO6Gc&U+W@fUOEoLT*(PCz1W@biaU`sGBPS6BU45k6bu>&2nq<0@YwL`2c^A0fq;Hwcpxw!TLU{Q2U|S@ +zJ1QMpJH3}dARrJR*k8T{23!vegbh>H`Fz99Uy4k#f384OIv-rg1n0>aMT*2L22m)}qT`hUgv +zQNabYe@#$OI@Z=&mO2&&09+6RAOye{zh3*JjSOi2xZjUHupcFe1dukM{IyR8P-g+; +z|G(*%ferXEp!{W+{wI6`OBLS#_CCMI|M4IG6TXhE3g77{Dxq{g*`M?*tHqanKip=foY$;irFy#MHBcQ)D`Q$dM-UyeY +z_#Q8U7amHcCjqKJyPk{9b;Ii2*cW%bM+rBg@Goluv_KyaAiGI6+0SF{1hL=wBh-s6 +z6KEnrc6;3kJ>eP_E(@S>R+k6DGu=NY4;SowJao>Fci~dkPoKJ^td(}Iz|Xll)=h9@ +z>oCH!cxc97+AaHNtK=Hc1h3b4Wq$tVQy11@j)*lHqsM3CNR!F7QTOBfzUtEnC4vkZ +zyRdlTXH$a4aq~C#5YLBd)a3#~rs5U+V^ndc*<)Xr^lC{Y4qx>G=!eao-(Rq+X^EX) +zh)_@R^O?mk-VD_3I~8!|ExH!%SsOojL7C~7*`aMhSRQ^XC9fJ>Gg~g(s^ufwFSd=S +zO;3+@HWITqWU3}`)pbdWd0J&w?C1P)?$j^#sa_orBMd)@~ZI=u7yO>}MO*PorrQ@6%12CkvxAvEh8Qj`dArW) +zrscIc%{|G5)rf16+ZtBM6NSsDg~T_+$&%XL*=cJ@OxLD_L4oxRF%JgNZhkm1uloa> +zmj>=Ltv<>`j|ylz&eeJ@_z7M$7^N^)R|n=|0_i8-Rf4rBPCT!wFA>XpA8@TAGejUq +z4+QD@q3D7`@z4;0x1)yo9rWKc1TFJ_z>f&}6rzHb2R-XOgjxowLkMCUCYys2M6Nc& +zZYjUD*OdWif6BcduJ6i!L`-e6SR0kc!NF=#sMK +zM4R4uXN5n-(1)Yb+*iQ;N^r;(^>9~QH1`&NO*%9K@xH_s#OH9o18p56ijg9hQ3Ocb +zPvOM$QnO?%1S~4~^_u(1D&@(nrjv)i1Cy&F&z15{YeXlZ;R(!GbssyQVlQqvRdC4Q +zD0XC}Xb6pNd~W~tebZ*|s%pnvdi8y_s=~wOfzbg2}gdK4msh +z6ReP5ND&CrSQG5}u*A>`I9;8;p7q<%P;cPujsd-~k3z&c#~yqy@=$%aT{*lLyD;iP +z<(5bB0fB4lL0iG3Vsl*;rY}=m+<&Xf*IDH}Px4dNW>#R$X>6wO71+UI1-&X(&K2r6 +z*Sd7*+%NH6VGiI<5qVloV)1V#P9a^_+MARK=aV#u!`r}CX~JI+TuQb1sS9rTS~770 +zFhApaf7W97x{4)PaN8%tH~P+1OI%z7l9*;{l6tf)KGH=%dUEQbAuA&wmW!p#BuPHi +zgn;roi^S^!k}pp9>b&iT49(93Cc*qrT>p|Gz}ydL;;~t=E)k&sG>#V_|4^cmf(pEp +zqEbTC0`k0+v@~=KRPsU=qvBRRJV0RU>~CJZ^{{;Lg>ncvzsppElS3m%q^u}94e>iB +zKs|j9GeMfVVM^*^t|I6|{1TwU*b^F4R2_RR6GN1sgG(cqcB)A#?HHsYI9^3@5?@;+ +z4L3s|JnWC@6OC=zAs4xUR7ci0;-(ehH-sW%E+zv! +z1n`sISXWACYufbE_;GZof3*5*5bHD`M+QYrM6P)ygwbb?_|nED`3FVCb$DTAM%wTq +zO)2>j=Y{cns`p9?iV6yf+0YuIpcXpM#)L>UKj!h@qfkkN^MeD2yIV-)S50(bkqbt0 +zfP)K_fZgtPfg6Dh4TFP|3>$`n%j$NK427eB9m)K3oScka2VB84Y%GK;99~!vr9-!N +z%pLam9XE#@n&3-tHFpf|{lU27<+nGtd;SaVtSE!7na2t2TT3N@Fm;wQp3FzxgSj!a +z%er5j^}la;oTddR(=C~m)LFXQlfJsG=PFm$Ox0o~YG%aOq>n_@q-t@AZY5uoeLKrP +z6G!97 +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 +z+bS*?E$ow+nNbavl}Pi5M8K1cC5&#J;?k +zF?e0C_lp%r>PGzzA0q3Xr@ksPusTeJi92GoSyU{I7H!s96&Vhvxewt`E4t=)U5}`h +z27njr=yB=NgoI9I4~pg%h~sCXkU+4zN1$W5ih*-M@i(fxDdCe|8;8!Pj3 +zv#H14cXq=$lrnVty+`WX6n*xM6YmDLJ&mCxqZ>Mm?$!Ep=8y`aEhPo*PVZORGergQ +zLAh*&Y7VqfCkeFc3ze%Dg`}1(oAo)%UeLBx4?rBjfALDmNJslWb@+GGq4Sq_p9=wU +z3ISLj{kIwK2N!>lRYToBXv2dlzyhc%V0D1s15}e~)Q{kmxo_?8juZS?#SpTFzPDa(b +z_UZm{9;wv1@!|IQ`SJ1T`SE^IvDCTl`S#9n?7^O*e4AQtAT0KI6=ESKr4u1k2!q{T +zCcwf)_rqWq<{o$hYU=#=or#@D`J<4R%Oi!;EAce>fE6#X|=V)UO4YM|N +z80kLI_#ML(WGXCJV5YP8R7^Q=NZVV_|2y{Y1VQKY`*zvW(cOYovY;87=S+?~gqe%sxo1+2W +z#->I<$^XPPqRvECF8QeX(@Vw(iw6C5qq3%){PH!r(b(DWbKyC0aNQ^;r_-20HrT5& +zF^P~ye&>#s(e@38zNp$W*>d@O!4|iZbej51`m;J1yg%Km2FY}*sg?ob(s}GCeHDeD +z208`m8Ei!5J)xsv$K*+Zkv|M3lO~NZ2aE(B#KpWWG%KDqA+8EoC0#j#BL+h)=(9cb +z$n>jA()5QE%A>)E9cI=hi}mXfN%ECEP1}p?;Zv8e4U?obCHk~B*W@kW*GeQT;wASj +zrib3<;#`x-Z7-t3(JJsH>@>!jBGj>s23kG2G0GrrlJM>A!x1*Eb(e|Wr5(L`KDUN4 +zuft5p8GldgsoWLm>8Al_Ep*g#S691L&|JuPa(2VA#W(+9e)z+So*W>6;(yDRe>Z@F +z<4waeAz=CP3n2f&!Tc{a0xAHj)8vl<6uE!^iroJgK%oT)pvVBI^tWjLoFlH1Ft?Wt +zke}fvAr<@k;igH +zj%QzyLl%1E==KfwvMXt)uDs=t2VAuO@kBXDjN}0RC +zJW5XMO0}>kAI6nQ)n2l(yu!Uzgya<-PN>Jq#}ftTNWjY3JvAsP%G>6j(FyzdzeFc= +zC)tO9A5t2sL${2|Ef3G5780ab;l7PlGK``@Fl#UMg3RGb^q=uciaO_3^P}_iNj`TS +z9J7#=?oM!()>6)xyPG<=J>EMeA!eu1lD=~On#wz*wSL$QqenAIjrN^pJCdTjPo?5MA7TJqv@eIo|3f^;D9_!5F?wDNJ= +z8s1vdle~r@tGc7cBWk^nZx^SxfilI(P8r^d)k(TF1v`0iLi+`bgP@a~P-m}l5*=;%H7 +zv>)W6nh@u=v9#D{U=;0eOi3+qZ|{OcZ8o3|zB7UGi_u(?&~feEO+-7-JnRte@|7@y +zciWAaVXk>DyjK3^Du0K$3Nlib;u*`tB`@kcFx1Ac@)#oMoB#UwmW1lcY$0Emb9!Oc +z(Q@;#^ay+p=fK$Z%b5xbv+!YDt1I8~P4y=Ji`a*O`4tXqBzQ71^gZImim_@@adQcz +z)!mUq8^O7=z?+NJk7djnrNd9ogO)43c_^kt@5emSIreF{I?iq%WT|Fj^32TTZ#eN^ +zZ6-80Z*$XNh_DO~!K~^Z7|y$TWb%3!jv`dldiqS~gbKmchnfM)($2X5&FsuT!}>pu +z;NLQ}vJ695*Z^_+UjX^vX6Ikn2$-EMVqIvKg0On+++-bc-WeSk7uvbH5!g%_o0wra +z+(}u=m(H +zb~(y^#&HS!5x=4{i;aPNF&Rt&tT*S&6PTQUkB$r}Ca@S(NaIw=*HvpE2oxVL-B+kg +z3FvY-IUryWZ+HDp9T{{9OmBEVxUW9B +zjnC_-<~F4saQRSYZieMt9uKEr@>`p3;_jNRY>BT5h +ziWH;`o>-g@elLvNT$b*3#&{N0Xc*xj(NdaBw`j35O-BDQXd%>a6<$D%DUZ-b{#%cn +zCa%XTJ<=HBGh^?oh)GzdjT4&gP;OPiHK#DnYxIZ%dvNM}6l)K&#j$0R%Cymw*XrKu +zB9jIBWNi!w%agwyHzH1}j4lUV^~obgGk@Fecw7#VWxB0zjPxYJ`SKnVsD(=DgAf<( +z_=$g{|5Yg(TAHa{!ZQ9)f`)c$rT_N2yjhofN8iyDOvQy<23lQ_ZXMb3>X#%UH4bG5 +zkr^NqCl4+sSYUVcm!h!C$Zz+yLB;G=V^V5n!I*pIXBPotb1vmK6{&jagVM^eW`&De +z!lbz`GobEA;@RK!!0fjulFkJLi+ +zZxd%b3fMZA$eJ&f@4Ib3di0Q(F5*KUc-mA#^ftV=QZD?cd7{Xi{;!Tk_(qOHQL!Ij=4Nd(Ffo;d{?biqCsY9mI-xN3=k&~% +zkX$>WmN&qmEDCGXl$IH^?Ji2@a6~&@C7025NRb|&rgE6KCQJsbf$?oWOdua1+GSm}B7bx2zkdkpT=k3kJe&>U +z*2B9beM&n^t6o$>)wc_lONfBOvQ|W*XT1w@_)L?f^Eu7hD!CdZLq{QAk${V9FV36t +zI#OPP?S(*TsD{wnY^M?Lh=bBH)0do}9241xm=g8;R08F&^;_Z*W{B#LLblgl*CCNv +zg^)E`qrPFyz5b&tC7(lnVpm`}5N}aji$iRiQk5gM-WfH74V#MSXNqKyt}~mxrw<=H +zy4G@MJipvoMZa)&0YSssa_>$aw-`xSU2jBAAXPY3;XsyQHZM~p9TLL5bOa|IedS&j +z#ad4)(P_JKO^rc%Nky3`eHpyu9S%;=43Ykr0C{CBkvL!$ohMdpLkwqn8v%YBKMv2^Y~FgHvNom+M$Woig!$y95hg)#3-lkl~ddJ(0;NrtBX&R=J-|!43lKJ +za{AT1xJ+iHd=;|tOIK(>PiO2-W}|;~J9TBEersyh1?f&QVp=6jIh))CBP^p81h=&w3PBgDUQr(>jB|hn54Jf*kn?pW}-JLXG|1 +zFg-*r=Pi+%Myy*zqbQRm{V +zH=BLEA5M|Aj35U5irrt#x?=AQ%?v=a8iz7UeH&{PE7B;KDEsgPgwh +z)EnA~C0GlaZlQm~Jc28IJ*bjFs9G7j6UJLxkU-=w1ncV@osMeO7fmFTTmjq51WWXp +z-=HuysFEQVgCsrQj&1Ln?b+q*xz+Ww;no93fEPbf-9E-5+FuR`T2thmdH|^|2n*2q +zcqFoIh;$_!55zlb9#{y`CrB{pkLzp#z{+^g%XJ8Tpw@S&^DwzUFX0}sXK1U+xVRMq +zF&!4Z<09kWz+%A}tVd>Eff6@7WEXNQdQcI48xl5P*)1O~_{U)^gEd@8CbyU!I}h#3AthXhb6L$o`qyUVlxv +z&z0g}>R4rB3S@|p-Tq^)Tdm{~(gNG5M@#(8Gg;N$CR5;`Nq+& +zAj>=XfqhKNp%DZ=tRwgq7pfo)@uPY;ht$qUr&z4(&-jUJay-xM4k7tIcxh!lVcAtmM)wQi27+BkFgDwFsHGfdSR(2@F)ZDnMhl4@ +zb{0x0~Ct0+AB +z3a{z$_kia_rfF;}^ewIQqRd>h1PvA-U$f2jD?$v6*q}|Zq1ea>(Wfgze9kpR1Rmr7f)K`c@%JlvKbtsgER6 +ze38T(CR&FV1K$XvM?l+=z1XocH)}yah9tQlhz%}b+WuzB%Y2?mhebMV_gG`>gYFTx +znQ}$>tm<@BT^3_IU*czz5D31qUU5af+LSIcK?8=G0h(`}l$D6HvUbHwgSj_ihI(&! +zwzUbi6dcVZ2i)p>vVopc8n?{Zz;kZ+YdrR#*4PGK8AHDUy-`o98#{svSJWH>9xdO@ +z=X_1(#Rc{~Uz0q$feRH7ciMO=*Hk>qUp&sz#Lf#e0Mne}RnsvlKQ4jGZr^mzM2S~) +z;HoN_&F4x~Y^`I1bGNH|$@rq_S$w!LGlsTVpCGt#8vhNZKm$|F_l8fD$(Y;98Koezjfg#&~xBRT^zAio@(R&cpE*2FLddKW&1Z&Ua6ag+58;GZxfCwF!Mj +z>|)OoVS8Cm{4@O)B&r9j6sym34T%K?Rj_Rl6{!lMK_j_|SuDjS{NG##M!2Dg;LmAy6udaFW{@U37(G?gs^noQAuEes&3b?sXfJzJvf{!6PPb(wAz+ +zSgkrjOBSe!{m9R=j05$`V?`-xS{dja_FnW<&~{9tTQSzOqDG?Ven_sj)rLr}T34go +zNAyLe$kszLn&(g4ff5rO?}o9o`- +zVLA%@7x4c=WwOw+{x8b+Z<+Zf8nsV6Z~!wOkpIoh|Amb|RA#&j1F|_*;0QVrZAc~I +zkV;iAtnRTYU!{SlBc>{!BN^Rlg&)3almU8{x#&UysUd}b0G-|%37%^2=$z}Q(`a4l +z?bx12>6-g#o5vpCCN8ZuY9UKk{d=f&WP}J`KU|wgAY33XA3Qv5)C3m(b_*c{g!XPP +z{pYt(?OTZvku1BMgzyZ$MqnUbJg5N?JO&)9uy3E)Z>74 +z1x6<;T-S%2$kmyzo1SxQQ9$tLbe!NOwev-lf#9k?ru%9{100RtbzPZMT!rO`Q%+>- +z!@!3~f&<~|4D+^@!@9Ms;@f*{RB6)4w_48%7IB{bwUolEM{CY(I%30@dsXoXb?IA} +z>)*KN2vaD->{4A<)4A*3x9RK~shwTs*5>-OY{lQ>?P@3t!5c+JD|l>!FIKH*C-8@G +zLPYqJ$)j9zo}7!l!u6@QHf^Jaoi3Je +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 + +literal 0 +HcmV?d00001 + +diff --git a/src/test/resources/com/android/apksig/v2-only-10-signers.apk b/src/test/resources/com/android/apksig/v2-only-10-signers.apk +new file mode 100644 +index 0000000000000000000000000000000000000000..ad34c14ced8a53dd4c5cbe18a147de6e99264bda +GIT binary patch +literal 20688 +zcmeHv1z1(hy8kXxK)NJ0-MHy)6r>SQxq#^Uh*a4$J?+osI*7*$H{h+hHD-qrq+LhCl1-G{| +zgS)ud!(A+#%*^yaaPbAdm<7Lzi-8vW%76m=TLm!aPi5c+Kb3)-eJfu)7X%J|4grCD +zflDKh9mo{q1hNNN0y#TSb^!jIL1rKmkSkDc3335>0QDw7?hNEEK#d(x^R3;*VE?xh +z9GEMB6(DsWznII5bTOaYKz>pGH347He!m8C6o6nbBNrDZ5Hhl}i<70@ov(dZf%@-b +zTwK6`^7n*_YUJQxU}t1&28;{A24MqVd~bVE#s|t5_q(WrUE~l2kRgzNuTuf8`2qT` +zrmw&TIs^GvnEuuHW_Fqq|LT2y9RK1s{MGnIPMVVc&iEHRQ32!?AB2i}abGIIA4j{8 +zHVHdZCwog%MI$>)b2Dcbc6VEwDD@^gJPCY}rZoN#+HUaxlOEx4d{icD2qRn?4}vS} +z50OR}G)Xr!N>6Nwet?dSPK56bA~5J6Qc+deBWLn+-X3}$U(H6m;oh_I)@#eeoSZ5~ +z0t;28D;c%O@QJ9P*E@Th;jnuqpB236qQmB-IY1QHD9;%dgm&YPu94vcV?U9bq0z@h +zdG2>~{S@#d~~~I#BeUY2Cdr$wO4fG-K=|TfMS-HFe(p2jgUK!S*|( +zwkOTh)611iPPe>5ny^fs?%V95>2_XO&y#f^;_>mch_xJT9lH17xTkjO^_gmY99 +z{h1Zb(-9lAW8|}S?W98_GGV) +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 +zHb)ceoaJ*xUO6e3FQ;hU{o-@RnK9|Z)TV>R> +zj?HqYxC~y!W+hH85Bunlzt&Cos@tb%Q##{>o231zNN;>O-6xrpnLc#!c6SRKg@Ehp +z*eF|xb%^y#ll}HFr)hg~&bx)!hBiSM%1FGiZ$lPJdbo0`MtkW|c;I6rV_Ec;60V{s +zP47hf=mKAN6n=zMHx!8FPtiz?d=yIHi$zDR6h_ZBZhD&)e&0(<9Cv#-jA=;c5tWp` +z=UoG{AzvF3m*J%{J(>8LD+@U%uJL@mZoMB`Oe?xWd+|N9`6RRvi<|Pnopt+HlaIy( +zK6a!r_q8zL9aBbpn(GzJ(yQ`sj46*;k3c7VRn*gR?Xx*IJJreH;hHSku?<O~h +z%b4ycU6q*Gb~EeU7eWkWPGDFO6+3%620xoA>O6-nt*%tty<)SIg~Vx3SYm71vmh=&5QxPhB5p^?sBSQ3TMv*T07B4T3(UFJ#H%>W>?NY=KPcaOS~?kTAu>)aE5yR +zs(F;%Qgo)b=hIhu;+It4<$Gdd()eb-%L?Kx*%uCrWG*GSD}}tv?p=@Lx3QA1A3qvM +zdZ3u}M)2dzUFh2T{e87;QfI>C$qM7z#OsXWjKr?nHf8l6_ufz-TtEUiD4%iLW&`F% +z_e!up%@PV}boTUfH9YeYtU?cm#C839tX17WlQ8(}Nt_^ymID*42sux6!(~Of +zG%os{{JG(FxGCpqE8w?%O}}#Hocz&o-N+*2mp{F1x!ag^H++h5+-Q=^h__&bDW7>T +z83MQSIlU}S!U&=H)IG&Ce>6J#yxziKiz2mx7FxxrT$x~|5ob1mHPj6 +zrEUf6DpUcX)&F#+fifIWpZ{z}!UgE#@GT^31B7L9zB|)>m+KWjo3A(_(2-Fub|ge# +zPzVB-0~>+$ZA${h%!JJW@RomYrn!0e5kEN7--^HNqlLix7LyZ!fd4i;6pR9u1i=an +za73v4Z{WoSqLguLv1F~`MYtQ3neo0<${C6st!;gmP=_%SO_-@(DEN?K=j1MD3f(i5 +z$esWf6zG(6?c~NEY}+^(XSFZ +za?7fzHYz8Y*wg^S$D=lvy>qEm_h+3~%_iudPffC!7>s1B+;qlC$bXxgr*kpX{~VjG +zfv2thFQCm8=;QbeZMFc~@V=uhOrwQ-w5Epc{|RmU2tE!j4nA%Uo{KOr=S30mw;}?c +z0~dk)4WVd%L#P4gUoe7Pp%3O%p1dXeVH>kp#JEF-5jXtsdcf+ +za*)yFrDldJ#suW$YzwW%&_VcJKQhlp($s&9i+RMoVS%8YN=F!-*kU +z#2GC|<_)CW_h;Flf-j`Z)tNgP035!iU%-tD)YmxI>-}m*ElWPRQ?c8$^ZI1f+$Y09$ysE)>(=Nzk8H+e6V9}E)qZB#yV|R)-d+>TxwE9!6Xaf?h(z8S+ +z-I-^Fi~00htmvPFD7;}nmzNqv(O-{h49Y7agFb8skDFnfG5*OISQWMF2>CHoR6pJq}wqa6> +zMeSwJ(`upJt~;$5{J1fC?v&LRu +z&dClVEFw`uk|9goez2t!kq@7qf+oF*p!>z0{y$A&3Lplz{|Ch2Gav$o-^Ab}AO`B+ +z#o)tj7oDqVcd3661K6J+&BMv@gAc&N#lgw>qZnKif7!=B?N4$*1N9F9UUN6{^{8eX +z#zD{Ot=eB0Q}3&EI={^7(WsPvl6s0(z3PKZFtteHx^Kic$=rH92qWwTtdO?`K8AR& +zg>(hBe`}r|%&M04Dv@D)#E4Plh#PdJ;H&k{D!gA+c*HCzoum1GajG| +zfr=STSWb;fYt998g%!{5%$`YZ1Q1>~ +z;36QbU}vYkIwKeyCxe=x2yT&0$eLlwNpwdP9gv_hT1chQ+BwFy$qALt&*d91c=6r# +zJlb1uG_){6iUW_xS?D&nN5~n2C~*<>`?yL~(A_sXn5B1J%HwtE&IgCMG>1m#-9i~& +z6y#7x>kN{5zR!-V;SYZ>QXQI!fB*6mMljVUoHMFLR-LMi9tbdn;6Eq=A_$u^wl9C0 +z0Pcnr)njmo7Av{^Pm17|4SrSxKTjyYbKo|IrpNUGOGJh8$rZkK{>PG^(^gP=6XZcx%-s<|^W?~1pXPtj2MIUK9VS7ZEfEzG8$S--km +z^2FMMvGjOix){XPdk6CDoPf(}#t~IYMXGYj%vICX@0xE8PM;(6h|4zUaig`z%o@#;skPbaU`oV^a_6WN*sRNExTQxJD2=Y +zCjxFpO^+H9ByivNEh{7Bbh=^PI}`wQ1^cxQULMw1W_cuam^!yC?)PzN2X}Z+`4VC7 +zNes!(3TvwFiTxA44}9^S-p@bFZN|JC0|f^Wj<#hqdEpK2Lg@h>0P^@-PXDQ#rlEmA +zdVmW4zCwTjoD&B?^zW_^0Idi*`xYq%)HCEi)pM9*Ia}T+iUoi}bB##keYBehtNSI_v +zX}8Y6xTc+i^FoSZbdhZRwjc2#tH4(hQo~yzN2yf|-6!$g_O*cr!GeBrgn^n%tA-AI +zt0^y$B#K@iJR!1pU4`Q}{?fPPv$0=B%P~TK+vR$w!yKHD+@o!ILf=xqtOHAHb*1Am +zKjQr&Dc9|KxDOU4KS8TL#mbwLK|RJ1#z+z2hmxjUh`Im)f5wy3p!v(WuWFWFnXVh9 +z(x`H)#p_VVz8#U(>>^mg;`;2H?TsQXLIo0>YMTO2(mACud`kT50^G|w?#HH +zH0%s=uB$djAGY|+x1F88oGw0k3F)1C#Cl3mxJOYN$TUwCP;9*?2Cc)IL^0_#^{4Nh +zJBRA+-b)ai9qyAk&HUuN5Ezh2v8IH1kPH*6SANK4B|VxM$T?SiEsdi#fChuXyZdnv +z6G<#O{vC&4xu@wMX6ypS<0;z&O`XACnWy8k4c8Nz$1M0oFP9^g$UaL78=C!Oo_^Wj +zugwzxHJcR|n}R8K6Ps|yn@&m$;Z&U=GJzi~Y#uG?LtFYW5*;9Y$Ffz#N#^orlywZ4 +z!6X&tAFY}f^{TUVt-wuOr|a#}!Oz|kx7~~zZIxf0nQ6g|lgh{C>D`7AD8_^&&0K1` +zI;rTJg)LkU31mh-qkLJKu^wKEyIr;rn7E0DV|eAAZ%yCA=%e?7stGG!u(E@45&1-{ +z=n4p?^7@T}iqhFZ=shBP4Gg@88E#(;U}cL}Yqz0oYIdzK7jF}r$a^KyVIwSM# +zM_poGc(=V3i`RtwjTfVbjE7d3xi;#l!^PU0--qzMOd}1!bGh}b +zBC$2L{tdrdkhqXA4?2Y0*XaOp2QPcVyoG1Qs9!ok7v}vaDugT!a}6zSB9^fiB=h7X +zZ#-=F30G9Ed>N_of}y{H|0#9dkXmaPc{D=aZoP|#fKO5m@72uZ#^ob@uVwqw(1!vg +zX^%1H*GwOB7aI{#@37tAX4ESR8MA=FyNkYW}q(XVSHaafYtlsC+x3`9Nk*P-7` +z+YJ=3t(>7NIt&tk>c(NE)`&0l(lYAT^k2F;@*ZxxM|CT4Tfrj#-EEyUfmeNUyC>2nhoov26m*0vOsu{p)WUq^%?AcRK*v@*yYv89m!)ki2 +zZ#7P08Mf#OER;UfMA*JJB4R1Dv9z9jjYYY}fzTDEeS9dvu%oAM+!>n2K6G2V`0)bH +z)yS#s!8Sa;PS>kOTf=l3Ihff_RCDxQVY0P&kHjx=1<*g;bIFFi>EIH`O_knQyGF_1AlKv<&Ik` +zg%vE#OtwXyw_xPuP)p#qwlNZ +zInq1J1pO#R|IGdR!|PrG9Kfd3-&e=qihpvyzP;`R&iQfhZ>!^&3vWF9>q{)@0h>z$ +z)Dv3ox!ShuLy>|nhj-B3s(f_Q1RCZ%dnD4)>)r97_Oh?`9&5OKi~IZCYp3#;3j&JP +zTIu%9WPEBL)6v(K^ +zgy9=(wJU0w7%qUh{iNRUNz-03G__LZZZJXUzRE*+!pu--)4!~YY~jqs_t37U#W8Wd +zXw0nJYKoEpdEh8>p|7Bj&G)&kV$l*+<{h$^hj*oInUmFziZ=1zv_wg9DLA2TBH0E_ +zT*JS$MnGGYx`|uU&|I?hp4pwAoD0vO#T+clx@OuxM)PES)eTY%&D43Zgm?N0PIRl8 +zxS==HkcowGblFD7{@|$ih7ZZF+@I>Q*45|A=0}b;VLW9uZwt@Wo;?1^{rP2szjl9s +z_m!ykG;Ue@)%A}YfaJ}p%$t&8rkWD9KC-^he!FdQwjYt9)^`@lE=k#05-}Ki)KwPY +z&>3uSl?0o&N6E1bgWQm}!ZoLPnL%E=!EeaZYc%R?m-z(|U(zc{(OpJDN9kJ=2C2w5 +zNc1>h_3HQ@!_gY$s==ds3Eqd4eaRS&mO1wX+LL5Ig^fgw^{RH*&j!{V>W56)?fL~) +z!uBi!dRjsi#Z@*KY*BYjY_2?acyPN-bA|+-VIW0@5=LF!@+!W;L{pXNiOhYNI3sP+ +z69x-~`gp_ya|Uu020=x4o!#g&xu>%Mqs%DFk9%A{hA%8k+FQ}yc~}#A+Nb8>aldNx +znU`B`49cm=+o#|viq8$99+9$UCgNI$UU$i@C+V$=63=cpmIey6XZH}3-@l_PaOVLC +z=g?t-I$Yi0ar?`5);Dbw(lU(Oj6~PN>p(V7SR%IB4)q)T%MRN$l^03KE{8s4k0{o> +zTMFu^NbkC?Q57B2mv;OJ3`w@CUmuvs37IN~sgM>jk +zpO@+>CAWrJ$!UA#jX1NA*;`(AIgUMxPI+idVRZaa#;WC9WRPjer74Gz`i6g} +zUDc5CVSfr+>&WV5F_7=0?#(iB9ff9MO|MsP6e8#H4#{JkDhgJI-|`6GLqB_2%0mAj +z#k#5-F|$+ehZK<|~eTZR)Wf +zMqCxrYiC7u=o2J;Q2@*VpbvlR$^Z3wk_3oiTqHL$C&_PDzdwI-;5P?;bKo}zzH;FE +z|M^R($ivkv@4zK(>`koU+?*=%UP>i?gBrp6&quN%O-=Q7ZCCK*hzeZcxzEi;Ih+;z0iaoSo#C + +literal 0 +HcmV?d00001 + +diff --git a/src/test/resources/com/android/apksig/v2-only-11-signers.apk b/src/test/resources/com/android/apksig/v2-only-11-signers.apk +new file mode 100644 +index 0000000000000000000000000000000000000000..674b6e4d7d67810c70aaf4255db90b710bf37d23 +GIT binary patch +literal 24784 +zcmeHw1z1(h*6`ubNOyPVp&Lm-T0-dt>F!P`K~j+p=|)1jB%~WDK^l~91o=05z1R1B +zz4!iK{P8`H!?X76HD_k+!5V`2G|FdQPvRgvS{v`lH{=ESp`Uf0%z#nknVc+rF?*%4@dJ6`D{D50SkS)jr +z~jvzQVCuc_s+sEI=FazyBXx!eA1Ne`E +zfM95EuWxH;V+zm(ql3_a4}SE$#jyeW_IbB$Ft;^W9%KO2KiZUmdp-dEv*nv$1A~G3 +zo0$G9`lhxTV*keuL;r6){0zXr`)iyC(6GuA> +z69q$C3o}zEXI6I`>nOEGTP!hb;l>ocC)C}dfyO;T5!eU}R$zK^Nh~m?OaNFCNx(SO +zz%VtjIXVsr2?-C|8-%0Zfv5aH`H+Oc-)V2?ZG0sQ{wMdIjSpVC#%3fG&%{s>l)GLa +z6d1e_5%BtGhcO)HWBf(ln^zkoCj49f^Ltn1 +zW`*;Tc*4~cp{P6;*U19~YYf}&`OiH>v`x~-k63Dz+$$+x9e*}@;Vsbqn9%03iE?he +zoWb#-*ONw6qtNZzxQtCSdKP29~H4&yPdrIX*jF@C~1V0BG$D5#|`yL%|ZHYOo%70-S8 +zu5QzE`ZeECYPIOArqp&vNqd1 +z)l^ +zRNd~|wm!TvIgPvMyIXw~hOa&0CDyDU)FI)sC<5cL4eB>UR}1H-qyWQ+!FXVM>^jZ` +z+|}W4R!9}R2+U5gZo!vdj}9(V{1bvC&0;= +zn7T(LD3}A{+OueD#%qz>%{7%gg_eD)EZNvqG?GWJRr0DD0cZO`UJCaDS6cAGee;9N +z?9fwdw7{kN``PXf_Lrpgv%?J3kCopBks}1kDlND33dYl-Bqp!c*_}4uG^P2x^x%Ii +zGJDq^`Jo?<$m3?Zph!1cHXnDll{r}>hY~I|eneVP0?>MXG_9D=C5pc;`8B%<&S;kg +zbQ{_6QZDQcMKuhIG*M?e;p_`~9kCBoi?PBK{;$KH&5M(g+r?zazz=Onar7c^L_DRy +zLyuUE?eBFlL97p-mmsBl7OoSiftQCg70{1c4sA#cc8q%P3MZUNYf{iwb!DR=bqh$Ah}?*9m^xVlHo|0 +z*yNj&yH|E8S5`G0q7vu19pjdI)ukilhCT0$ +za)EVwmZ#q+`y6p}7v5{Jt??1{`G~C~ZqpuWeC%LVjP0uj +z#?$}+2?SRH;E)Loh5~~TL0^NDWufr8=pl%3@QhDnhWKEhAz17f5HvVwbr@)51QRDi +z7Ip{+7lafKg`Ee&$;r;n&B4nK(ZWOF;)L+A^ZpI}^`JngT1X%i(+|>6074252mr;S +zrd$QEYMjfMW@}z*-W@O?IP9q7tua_ke<*U?r;ak>dMORHWBD3E=oH0Du8~%9a*t)$mzf{iF@vV3%K?djeED7bnb^x{BJ9e<_1#Y0 +zWrcjbs1`lsvUiEmQYFXT>frPT#R7xJN$QcoS-I1>y&4M|Ydyksf?TsPxqJ&TrFG?B +z#IbT$TST+9Y)9*CA~~Lmeq3o|j(`pb1_58g>Fuk$n4|j=J+g7dPwI80={-`OVv^|* +zV139-Wd3kEVJ;&e^rTJr>p^5-kQd(0iXqd=p)F6Xu}xIm!}!MGnAnb+*#dO4N!Vw} +z@>3AC)ClA>!R8nr>n4k*cMsnoT4%KGnR3Q`N}ty@X_~G!z_)&4PxT-($0(?vI)3^H +zt2;*-q6i@YWPk(}1{VhVS*HL()E9L!3sUsN9oF&`_%xaU2-)q&R517uT>oEpK)&sO +z1p^C#hJw2JNx-1lKoDjyHraz1$K=YR8;cY8kBC@oPK0j}hQQc<1j<#-6Ig_#q1uvN +zEN&UvvYS_S;0Du7gmdO8+5-9^@Rx$wN_a8NU#=sbT03d-d+5mum7``%A +zqlq@l4yw +zd2lh4_oA?0lbD}_$@)-LJNo4;N3<4uhr)tZA%<;+@X~WFhim_(s0I{@C;GD-S@GtS +z98kXdtH;4&BLvO`zMipJn#Nw}JgF=@A~=pu7u<7EXJ|bAO0zyrEyb^v_50+{AF+zR +z*5^W;UasmB<=!uxmg#C#J`K)^^hLmip3dM^)ET|55+oZ=nG22-$*8VDd|*yYvvn|O +zO1(67QqcK45bZGoa!?qtCS!;=S;jQ=4$_>h{iYtXW4LQ@kLo>TkrVcm^|>B~yGfT1 +z1if+RVJTm;2yeCB9UpIJ%IlyfeWhe+)J^g!ImvoYr*fZ49mPKWUXaDc9WVtb^_ppw +zArSSm?JIc?qF%qpteQ9}ks%v~WMLr7OrH<}fKMQPW?nBXlKZ_a((H;KvBRiSE*4}t +zwCBtyE(U63`uXZ(gSnA7 +z;vhzxJ^@Al^88M7|&zfQnvLNx~+kiz#;?KRuA|S1(o2lFXh-vkpoYr#o*)I@+R=QeMIn!i-gj +zIwM{l$bJTUkJjaKh4uJCO*7(Y2&KVgeJvF9&Uofm8UZ}Xdr`4rgCpf$O2$|Y5{CTd +zxnX`sxF5ZFtpq4lwUDkgoC3@Z#4)m11YP8HqHBB@@SK%sxQh3RB`<9I#*})IIOHQ1 +z+e_m(;~tz4>B6R +z1zeX8i824+iGJDPpL!x05JU^sPiTN*}_Y+FIJi~lhw>BOUtUL8S$j!B4uj+`0 +zV1UVOO3j83(h@~$+zY}&;U{RunLmg^^LTftsxdH)JL%?p^H0D<1pq|=Ze7$ppoU0- +z$$gmUkcQFJVQFi2s7tW&NVa*oh~6SfZu7bfef)axrU6Wj8)up$AE@$x#1`LcIu{X9 +z>%!nGBT@05M$Ie;4Ew@vwNQ-0f&{|=jSA4qPK1DU)3Xe_Y`3j!?x011Sh +z2O#iAEKyiUmWn6D)BUev2~G$v#~)$|4sM>GV~JbzFR{e8L4hzmfbRbsOF-Yo5&@vf +z0s0z_>u4bYq}bR(7rj9xrE#9SZ4MgjAm`(xrA*2PDWcansq2c~aWrMjjfnPHbFTw$ +z3S+{l(|sV9n3t^GYf|j2xWX5EVp;iTxpl&>6Fl%|dYHsLO(Ss{uecR0 +z-;Yy+4uh0AiNPiBj{Ar`rELqzRrh17!Ef&uR>(xS2+p&X}fHD9rbs(XZu0#ieqLLQ8~ +z&Tf|6Qub9e*f7rto-KN73i7gf0NFN(#y%AlNvO({1=iOr=rWdaBm3aXWT))|OwLx~ +z($>3)jl0>z#chE);fRrA*!1*a+<@cA4L+&F%7JNf#||cx8%ksta}OPlowjE(m#niX +zfB5JTFi-weW1nNw_Z{xfZo4`Xh>$H*o-oh_Etc{aE(&lJ2OK~ZU&CCmeTHpgDsPI$ +z*}u-^d`fg#DpyL{bnw+pla+X+Apfc->SLsdDDmX7E+0JMyw}ZJhht9V{kHNbsg9je +zXi;gbvYm2_9B$UJp#V)4@=dqXXcHQv1Qo*mWY`%$4)@sF6!aTt{Cg3h36(89~sZ2wGeX=fp7dM +z>`xQ)z9at#Tv?ZQH+PmwV&q6Lfj0&Tp5!i_f%EWciLP{f7146`rAs_-uUqfuW|Ok+&|YlMEM74!$jXjfNN3G4+l%vY{-cf* +z#=d3-tP8Tp)5TtaOx=or`e&t)+mT3wQw2TEQeVutSScUM>AQ0u{G9Z?EavMtpfL=^(35#`4nPcQLN}KE} +zvWd;_xtaDJ3qpo6CXp@i3LQ>ECP?;+CrRjnhRIpf<|>jg91wZ&5$!`Tyj44OPzzZe +zFqW8O=v!6ekXR(S$aF(2nhxy*Ke(T}R^%_`s^;{uTHC58i>fb+^;9%nao^qO@cYX2 +znJM_|*p=b3M^fsQj`%W(M;V9Sem$Wh^Fem4G{7^{&P6|Fn^-7e5w6c%txp +zM&M}P6?$v!_*gZI&yp}|!x>VDGl(Ap{tIT?Lg3;EU(XHr +zf{@+`?K7wBDy~D@F&7hz2{T!Bb7n7xr|sO>r6PSLCnk3U!Hf;r#Mlk|m*ZSn9xb5> +zWzTJ#lSP&z&1{ui6-XUJ!CbbP#u(BpoUfb`)aye$sPt3#B#sv@K0m8`yj|YKqaGkOAkgL +zj6crRC?b_aVokkK#WE{G&G)cR+}879uIL83gpt3W#t1fVJ~2j(l=W0ISXZD);iT=! +zT^w#FH{sZ91>&}EdaH+Q#i*IBM!Q?`e +z=hd=rMyXXu>^ND($5kDd@ekzb!oJ{kA+7Z~79jV3Uyc4Y>c5TpZ=?R(sQ*tl>XyK+ +zLIsdo{d+JC;N*b${C7JN&cGP^?4MV9sT7PO$gTaoSZNi>Tl$sq2Qs#K`?px7{ZkO +z_pxGv;7izdnKHMqBHi^%OnF8Xvxj2Fs#`xM)F97C<7TMk3%n%VzjWnDqG^GD+7svu +z4?QbcJ^krVzHI`F+q_;If)mL>?y&t-;zk>Gp!W~H?Ux9}+5Q-E_j-+dMM;$@q4DMI)7*w|;-rAK0F8`9fo +zb8ldnYt@SuzPmOMNENub-DH9S=1Ur=fkX(o*ol1Pv>D#8v45jVNOI5H+TeWqCbvK* +zOe=wjdNW%zfP6l+AM#x#%pGMK!iS+mQs@b2U1~{wHge;1s`l>*B!jhYN&TN=vlZ}d +zEB_PH<^qgy_%3ZWfV5%#khU=OW|Fb0Dw_W-Y2$r+d>!LcibtYT02x@GwDpXz% +zHk`iGL`P(VLsH7J+-d|pNbc%S?3pG>`RBZtN9+s}7~x7X@&s;T@7>KYeZQXme?{KD +zCC13YYsw~alX2{pNA9cJ-G_~b*a6+#m7x^5op +z4DaJzrDTA7OtKc~gOII*ry=MldnFaIW)}zMB99daVj2dwo;oKv{u^=ouW}g%NW7r{ +zA}0_04l)3MfqPM)b|axWRE3*?l3tKTiYAo8e|C=Ey>URHlpjAqd +zl*y=OBM7yr&Z}Y@=AQK_xel3Z9Ko-dp1b%M<_uqJ%aA!A$oWyVTz$afsoH40)R~ +z02N;+j5x}-n>|3bPCO_^e`yqIcQHkUgv{!-@l8WWg+|!d +zPjahssposg#bb1&iR9gN6W0xVQFrs=p_6n@kqiH18P5jgvo^b;NtkT1UhoN3@JF^U +zTKqv$f7#)mSw?7R3lPK%%nrKAVA3rQNg@qzBNM*zXLXD>je9>PQh8b}QU^<|*pkSg +zGvAWGl1sbGjC3kU>J0-78C9b0gr>D=eJafP60 +zdFZ){>qL2oI~Mk=Au#XXiW6|P1K?H|9s@PR6bvBsuX*dQ~$io+p3Q8 +zBTd+vd^j%mwQObdo{Yo-~Fml*Cn0%fp@^Q$T +zCM*%m@xvurC}!2nsYJSo5kq?AbDr@U2CMhg<4Gu+uuPd~yK6>mRccj5@Ux%1Tb +zo@Y~QHF}3S^mQ3#Xi`+XW^Ubh@*@mDqQ8~rz%>ql +zTaAhUYDhpRKz?7|Eb#m*!_|oml$)Wcq%KozmCDAL6Ej+Zl&zEG{xj>jt&EtM3hL`& +zCEd+e1#xGDOs+(2we?puXxNjp>UCAa%Y_41Vv +z-oEjnq;PxO>l2EFj)-~Wp`39#c5rfeLcCe5vbm0uL;GUOVC1d;g8Y9iFkV1HS{P8z +zAMrOdpibn#xBhqW_w5eVHNbCRpZWq&y^lXsFPa--y#R%C20?*C1mf=}XDComcVIz( +z$W1!}Zw38nbDWEtmy7=&>h~S}^`Jl~%Abit!GeGk9UAaOppd?8d5$c_aigczo#;WT +z2B~s2H90m6=Pp2!G`gAi%u;vColF!`cj~a1^PexO@h;7C<0(_(cI2w9IN$fPS$T`# +zVHq?oxp3L`EH>SihD4*q|0|trWej&JxQY_lA?n@k7e7?Tdc`fLyv6*ow~rUD#Xkk& +z-qYvA!7XEDrDU5I2#J+ONKk-kmPyE*XUI-;hZLL;Akdpjq)^*B#I(r@7B4O4>eG4g +zKJq+2Ty`)pH-wFa8j&^EsdJB%H3E@gLTZmO6)T_*X7*8vU7btgb!ct|hd4Ec#+KYd +z>E7jKQ$}kK5_+y>J+0!4h#RR4&A<*vdqWRJaf)$GvBIof@u>$4Od-^t>;N8^#R=Vy +zFNGiTlO@G#s3)4tBzAwW1HbI>M?3Jx2?cl#Jm$>gqBd|9FJJCOnV)UIh4`104fx)8 +zQRr!tvpNraO(;dOd(a3@atn0pWjx4N%qZ0GE{sc&t8h9Q_i4ZSVB&ar?0>ln!6O=7 +zuJH+d?Jk|gAYZ!bZ-By)F1nGs#VAx_6?3m*@!Hh8>_bKaA_5<~Lj}p^vj9wU)43L_ +zDYT+DRvz@l7n5^^AeP?8;FcR4PRn@*1PNt{@>x?C4HthYzif;?2k3K7o8Z^=Rvz

T-B=bzm-_C*KM(pfm^o+$s+UfRV&DMU+4y$=qeR +z@g!Bt5@*Sa>!SWgtNWP4he~&F +zb1t6|>~An9>s;Es;r+}T@9F*ai|o#`kK>?_VBE2`^hPhN!2@VofCqp+{?^lftEVZ5 +zAdoI#f`6&);xm&^9+Upjf-FiM*7>$W5Z3+4G6y&$4Aj@QpyuE +z&Xmwa5PAJvlkqN4EOwCa&=%v=uY(vQ$T6&89aZqfy*3FHr;zq|@wLd%(|TAec4 +zHcX~^z@-|mO&RlHL`I_vXBCz6i(jUbErw)6O!Q#9{GFIew4Tq&ay5wA0ag@+uL)QT +zbgVnoq||wgKg1=a4(d~5tbD~0*%N9Q=~l>{6o`zSv}#vMoCkG(eKs?H+!pR5=lQ8X +zU}5gsqTI8O=QYv8=>5SA(s~WE=sD|qN8Y>);B=bHENff+N>~Z(8rXD1RIiz^3r5$UDiVJY7cwyYgM0dA +zhkxy!08z8vaJJ5ybvL$-a8Pknq>G^Fd?Fq6+1xs9RS&wkA34z;+;<^Uf&bi0?wYKI +z4kd)3%2h21nu9ljrky +z+SsNQ{4&vnYQaH_aMxs`#p&A-#h7~~%Rz}dSQrLGAN{KOmdDc81Rf-8d_~O)&Vl6O +zF(b)C7)onD<&_mL3_|#YQX9LqErgnzUEm%}gh#Lt^;^%k*d5o1cY1YiWVc0L3pabKb7WITU7G(=Db~1*(7bN}W +z^3_Dx!W+)09JvxgrDcNv`G70RnjzKJFp_A9ob7fOHx943EY{RKTK)RDp4YnFRp?9p +zqLkOjOIs!{xe5*ODEC?JbJ6P-gbm8*UgB!5BTF#eEz+y0C$L|Y*pV~HBnv{g3ecwA +zNjV7Ow<({eDL4z}ht`QjO|BAM?WLyItLnd_GV5k@5ij#V-q(u0m0=BG +zq_l8bv{O+)b|*GNv{G5yH~3MVu3@e%q+hL*G;-(7jY2n{rDNl3x{RCnicoO13mwg)=f+s$lCOqI^{)Z@U}P +zKb1<~2W3lDTNv$_huta?BZ<%ArbQ-gRU?3IBnhmxbhHhjZPpHl@d` +z&9YC!;8}7@BXb#LjCab{`(}$J`L!CE!|NYJ@>TU=s$}lng+H{ToU~c+h*!r>YC&y$ +zt7kbuU=gOIZ`arc7@4QW2K4S;S8j0ICRc}nd#u<&q#^l3(a0}A>-Y(tSSZ6!yBPd=(5A8)f{tto-%#)B#^saZH8mXP+WkwgHp%C +zjr=mECI*`V&xbH1b|r2yk}u@gUh$QM$CeJP@|1|l&&(m6D9u3yALpFdHA#~)?k2ly +z(D<#EyrID$2OTvt(E>66_@m!`>bIZzH-5?sI2=J32&4YPt7BlyHLyYk-n_aEzYKq@ +zju#0ZujBN?8~(fS>rbzH@v{S)QvX;Te@Fiketm!43o83(;@?-t&u*jfh;J{kqz3M+ +z4p2^Nu5q^Q+J(Y~pha}hJSn +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 +Tg9RFHk9CIzHQe49++O|{heuzh + +literal 0 +HcmV?d00001 + +-- +2.30.2 + diff --git a/Patches/LineageOS-17.1/android_tools_apksig/360973-backport-prereq.patch b/Patches/LineageOS-17.1/android_tools_apksig/360973-backport-prereq.patch new file mode 100644 index 00000000..5194e448 --- /dev/null +++ b/Patches/LineageOS-17.1/android_tools_apksig/360973-backport-prereq.patch @@ -0,0 +1,53 @@ +From 011adec1a494974102930bf65a8d2fdfa8b375b5 Mon Sep 17 00:00:00 2001 +From: Khaled Abdelmohsen +Date: Mon, 24 Feb 2020 16:59:21 +0000 +Subject: [PATCH 1/2] Create source stamp verifier + +Bug: 148005911 +Test: gradlew test +Change-Id: I7008c9567ad5e8b63e7f6ba192d38b10c5c9a2dc +Merged-In: I7008c9567ad5e8b63e7f6ba192d38b10c5c9a2dc +(cherry picked from commit a3970357d65d59b70c6ccf2c5c55000cb4310953) +--- + .../internal/apk/ApkSigningBlockUtils.java | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java b/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java +index 2330f6d..f15597b 100644 +--- a/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java ++++ b/src/main/java/com/android/apksig/internal/apk/ApkSigningBlockUtils.java +@@ -998,6 +998,20 @@ public class ApkSigningBlockUtils { + return false; + } + ++ public boolean containsWarnings() { ++ if (!mWarnings.isEmpty()) { ++ return true; ++ } ++ if (!signers.isEmpty()) { ++ for (SignerInfo signer : signers) { ++ if (signer.containsWarnings()) { ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ + public void addError(ApkVerifier.Issue msg, Object... parameters) { + mErrors.add(new ApkVerifier.IssueWithParams(msg, parameters)); + } +@@ -1042,6 +1056,10 @@ public class ApkSigningBlockUtils { + return !mErrors.isEmpty(); + } + ++ public boolean containsWarnings() { ++ return !mWarnings.isEmpty(); ++ } ++ + public List getErrors() { + return mErrors; + } +-- +2.30.2 + diff --git a/Patches/LineageOS-17.1/android_tools_apksig/360973-backport.patch b/Patches/LineageOS-17.1/android_tools_apksig/360973-backport.patch index 2ce544ed..ef02af06 100644 --- a/Patches/LineageOS-17.1/android_tools_apksig/360973-backport.patch +++ b/Patches/LineageOS-17.1/android_tools_apksig/360973-backport.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 9a80527425030dae7f962ab95eda500a720cde47 Mon Sep 17 00:00:00 2001 From: Michael Groover Date: Fri, 31 Mar 2023 14:30:21 -0500 -Subject: [PATCH] Limit the number of supported v1 and v2 signers +Subject: [PATCH 2/2] Limit the number of supported v1 and v2 signers The v1 and v2 APK Signature Schemes support multiple signers; this was intended to allow multiple entities to sign an APK. Previously, @@ -15,29 +15,31 @@ Test: gradlew test (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ea0632935646f2f6bf5822a5e9c97885269780bd) Merged-In: I77f4218599511ff4f9f3790e4942a329d5a18da4 Change-Id: I77f4218599511ff4f9f3790e4942a329d5a18da4 + +Change-Id: I604ce656e6dcd750e664adcb814c5c66f7b80ce1 --- .../java/com/android/apksig/ApkVerifier.java | 29 +++++ .../internal/apk/v1/V1SchemeSigner.java | 7 ++ .../internal/apk/v1/V1SchemeVerifier.java | 7 ++ - .../internal/apk/v2/V2SchemeSigner.java | 8 ++ - .../internal/apk/v2/V2SchemeVerifier.java | 5 + + .../internal/apk/v2/V2SchemeSigner.java | 6 ++ + .../internal/apk/v2/V2SchemeVerifier.java | 4 + .../com/android/apksig/ApkSignerTest.java | 100 ++++++++++++++++++ .../com/android/apksig/ApkVerifierTest.java | 31 ++++++ .../com/android/apksig/v1-only-10-signers.apk | Bin 0 -> 18389 bytes .../com/android/apksig/v1-only-11-signers.apk | Bin 0 -> 22297 bytes .../com/android/apksig/v2-only-10-signers.apk | Bin 0 -> 20688 bytes .../com/android/apksig/v2-only-11-signers.apk | Bin 0 -> 24784 bytes - 11 files changed, 187 insertions(+) + 11 files changed, 184 insertions(+) create mode 100644 src/test/resources/com/android/apksig/v1-only-10-signers.apk create mode 100644 src/test/resources/com/android/apksig/v1-only-11-signers.apk create mode 100644 src/test/resources/com/android/apksig/v2-only-10-signers.apk create mode 100644 src/test/resources/com/android/apksig/v2-only-11-signers.apk diff --git a/src/main/java/com/android/apksig/ApkVerifier.java b/src/main/java/com/android/apksig/ApkVerifier.java -index 3e1e7da..cfbc8d2 100644 +index 5e458ef..62b132a 100644 --- a/src/main/java/com/android/apksig/ApkVerifier.java +++ b/src/main/java/com/android/apksig/ApkVerifier.java -@@ -644,6 +644,15 @@ public class ApkVerifier { +@@ -620,6 +620,15 @@ public class ApkVerifier { } private void mergeFrom(ApkSigningBlockUtils.Result source) { @@ -53,7 +55,7 @@ index 3e1e7da..cfbc8d2 100644 switch (source.signatureSchemeVersion) { case ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V2: mVerifiedUsingV2Scheme = source.verified; -@@ -921,6 +930,16 @@ public class ApkVerifier { +@@ -897,6 +906,16 @@ public class ApkVerifier { */ JAR_SIG_NO_SIGNATURES("No JAR signatures"), @@ -70,7 +72,7 @@ index 3e1e7da..cfbc8d2 100644 /** * APK does not contain any entries covered by JAR signatures. */ -@@ -1349,6 +1368,16 @@ public class ApkVerifier { +@@ -1325,6 +1344,16 @@ public class ApkVerifier { "APK Signature Scheme v2 signature %1$s indicates the APK is signed using %2$s but " + "no such signature was found. Signature stripped?"), @@ -88,49 +90,52 @@ index 3e1e7da..cfbc8d2 100644 * APK Signature Scheme v2 signature contains no signers. */ diff --git a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java -index f900211..6422af0 100644 +index f900211..05721ed 100644 --- a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java +++ b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeSigner.java -@@ -16,6 +16,8 @@ - - package com.android.apksig.internal.apk.v1; - -+//import static com.android.apksig.Constants.MAX_APK_SIGNERS; +@@ -246,9 +246,16 @@ public abstract class V1SchemeSigner { + String createdBy) + throws NoSuchAlgorithmException, ApkFormatException, InvalidKeyException, + CertificateException, SignatureException { + - import com.android.apksig.apk.ApkFormatException; - import com.android.apksig.internal.asn1.Asn1DerEncoder; - import com.android.apksig.internal.asn1.Asn1EncodingException; -@@ -249,6 +251,11 @@ public abstract class V1SchemeSigner { ++ int MAX_APK_SIGNERS = 10; if (signerConfigs.isEmpty()) { throw new IllegalArgumentException("At least one signer config must be provided"); } -+ if (signerConfigs.size() > 10) { ++ if (signerConfigs.size() > MAX_APK_SIGNERS) { + throw new IllegalArgumentException( -+ "APK Signature Scheme v1 only supports a maximum of " + 10 + ", " ++ "APK Signature Scheme v1 only supports a maximum of " + MAX_APK_SIGNERS + ", " + + signerConfigs.size() + " provided"); + } OutputManifestFile manifest = generateManifestFile( jarEntryDigestAlgorithm, jarEntryDigests, sourceManifestBytes); diff --git a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java -index 47d5b01..615215c 100644 +index a828bcc..8e49dd3 100644 --- a/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java +++ b/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java -@@ -16,6 +16,8 @@ +@@ -16,6 +16,7 @@ package com.android.apksig.internal.apk.v1; -+//import static com.android.apksig.Constants.MAX_APK_SIGNERS; + import com.android.apksig.ApkVerifier.Issue; import com.android.apksig.ApkVerifier.IssueWithParams; import com.android.apksig.apk.ApkFormatException; -@@ -303,6 +305,11 @@ public abstract class V1SchemeVerifier { +@@ -249,6 +250,7 @@ public abstract class V1SchemeVerifier { + // * All JAR entries listed in JAR manifest are present in the APK. + + // Identify signers ++ int MAX_APK_SIGNERS = 10; + List signers = new ArrayList<>(sigBlockEntries.size()); + for (CentralDirectoryRecord sigBlockEntry : sigBlockEntries) { + String sigBlockEntryName = sigBlockEntry.getName(); +@@ -277,6 +279,11 @@ public abstract class V1SchemeVerifier { result.addError(Issue.JAR_SIG_NO_SIGNATURES); return; } -+ if (signers.size() > 10) { -+ result.addError(Issue.JAR_SIG_MAX_SIGNATURES_EXCEEDED, 10, ++ if (signers.size() > MAX_APK_SIGNERS) { ++ result.addError(Issue.JAR_SIG_MAX_SIGNATURES_EXCEEDED, MAX_APK_SIGNERS, + signers.size()); + return; + } @@ -138,66 +143,49 @@ index 47d5b01..615215c 100644 // Verify each signer's signature block file .(RSA|DSA|EC) against the corresponding // signature file .SF. Any error encountered for any signer terminates verification, to diff --git a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java -index d8e4723..03a0311 100644 +index 6d001e7..375ff91 100644 --- a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java +++ b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeSigner.java -@@ -16,6 +16,7 @@ - - package com.android.apksig.internal.apk.v2; - -+//import static com.android.apksig.Constants.MAX_APK_SIGNERS; - import static com.android.apksig.internal.apk.ApkSigningBlockUtils.encodeAsSequenceOfLengthPrefixedElements; - import static com.android.apksig.internal.apk.ApkSigningBlockUtils.encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes; - import static com.android.apksig.internal.apk.ApkSigningBlockUtils.encodeCertificates; -@@ -28,6 +29,7 @@ import com.android.apksig.internal.apk.SignatureAlgorithm; - import com.android.apksig.internal.util.Pair; - import com.android.apksig.util.DataSource; - import com.android.apksig.util.RunnablesExecutor; -+ - import java.io.IOException; - import java.nio.ByteBuffer; - import java.nio.ByteOrder; -@@ -163,6 +165,12 @@ public abstract class V2SchemeSigner { +@@ -161,6 +161,12 @@ public abstract class V2SchemeSigner { + throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { // FORMAT: // * length-prefixed sequence of length-prefixed signer blocks. - -+ if (signerConfigs.size() > 10) { ++ int MAX_APK_SIGNERS = 10; ++ if (signerConfigs.size() > MAX_APK_SIGNERS) { + throw new IllegalArgumentException( -+ "APK Signature Scheme v2 only supports a maximum of " + 10 + ", " ++ "APK Signature Scheme v2 only supports a maximum of " + MAX_APK_SIGNERS + ", " + + signerConfigs.size() + " provided"); + } -+ + List signerBlocks = new ArrayList<>(signerConfigs.size()); int signerNumber = 0; - for (SignerConfig signerConfig : signerConfigs) { diff --git a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java -index 51c40bd..651ed5d 100644 +index e1be06e..39b205b 100644 --- a/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java +++ b/src/main/java/com/android/apksig/internal/apk/v2/V2SchemeVerifier.java -@@ -16,6 +16,8 @@ - - package com.android.apksig.internal.apk.v2; - -+//import static com.android.apksig.Constants.MAX_APK_SIGNERS; -+ - import com.android.apksig.ApkVerifier.Issue; - import com.android.apksig.apk.ApkFormatException; - import com.android.apksig.apk.ApkUtils; -@@ -225,6 +227,9 @@ public abstract class V2SchemeVerifier { +@@ -180,6 +180,7 @@ public abstract class V2SchemeVerifier { + int maxSdkVersion, + ApkSigningBlockUtils.Result result) throws NoSuchAlgorithmException { + ByteBuffer signers; ++ int MAX_APK_SIGNERS = 10; + try { + signers = ApkSigningBlockUtils.getLengthPrefixedSlice(apkSignatureSchemeV2Block); + } catch (ApkFormatException e) { +@@ -221,6 +222,9 @@ public abstract class V2SchemeVerifier { return; } } -+ if (signerCount > 10) { -+ result.addError(Issue.V2_SIG_MAX_SIGNATURES_EXCEEDED, 10, signerCount); ++ if (signerCount > MAX_APK_SIGNERS) { ++ result.addError(Issue.V2_SIG_MAX_SIGNATURES_EXCEEDED, MAX_APK_SIGNERS, signerCount); + } } /** diff --git a/src/test/java/com/android/apksig/ApkSignerTest.java b/src/test/java/com/android/apksig/ApkSignerTest.java -index 1434017..729d96f 100644 +index 80f35ba..ccdb02a 100644 --- a/src/test/java/com/android/apksig/ApkSignerTest.java +++ b/src/test/java/com/android/apksig/ApkSignerTest.java -@@ -635,6 +635,106 @@ public class ApkSignerTest { +@@ -339,6 +339,106 @@ public class ApkSignerTest { } catch (ApkFormatException expected) {} } @@ -305,7 +293,7 @@ index 1434017..729d96f 100644 public void testWeirdZipCompressionMethod() throws Exception { // Any ZIP compression method other than STORED is treated as DEFLATED by Android. diff --git a/src/test/java/com/android/apksig/ApkVerifierTest.java b/src/test/java/com/android/apksig/ApkVerifierTest.java -index 351d0a8..2392b88 100644 +index 6f6c04d..0546f0f 100644 --- a/src/test/java/com/android/apksig/ApkVerifierTest.java +++ b/src/test/java/com/android/apksig/ApkVerifierTest.java @@ -239,6 +239,20 @@ public class ApkVerifierTest { @@ -329,7 +317,7 @@ index 351d0a8..2392b88 100644 @Test public void testV2StrippedRejected() throws Exception { // APK signed with v1 and v2 schemes, but v2 signature was stripped from the file (by using -@@ -630,6 +644,23 @@ public class ApkVerifierTest { +@@ -471,6 +485,23 @@ public class ApkVerifierTest { Issue.V2_SIG_NO_SUPPORTED_SIGNATURES); } @@ -1454,3 +1442,6 @@ Tg9RFHk9CIzHQe49++O|{heuzh literal 0 HcmV?d00001 +-- +2.30.2 + diff --git a/Scripts/LineageOS-16.0/Patch.sh b/Scripts/LineageOS-16.0/Patch.sh index d9080cc2..b7b06f10 100644 --- a/Scripts/LineageOS-16.0/Patch.sh +++ b/Scripts/LineageOS-16.0/Patch.sh @@ -371,6 +371,11 @@ if enterAndClear "system/nfc"; then applyPatch "$DOS_PATCHES/android_system_nfc/360972.patch"; #R_asb_2023-07 OOBW in rw_i93_send_to_upper() fi; +if enterAndClear "tools/apksig"; then +applyPatch "$DOS_PATCHES/android_tools_apksig/360973-backport-prereq.patch"; #R_asb_2023-07 Create source stamp verifier +applyPatch "$DOS_PATCHES/android_tools_apksig/360973-backport.patch"; #R_asb_2023-07 Limit the number of supported v1 and v2 signers +fi; + if enterAndClear "vendor/nxp/opensource/commonsys/external/libnfc-nci"; then applyPatch "$DOS_PATCHES/android_vendor_nxp_opensource_commonsys_external_libnfc-nci/360974-backport.patch"; #R_asb_2023-07 OOBW in rw_i93_send_to_upper() fi; diff --git a/Scripts/LineageOS-17.1/Patch.sh b/Scripts/LineageOS-17.1/Patch.sh index b73f8c2a..e4eab3c6 100644 --- a/Scripts/LineageOS-17.1/Patch.sh +++ b/Scripts/LineageOS-17.1/Patch.sh @@ -441,9 +441,10 @@ if enterAndClear "system/update_engine"; then git revert --no-edit c68499e3ff10f2a31f913e14f66aafb4ed94d42d; #Do not skip payload signature verification fi; -#if enterAndClear "tools/apksig"; then -#applyPatch "$DOS_PATCHES/android_tools_apksig/360973-backport.patch"; #R_asb_2023-07 Limit the number of supported v1 and v2 signers #TODO backport containsWarnings for SignerInfo -#fi; +if enterAndClear "tools/apksig"; then +applyPatch "$DOS_PATCHES/android_tools_apksig/360973-backport-prereq.patch"; #R_asb_2023-07 Create source stamp verifier +applyPatch "$DOS_PATCHES/android_tools_apksig/360973-backport.patch"; #R_asb_2023-07 Limit the number of supported v1 and v2 signers +fi; if enterAndClear "vendor/lineage"; then rm build/target/product/security/lineage.x509.pem; #Remove Lineage keys