Loading core/java/android/os/incremental/V4Signature.java +1 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ public class V4Signature { * * @param fileSize - size of the signed file (APK) */ public static byte[] getSigningData(long fileSize, HashingInfo hashingInfo, public static byte[] getSignedData(long fileSize, HashingInfo hashingInfo, SigningInfo signingInfo) { final int size = 4/*size*/ + 8/*fileSize*/ + 4/*hash_algorithm*/ + 1/*log2_blocksize*/ + bytesSize( Loading core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java +8 −9 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmContent import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaKeyAlgorithm; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.isSupportedSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.pickBestDigestForV4; import static android.util.apk.ApkSigningBlockUtils.readLengthPrefixedByteArray; import android.util.ArrayMap; Loading Loading @@ -213,11 +212,9 @@ public class ApkSignatureSchemeV2Verifier { verityDigest, apk.length(), signatureInfo); } byte[] digest = pickBestDigestForV4(contentDigests); return new VerifiedSigner( signerCerts.toArray(new X509Certificate[signerCerts.size()][]), verityRootHash, digest); verityRootHash, contentDigests); } private static X509Certificate[] verifySigner( Loading Loading @@ -339,8 +336,7 @@ public class ApkSignatureSchemeV2Verifier { } catch (CertificateException e) { throw new SecurityException("Failed to decode certificate #" + certificateCount, e); } certificate = new VerbatimX509Certificate( certificate, encodedCert); certificate = new VerbatimX509Certificate(certificate, encodedCert); certs.add(certificate); } Loading Loading @@ -434,12 +430,15 @@ public class ApkSignatureSchemeV2Verifier { public final X509Certificate[][] certs; public final byte[] verityRootHash; public final byte[] digest; // Algorithm -> digest map of signed digests in the signature. // All these are verified if requested. public final Map<Integer, byte[]> contentDigests; public VerifiedSigner(X509Certificate[][] certs, byte[] verityRootHash, byte[] digest) { public VerifiedSigner(X509Certificate[][] certs, byte[] verityRootHash, Map<Integer, byte[]> contentDigests) { this.certs = certs; this.verityRootHash = verityRootHash; this.digest = digest; this.contentDigests = contentDigests; } } Loading core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java +18 −15 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmContent import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaKeyAlgorithm; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.isSupportedSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.pickBestDigestForV4; import static android.util.apk.ApkSigningBlockUtils.readLengthPrefixedByteArray; import android.os.Build; Loading Loading @@ -161,7 +160,7 @@ public class ApkSignatureSchemeV3Verifier { boolean doVerifyIntegrity) throws SecurityException, IOException { int signerCount = 0; Map<Integer, byte[]> contentDigests = new ArrayMap<>(); VerifiedSigner result = null; Pair<X509Certificate[], VerifiedProofOfRotation> result = null; CertificateFactory certFactory; try { certFactory = CertificateFactory.getInstance("X.509"); Loading Loading @@ -206,18 +205,17 @@ public class ApkSignatureSchemeV3Verifier { ApkSigningBlockUtils.verifyIntegrity(contentDigests, apk, signatureInfo); } byte[] verityRootHash = null; if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) { byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256); result.verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength( verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength( verityDigest, apk.length(), signatureInfo); } result.digest = pickBestDigestForV4(contentDigests); return result; return new VerifiedSigner(result.first, result.second, verityRootHash, contentDigests); } private static VerifiedSigner verifySigner( private static Pair<X509Certificate[], VerifiedProofOfRotation> verifySigner( ByteBuffer signerBlock, Map<Integer, byte[]> contentDigests, CertificateFactory certFactory) Loading Loading @@ -349,8 +347,7 @@ public class ApkSignatureSchemeV3Verifier { } catch (CertificateException e) { throw new SecurityException("Failed to decode certificate #" + certificateCount, e); } certificate = new VerbatimX509Certificate( certificate, encodedCert); certificate = new VerbatimX509Certificate(certificate, encodedCert); certs.add(certificate); } Loading Loading @@ -382,8 +379,9 @@ public class ApkSignatureSchemeV3Verifier { private static final int PROOF_OF_ROTATION_ATTR_ID = 0x3ba06f8c; private static VerifiedSigner verifyAdditionalAttributes(ByteBuffer attrs, List<X509Certificate> certs, CertificateFactory certFactory) throws IOException { private static Pair<X509Certificate[], VerifiedProofOfRotation> verifyAdditionalAttributes( ByteBuffer attrs, List<X509Certificate> certs, CertificateFactory certFactory) throws IOException { X509Certificate[] certChain = certs.toArray(new X509Certificate[certs.size()]); VerifiedProofOfRotation por = null; Loading Loading @@ -421,7 +419,7 @@ public class ApkSignatureSchemeV3Verifier { break; } } return new VerifiedSigner(certChain, por); return Pair.create(certChain, por); } private static VerifiedProofOfRotation verifyProofOfRotationStruct( Loading Loading @@ -570,12 +568,17 @@ public class ApkSignatureSchemeV3Verifier { public final X509Certificate[] certs; public final VerifiedProofOfRotation por; public byte[] verityRootHash; public byte[] digest; public final byte[] verityRootHash; // Algorithm -> digest map of signed digests in the signature. // All these are verified if requested. public final Map<Integer, byte[]> contentDigests; public VerifiedSigner(X509Certificate[] certs, VerifiedProofOfRotation por) { public VerifiedSigner(X509Certificate[] certs, VerifiedProofOfRotation por, byte[] verityRootHash, Map<Integer, byte[]> contentDigests) { this.certs = certs; this.por = por; this.verityRootHash = verityRootHash; this.contentDigests = contentDigests; } } Loading core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java +30 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package android.util.apk; import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_VERITY_CHUNKED_SHA256; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaKeyAlgorithm; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.isSupportedSignatureAlgorithm; import android.os.incremental.IncrementalManager; import android.os.incremental.V4Signature; import android.util.ArrayMap; import android.util.Pair; import java.io.ByteArrayInputStream; Loading @@ -42,6 +44,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Map; /** * APK Signature Scheme v4 verifier. Loading Loading @@ -79,13 +82,20 @@ public class ApkSignatureSchemeV4Verifier { throw new SignatureNotFoundException("Failed to read V4 signature.", e); } final byte[] signedData = V4Signature.getSigningData(apk.length(), hashingInfo, // Verify signed data and extract certificates and apk digest. final byte[] signedData = V4Signature.getSignedData(apk.length(), hashingInfo, signingInfo); final Pair<Certificate, byte[]> result = verifySigner(signingInfo, signedData); return verifySigner(signingInfo, signedData); // Populate digests enforced by IncFS driver. Map<Integer, byte[]> contentDigests = new ArrayMap<>(); contentDigests.put(convertToContentDigestType(hashingInfo.hashAlgorithm), hashingInfo.rawRootHash); return new VerifiedSigner(new Certificate[]{result.first}, result.second, contentDigests); } private static VerifiedSigner verifySigner(V4Signature.SigningInfo signingInfo, private static Pair<Certificate, byte[]> verifySigner(V4Signature.SigningInfo signingInfo, final byte[] signedData) throws SecurityException { if (!isSupportedSignatureAlgorithm(signingInfo.signatureAlgorithmId)) { throw new SecurityException("No supported signatures found"); Loading Loading @@ -145,21 +155,34 @@ public class ApkSignatureSchemeV4Verifier { "Public key mismatch between certificate and signature record"); } return new VerifiedSigner(new Certificate[]{certificate}, signingInfo.apkDigest); return Pair.create(certificate, signingInfo.apkDigest); } private static int convertToContentDigestType(int hashAlgorithm) throws SecurityException { if (hashAlgorithm == V4Signature.HASHING_ALGORITHM_SHA256) { return CONTENT_DIGEST_VERITY_CHUNKED_SHA256; } throw new SecurityException("Unsupported hashAlgorithm: " + hashAlgorithm); } /** * Verified APK Signature Scheme v4 signer, including V3 digest. * Verified APK Signature Scheme v4 signer, including V2/V3 digest. * * @hide for internal use only. */ public static class VerifiedSigner { public final Certificate[] certs; public byte[] apkDigest; public final byte[] apkDigest; // Algorithm -> digest map of signed digests in the signature. // These are continuously enforced by the IncFS driver. public final Map<Integer, byte[]> contentDigests; public VerifiedSigner(Certificate[] certs, byte[] apkDigest) { public VerifiedSigner(Certificate[] certs, byte[] apkDigest, Map<Integer, byte[]> contentDigests) { this.certs = certs; this.apkDigest = apkDigest; this.contentDigests = contentDigests; } } Loading core/java/android/util/apk/ApkSignatureVerifier.java +14 −6 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import java.security.cert.CertificateEncodingException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.zip.ZipEntry; Loading Loading @@ -184,21 +185,21 @@ public class ApkSignatureVerifier { Signature[] signerSigs = convertToSignatures(signerCerts); if (verifyFull) { byte[] nonstreamingDigest = null; Certificate[][] nonstreamingCerts = null; Map<Integer, byte[]> nonstreamingDigests; Certificate[][] nonstreamingCerts; try { // v4 is an add-on and requires v2 or v3 signature to validate against its // certificate and digest ApkSignatureSchemeV3Verifier.VerifiedSigner v3Signer = ApkSignatureSchemeV3Verifier.unsafeGetCertsWithoutVerification(apkPath); nonstreamingDigest = v3Signer.digest; nonstreamingDigests = v3Signer.contentDigests; nonstreamingCerts = new Certificate[][]{v3Signer.certs}; } catch (SignatureNotFoundException e) { try { ApkSignatureSchemeV2Verifier.VerifiedSigner v2Signer = ApkSignatureSchemeV2Verifier.verify(apkPath, false); nonstreamingDigest = v2Signer.digest; nonstreamingDigests = v2Signer.contentDigests; nonstreamingCerts = v2Signer.certs; } catch (SignatureNotFoundException ee) { throw new SecurityException( Loading @@ -220,8 +221,15 @@ public class ApkSignatureVerifier { } } if (!ArrayUtils.equals(vSigner.apkDigest, nonstreamingDigest, boolean found = false; for (byte[] nonstreamingDigest : nonstreamingDigests.values()) { if (ArrayUtils.equals(vSigner.apkDigest, nonstreamingDigest, vSigner.apkDigest.length)) { found = true; break; } } if (!found) { throw new SecurityException("APK digest in V4 signature does not match V2/V3"); } } Loading Loading
core/java/android/os/incremental/V4Signature.java +1 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ public class V4Signature { * * @param fileSize - size of the signed file (APK) */ public static byte[] getSigningData(long fileSize, HashingInfo hashingInfo, public static byte[] getSignedData(long fileSize, HashingInfo hashingInfo, SigningInfo signingInfo) { final int size = 4/*size*/ + 8/*fileSize*/ + 4/*hash_algorithm*/ + 1/*log2_blocksize*/ + bytesSize( Loading
core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java +8 −9 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmContent import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaKeyAlgorithm; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.isSupportedSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.pickBestDigestForV4; import static android.util.apk.ApkSigningBlockUtils.readLengthPrefixedByteArray; import android.util.ArrayMap; Loading Loading @@ -213,11 +212,9 @@ public class ApkSignatureSchemeV2Verifier { verityDigest, apk.length(), signatureInfo); } byte[] digest = pickBestDigestForV4(contentDigests); return new VerifiedSigner( signerCerts.toArray(new X509Certificate[signerCerts.size()][]), verityRootHash, digest); verityRootHash, contentDigests); } private static X509Certificate[] verifySigner( Loading Loading @@ -339,8 +336,7 @@ public class ApkSignatureSchemeV2Verifier { } catch (CertificateException e) { throw new SecurityException("Failed to decode certificate #" + certificateCount, e); } certificate = new VerbatimX509Certificate( certificate, encodedCert); certificate = new VerbatimX509Certificate(certificate, encodedCert); certs.add(certificate); } Loading Loading @@ -434,12 +430,15 @@ public class ApkSignatureSchemeV2Verifier { public final X509Certificate[][] certs; public final byte[] verityRootHash; public final byte[] digest; // Algorithm -> digest map of signed digests in the signature. // All these are verified if requested. public final Map<Integer, byte[]> contentDigests; public VerifiedSigner(X509Certificate[][] certs, byte[] verityRootHash, byte[] digest) { public VerifiedSigner(X509Certificate[][] certs, byte[] verityRootHash, Map<Integer, byte[]> contentDigests) { this.certs = certs; this.verityRootHash = verityRootHash; this.digest = digest; this.contentDigests = contentDigests; } } Loading
core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java +18 −15 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmContent import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaKeyAlgorithm; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.isSupportedSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.pickBestDigestForV4; import static android.util.apk.ApkSigningBlockUtils.readLengthPrefixedByteArray; import android.os.Build; Loading Loading @@ -161,7 +160,7 @@ public class ApkSignatureSchemeV3Verifier { boolean doVerifyIntegrity) throws SecurityException, IOException { int signerCount = 0; Map<Integer, byte[]> contentDigests = new ArrayMap<>(); VerifiedSigner result = null; Pair<X509Certificate[], VerifiedProofOfRotation> result = null; CertificateFactory certFactory; try { certFactory = CertificateFactory.getInstance("X.509"); Loading Loading @@ -206,18 +205,17 @@ public class ApkSignatureSchemeV3Verifier { ApkSigningBlockUtils.verifyIntegrity(contentDigests, apk, signatureInfo); } byte[] verityRootHash = null; if (contentDigests.containsKey(CONTENT_DIGEST_VERITY_CHUNKED_SHA256)) { byte[] verityDigest = contentDigests.get(CONTENT_DIGEST_VERITY_CHUNKED_SHA256); result.verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength( verityRootHash = ApkSigningBlockUtils.parseVerityDigestAndVerifySourceLength( verityDigest, apk.length(), signatureInfo); } result.digest = pickBestDigestForV4(contentDigests); return result; return new VerifiedSigner(result.first, result.second, verityRootHash, contentDigests); } private static VerifiedSigner verifySigner( private static Pair<X509Certificate[], VerifiedProofOfRotation> verifySigner( ByteBuffer signerBlock, Map<Integer, byte[]> contentDigests, CertificateFactory certFactory) Loading Loading @@ -349,8 +347,7 @@ public class ApkSignatureSchemeV3Verifier { } catch (CertificateException e) { throw new SecurityException("Failed to decode certificate #" + certificateCount, e); } certificate = new VerbatimX509Certificate( certificate, encodedCert); certificate = new VerbatimX509Certificate(certificate, encodedCert); certs.add(certificate); } Loading Loading @@ -382,8 +379,9 @@ public class ApkSignatureSchemeV3Verifier { private static final int PROOF_OF_ROTATION_ATTR_ID = 0x3ba06f8c; private static VerifiedSigner verifyAdditionalAttributes(ByteBuffer attrs, List<X509Certificate> certs, CertificateFactory certFactory) throws IOException { private static Pair<X509Certificate[], VerifiedProofOfRotation> verifyAdditionalAttributes( ByteBuffer attrs, List<X509Certificate> certs, CertificateFactory certFactory) throws IOException { X509Certificate[] certChain = certs.toArray(new X509Certificate[certs.size()]); VerifiedProofOfRotation por = null; Loading Loading @@ -421,7 +419,7 @@ public class ApkSignatureSchemeV3Verifier { break; } } return new VerifiedSigner(certChain, por); return Pair.create(certChain, por); } private static VerifiedProofOfRotation verifyProofOfRotationStruct( Loading Loading @@ -570,12 +568,17 @@ public class ApkSignatureSchemeV3Verifier { public final X509Certificate[] certs; public final VerifiedProofOfRotation por; public byte[] verityRootHash; public byte[] digest; public final byte[] verityRootHash; // Algorithm -> digest map of signed digests in the signature. // All these are verified if requested. public final Map<Integer, byte[]> contentDigests; public VerifiedSigner(X509Certificate[] certs, VerifiedProofOfRotation por) { public VerifiedSigner(X509Certificate[] certs, VerifiedProofOfRotation por, byte[] verityRootHash, Map<Integer, byte[]> contentDigests) { this.certs = certs; this.por = por; this.verityRootHash = verityRootHash; this.contentDigests = contentDigests; } } Loading
core/java/android/util/apk/ApkSignatureSchemeV4Verifier.java +30 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package android.util.apk; import static android.util.apk.ApkSigningBlockUtils.CONTENT_DIGEST_VERITY_CHUNKED_SHA256; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaKeyAlgorithm; import static android.util.apk.ApkSigningBlockUtils.getSignatureAlgorithmJcaSignatureAlgorithm; import static android.util.apk.ApkSigningBlockUtils.isSupportedSignatureAlgorithm; import android.os.incremental.IncrementalManager; import android.os.incremental.V4Signature; import android.util.ArrayMap; import android.util.Pair; import java.io.ByteArrayInputStream; Loading @@ -42,6 +44,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Map; /** * APK Signature Scheme v4 verifier. Loading Loading @@ -79,13 +82,20 @@ public class ApkSignatureSchemeV4Verifier { throw new SignatureNotFoundException("Failed to read V4 signature.", e); } final byte[] signedData = V4Signature.getSigningData(apk.length(), hashingInfo, // Verify signed data and extract certificates and apk digest. final byte[] signedData = V4Signature.getSignedData(apk.length(), hashingInfo, signingInfo); final Pair<Certificate, byte[]> result = verifySigner(signingInfo, signedData); return verifySigner(signingInfo, signedData); // Populate digests enforced by IncFS driver. Map<Integer, byte[]> contentDigests = new ArrayMap<>(); contentDigests.put(convertToContentDigestType(hashingInfo.hashAlgorithm), hashingInfo.rawRootHash); return new VerifiedSigner(new Certificate[]{result.first}, result.second, contentDigests); } private static VerifiedSigner verifySigner(V4Signature.SigningInfo signingInfo, private static Pair<Certificate, byte[]> verifySigner(V4Signature.SigningInfo signingInfo, final byte[] signedData) throws SecurityException { if (!isSupportedSignatureAlgorithm(signingInfo.signatureAlgorithmId)) { throw new SecurityException("No supported signatures found"); Loading Loading @@ -145,21 +155,34 @@ public class ApkSignatureSchemeV4Verifier { "Public key mismatch between certificate and signature record"); } return new VerifiedSigner(new Certificate[]{certificate}, signingInfo.apkDigest); return Pair.create(certificate, signingInfo.apkDigest); } private static int convertToContentDigestType(int hashAlgorithm) throws SecurityException { if (hashAlgorithm == V4Signature.HASHING_ALGORITHM_SHA256) { return CONTENT_DIGEST_VERITY_CHUNKED_SHA256; } throw new SecurityException("Unsupported hashAlgorithm: " + hashAlgorithm); } /** * Verified APK Signature Scheme v4 signer, including V3 digest. * Verified APK Signature Scheme v4 signer, including V2/V3 digest. * * @hide for internal use only. */ public static class VerifiedSigner { public final Certificate[] certs; public byte[] apkDigest; public final byte[] apkDigest; // Algorithm -> digest map of signed digests in the signature. // These are continuously enforced by the IncFS driver. public final Map<Integer, byte[]> contentDigests; public VerifiedSigner(Certificate[] certs, byte[] apkDigest) { public VerifiedSigner(Certificate[] certs, byte[] apkDigest, Map<Integer, byte[]> contentDigests) { this.certs = certs; this.apkDigest = apkDigest; this.contentDigests = contentDigests; } } Loading
core/java/android/util/apk/ApkSignatureVerifier.java +14 −6 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import java.security.cert.CertificateEncodingException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.zip.ZipEntry; Loading Loading @@ -184,21 +185,21 @@ public class ApkSignatureVerifier { Signature[] signerSigs = convertToSignatures(signerCerts); if (verifyFull) { byte[] nonstreamingDigest = null; Certificate[][] nonstreamingCerts = null; Map<Integer, byte[]> nonstreamingDigests; Certificate[][] nonstreamingCerts; try { // v4 is an add-on and requires v2 or v3 signature to validate against its // certificate and digest ApkSignatureSchemeV3Verifier.VerifiedSigner v3Signer = ApkSignatureSchemeV3Verifier.unsafeGetCertsWithoutVerification(apkPath); nonstreamingDigest = v3Signer.digest; nonstreamingDigests = v3Signer.contentDigests; nonstreamingCerts = new Certificate[][]{v3Signer.certs}; } catch (SignatureNotFoundException e) { try { ApkSignatureSchemeV2Verifier.VerifiedSigner v2Signer = ApkSignatureSchemeV2Verifier.verify(apkPath, false); nonstreamingDigest = v2Signer.digest; nonstreamingDigests = v2Signer.contentDigests; nonstreamingCerts = v2Signer.certs; } catch (SignatureNotFoundException ee) { throw new SecurityException( Loading @@ -220,8 +221,15 @@ public class ApkSignatureVerifier { } } if (!ArrayUtils.equals(vSigner.apkDigest, nonstreamingDigest, boolean found = false; for (byte[] nonstreamingDigest : nonstreamingDigests.values()) { if (ArrayUtils.equals(vSigner.apkDigest, nonstreamingDigest, vSigner.apkDigest.length)) { found = true; break; } } if (!found) { throw new SecurityException("APK digest in V4 signature does not match V2/V3"); } } Loading