Loading tools/apksigner/core/src/com/android/apksigner/core/ApkSignerEngine.java +13 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.apksigner.core; import java.io.Closeable; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.util.List; Loading Loading @@ -182,13 +183,17 @@ public interface ApkSignerEngine extends Closeable { * request must be fulfilled before * {@link #outputZipSections(DataSource, DataSource, DataSource)} is invoked. * * @throws NoSuchAlgorithmException if a signature could not be generated because a required * cryptographic algorithm implementation is missing * @throws InvalidKeyException if a signature could not be generated because a signing key is * not suitable for generating the signature * @throws SignatureException if an error occurred while generating the JAR signature * @throws SignatureException if an error occurred while generating a signature * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR * entries, or if the engine is closed */ OutputJarSignatureRequest outputJarEntries() throws InvalidKeyException, SignatureException; OutputJarSignatureRequest outputJarEntries() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IllegalStateException; /** * Indicates to this engine that the ZIP sections comprising the output APK have been output. Loading @@ -207,16 +212,20 @@ public interface ApkSignerEngine extends Closeable { * {@link #outputDone()} is invoked. * * @throws IOException if an I/O error occurs while reading the provided ZIP sections * @throws NoSuchAlgorithmException if a signature could not be generated because a required * cryptographic algorithm implementation is missing * @throws InvalidKeyException if a signature could not be generated because a signing key is * not suitable for generating the signature * @throws SignatureException if an error occurred while generating the APK's signature * @throws SignatureException if an error occurred while generating a signature * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR * entries or to output JAR signature, or if the engine is closed */ OutputApkSigningBlockRequest outputZipSections( DataSource zipEntries, DataSource zipCentralDirectory, DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException; DataSource zipEocd) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, IllegalStateException; /** * Indicates to this engine that the signed APK was output. Loading tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java +4 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.apksigner.core.util.DataSource; import com.android.apksigner.core.zip.ZipFormatException; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; Loading Loading @@ -61,9 +62,11 @@ public class ApkVerifier { * * @throws IOException if an I/O error is encountered while reading the APK * @throws ZipFormatException if the APK is malformed at ZIP format level * @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a * required cryptographic algorithm implementation is missing */ public Result verify(DataSource apk, int minSdkVersion, int maxSdkVersion) throws IOException, ZipFormatException { throws IOException, ZipFormatException, NoSuchAlgorithmException { if (minSdkVersion < 0) { throw new IllegalArgumentException( "minSdkVersion must not be negative: " + minSdkVersion); Loading tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java +4 −2 Original line number Diff line number Diff line Loading @@ -293,7 +293,7 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { @Override public OutputJarSignatureRequest outputJarEntries() throws InvalidKeyException, SignatureException { throws InvalidKeyException, SignatureException, NoSuchAlgorithmException { checkNotClosed(); if (!mV1SignaturePending) { Loading Loading @@ -413,7 +413,9 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { public OutputApkSigningBlockRequest outputZipSections( DataSource zipEntries, DataSource zipCentralDirectory, DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException { DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException { checkNotClosed(); checkV1SigningDoneIfEnabled(); if (!mV2SigningEnabled) { Loading tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java +16 −20 Original line number Diff line number Diff line Loading @@ -155,13 +155,10 @@ public abstract class V1SchemeSigner { /** * Returns a new {@link MessageDigest} instance corresponding to the provided digest algorithm. */ public static MessageDigest getMessageDigestInstance(DigestAlgorithm digestAlgorithm) { private static MessageDigest getMessageDigestInstance(DigestAlgorithm digestAlgorithm) throws NoSuchAlgorithmException { String jcaAlgorithm = digestAlgorithm.getJcaMessageDigestAlgorithm(); try { return MessageDigest.getInstance(jcaAlgorithm); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Failed to obtain " + jcaAlgorithm + " MessageDigest", e); } } /** Loading Loading @@ -215,6 +212,8 @@ public abstract class V1SchemeSigner { * @param signerConfigs signer configurations, one for each signer. At least one signer config * must be provided. * * @throws NoSuchAlgorithmException if a required cryptographic algorithm implementation is * missing * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or * cannot be used in general * @throws SignatureException if an error occurs when computing digests of generating Loading @@ -226,7 +225,8 @@ public abstract class V1SchemeSigner { Map<String, byte[]> jarEntryDigests, List<Integer> apkSigningSchemeIds, byte[] sourceManifestBytes) throws InvalidKeyException, CertificateException, SignatureException { throws NoSuchAlgorithmException, InvalidKeyException, CertificateException, SignatureException { if (signerConfigs.isEmpty()) { throw new IllegalArgumentException("At least one signer config must be provided"); } Loading @@ -253,7 +253,8 @@ public abstract class V1SchemeSigner { DigestAlgorithm digestAlgorithm, List<Integer> apkSigningSchemeIds, OutputManifestFile manifest) throws InvalidKeyException, CertificateException, SignatureException { throws NoSuchAlgorithmException, InvalidKeyException, CertificateException, SignatureException { if (signerConfigs.isEmpty()) { throw new IllegalArgumentException("At least one signer config must be provided"); } Loading Loading @@ -378,7 +379,7 @@ public abstract class V1SchemeSigner { private static byte[] generateSignatureFile( List<Integer> apkSignatureSchemeIds, DigestAlgorithm manifestDigestAlgorithm, OutputManifestFile manifest) { OutputManifestFile manifest) throws NoSuchAlgorithmException { Manifest sf = new Manifest(); Attributes mainAttrs = sf.getMainAttributes(); mainAttrs.put(Attributes.Name.SIGNATURE_VERSION, ATTRIBUTE_VALUE_SIGNATURE_VERSION); Loading Loading @@ -447,7 +448,8 @@ public abstract class V1SchemeSigner { @SuppressWarnings("restriction") private static byte[] generateSignatureBlock( SignerConfig signerConfig, byte[] signatureFileBytes) throws InvalidKeyException, CertificateException, SignatureException { throws NoSuchAlgorithmException, InvalidKeyException, CertificateException, SignatureException { List<X509Certificate> signerCerts = signerConfig.certificates; X509Certificate signerCert = signerCerts.get(0); PublicKey signerPublicKey = signerCert.getPublicKey(); Loading @@ -455,16 +457,10 @@ public abstract class V1SchemeSigner { Pair<String, AlgorithmId> signatureAlgs = getSignerInfoSignatureAlgorithm(signerPublicKey, digestAlgorithm); String jcaSignatureAlgorithm = signatureAlgs.getFirst(); byte[] signatureBytes; try { Signature signature = Signature.getInstance(jcaSignatureAlgorithm); signature.initSign(signerConfig.privateKey); signature.update(signatureFileBytes); signatureBytes = signature.sign(); } catch (NoSuchAlgorithmException e) { throw new SignatureException( jcaSignatureAlgorithm + " Signature implementation not found", e); } byte[] signatureBytes = signature.sign(); X500Name issuerName; try { Loading tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeVerifier.java +23 −33 Original line number Diff line number Diff line Loading @@ -72,6 +72,8 @@ public abstract class V1SchemeVerifier { * * @throws ZipFormatException if the APK is malformed * @throws IOException if an I/O error occurs when reading the APK * @throws NoSuchAlgorithmException if the APK's JAR signatures cannot be verified because a * required cryptographic algorithm implementation is missing */ public static Result verify( DataSource apk, Loading @@ -79,7 +81,7 @@ public abstract class V1SchemeVerifier { Map<Integer, String> supportedApkSigSchemeNames, Set<Integer> foundApkSigSchemeIds, int minSdkVersion, int maxSdkVersion) throws IOException, ZipFormatException { int maxSdkVersion) throws IOException, ZipFormatException, NoSuchAlgorithmException { if (minSdkVersion > maxSdkVersion) { throw new IllegalArgumentException( "minSdkVersion (" + minSdkVersion + ") > maxSdkVersion (" + maxSdkVersion Loading Loading @@ -152,7 +154,7 @@ public abstract class V1SchemeVerifier { Set<Integer> foundApkSigSchemeIds, int minSdkVersion, int maxSdkVersion, Result result) throws ZipFormatException, IOException { Result result) throws ZipFormatException, IOException, NoSuchAlgorithmException { // Find JAR manifest and signature block files. CentralDirectoryRecord manifestEntry = null; Loading Loading @@ -312,6 +314,8 @@ public abstract class V1SchemeVerifier { cdRecords, entryNameToManifestSection, signers, minSdkVersion, maxSdkVersion, result); if (result.containsErrors()) { return; Loading Loading @@ -405,7 +409,7 @@ public abstract class V1SchemeVerifier { @SuppressWarnings("restriction") public void verifySigBlockAgainstSigFile( DataSource apk, long cdStartOffset, int minSdkVersion, int maxSdkVersion) throws IOException, ZipFormatException { throws IOException, ZipFormatException, NoSuchAlgorithmException { byte[] sigBlockBytes = LocalFileHeader.getUncompressedData( apk, 0, Loading Loading @@ -461,7 +465,7 @@ public abstract class V1SchemeVerifier { } try { verifiedSignerInfo = sigBlock.verify(unverifiedSignerInfo, mSigFileBytes); } catch (NoSuchAlgorithmException | SignatureException e) { } catch (SignatureException e) { mResult.addError( Issue.JAR_SIG_VERIFY_EXCEPTION, mSignatureBlockEntry.getName(), Loading Loading @@ -856,7 +860,7 @@ public abstract class V1SchemeVerifier { Map<Integer, String> supportedApkSigSchemeNames, Set<Integer> foundApkSigSchemeIds, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { // Inspect the main section of the .SF file. ManifestParser sf = new ManifestParser(mSigFileBytes); ManifestParser.Section sfMainSection = sf.readSection(); Loading Loading @@ -965,7 +969,7 @@ public abstract class V1SchemeVerifier { boolean createdBySigntool, byte[] manifestBytes, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { Collection<NamedDigest> expectedDigests = getDigestsToVerify( sfMainSection, Loading Loading @@ -1008,7 +1012,7 @@ public abstract class V1SchemeVerifier { ManifestParser.Section manifestMainSection, byte[] manifestBytes, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { Collection<NamedDigest> expectedDigests = getDigestsToVerify( sfMainSection, Loading Loading @@ -1049,7 +1053,7 @@ public abstract class V1SchemeVerifier { ManifestParser.Section manifestIndividualSection, byte[] manifestBytes, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { String entryName = sfIndividualSection.getName(); Collection<NamedDigest> expectedDigests = getDigestsToVerify( Loading Loading @@ -1344,7 +1348,9 @@ public abstract class V1SchemeVerifier { Collection<CentralDirectoryRecord> cdRecords, Map<String, ManifestParser.Section> entryNameToManifestSection, List<Signer> signers, Result result) throws ZipFormatException, IOException { int minSdkVersion, int maxSdkVersion, Result result) throws ZipFormatException, IOException, NoSuchAlgorithmException { // Iterate over APK contents as sequentially as possible to improve performance. List<CentralDirectoryRecord> cdRecordsSortedByLocalFileHeaderOffset = new ArrayList<>(cdRecords); Loading Loading @@ -1391,22 +1397,8 @@ public abstract class V1SchemeVerifier { continue; } List<NamedDigest> expectedDigests = new ArrayList<>(); for (ManifestParser.Attribute attr : manifestSection.getAttributes()) { String name = attr.getName(); String nameUpperCase = name.toUpperCase(Locale.US); if (!nameUpperCase.endsWith("-DIGEST")) { continue; } String jcaDigestAlgorithm = nameUpperCase.substring(0, nameUpperCase.length() - "-DIGEST".length()); if ("SHA1".equals(jcaDigestAlgorithm)) { jcaDigestAlgorithm = "SHA-1"; } byte[] digest = Base64.getDecoder().decode(attr.getValue()); expectedDigests.add(new NamedDigest(jcaDigestAlgorithm, digest)); } Collection<NamedDigest> expectedDigests = getDigestsToVerify(manifestSection, "-Digest", minSdkVersion, maxSdkVersion); if (expectedDigests.isEmpty()) { result.addError(Issue.JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_MANIFEST, entryName); continue; Loading Loading @@ -1465,21 +1457,19 @@ public abstract class V1SchemeVerifier { return result; } private static MessageDigest getMessageDigest(String algorithm) { try { private static MessageDigest getMessageDigest(String algorithm) throws NoSuchAlgorithmException { return MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Failed to obtain " + algorithm + " MessageDigest", e); } } private static byte[] digest(String algorithm, byte[] data, int offset, int length) { private static byte[] digest(String algorithm, byte[] data, int offset, int length) throws NoSuchAlgorithmException { MessageDigest md = getMessageDigest(algorithm); md.update(data, offset, length); return md.digest(); } private static byte[] digest(String algorithm, byte[] data) { private static byte[] digest(String algorithm, byte[] data) throws NoSuchAlgorithmException { return getMessageDigest(algorithm).digest(data); } Loading Loading
tools/apksigner/core/src/com/android/apksigner/core/ApkSignerEngine.java +13 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.apksigner.core; import java.io.Closeable; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; import java.util.List; Loading Loading @@ -182,13 +183,17 @@ public interface ApkSignerEngine extends Closeable { * request must be fulfilled before * {@link #outputZipSections(DataSource, DataSource, DataSource)} is invoked. * * @throws NoSuchAlgorithmException if a signature could not be generated because a required * cryptographic algorithm implementation is missing * @throws InvalidKeyException if a signature could not be generated because a signing key is * not suitable for generating the signature * @throws SignatureException if an error occurred while generating the JAR signature * @throws SignatureException if an error occurred while generating a signature * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR * entries, or if the engine is closed */ OutputJarSignatureRequest outputJarEntries() throws InvalidKeyException, SignatureException; OutputJarSignatureRequest outputJarEntries() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IllegalStateException; /** * Indicates to this engine that the ZIP sections comprising the output APK have been output. Loading @@ -207,16 +212,20 @@ public interface ApkSignerEngine extends Closeable { * {@link #outputDone()} is invoked. * * @throws IOException if an I/O error occurs while reading the provided ZIP sections * @throws NoSuchAlgorithmException if a signature could not be generated because a required * cryptographic algorithm implementation is missing * @throws InvalidKeyException if a signature could not be generated because a signing key is * not suitable for generating the signature * @throws SignatureException if an error occurred while generating the APK's signature * @throws SignatureException if an error occurred while generating a signature * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR * entries or to output JAR signature, or if the engine is closed */ OutputApkSigningBlockRequest outputZipSections( DataSource zipEntries, DataSource zipCentralDirectory, DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException; DataSource zipEocd) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException, IllegalStateException; /** * Indicates to this engine that the signed APK was output. Loading
tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java +4 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.apksigner.core.util.DataSource; import com.android.apksigner.core.zip.ZipFormatException; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; Loading Loading @@ -61,9 +62,11 @@ public class ApkVerifier { * * @throws IOException if an I/O error is encountered while reading the APK * @throws ZipFormatException if the APK is malformed at ZIP format level * @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a * required cryptographic algorithm implementation is missing */ public Result verify(DataSource apk, int minSdkVersion, int maxSdkVersion) throws IOException, ZipFormatException { throws IOException, ZipFormatException, NoSuchAlgorithmException { if (minSdkVersion < 0) { throw new IllegalArgumentException( "minSdkVersion must not be negative: " + minSdkVersion); Loading
tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java +4 −2 Original line number Diff line number Diff line Loading @@ -293,7 +293,7 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { @Override public OutputJarSignatureRequest outputJarEntries() throws InvalidKeyException, SignatureException { throws InvalidKeyException, SignatureException, NoSuchAlgorithmException { checkNotClosed(); if (!mV1SignaturePending) { Loading Loading @@ -413,7 +413,9 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { public OutputApkSigningBlockRequest outputZipSections( DataSource zipEntries, DataSource zipCentralDirectory, DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException { DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException { checkNotClosed(); checkV1SigningDoneIfEnabled(); if (!mV2SigningEnabled) { Loading
tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java +16 −20 Original line number Diff line number Diff line Loading @@ -155,13 +155,10 @@ public abstract class V1SchemeSigner { /** * Returns a new {@link MessageDigest} instance corresponding to the provided digest algorithm. */ public static MessageDigest getMessageDigestInstance(DigestAlgorithm digestAlgorithm) { private static MessageDigest getMessageDigestInstance(DigestAlgorithm digestAlgorithm) throws NoSuchAlgorithmException { String jcaAlgorithm = digestAlgorithm.getJcaMessageDigestAlgorithm(); try { return MessageDigest.getInstance(jcaAlgorithm); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Failed to obtain " + jcaAlgorithm + " MessageDigest", e); } } /** Loading Loading @@ -215,6 +212,8 @@ public abstract class V1SchemeSigner { * @param signerConfigs signer configurations, one for each signer. At least one signer config * must be provided. * * @throws NoSuchAlgorithmException if a required cryptographic algorithm implementation is * missing * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or * cannot be used in general * @throws SignatureException if an error occurs when computing digests of generating Loading @@ -226,7 +225,8 @@ public abstract class V1SchemeSigner { Map<String, byte[]> jarEntryDigests, List<Integer> apkSigningSchemeIds, byte[] sourceManifestBytes) throws InvalidKeyException, CertificateException, SignatureException { throws NoSuchAlgorithmException, InvalidKeyException, CertificateException, SignatureException { if (signerConfigs.isEmpty()) { throw new IllegalArgumentException("At least one signer config must be provided"); } Loading @@ -253,7 +253,8 @@ public abstract class V1SchemeSigner { DigestAlgorithm digestAlgorithm, List<Integer> apkSigningSchemeIds, OutputManifestFile manifest) throws InvalidKeyException, CertificateException, SignatureException { throws NoSuchAlgorithmException, InvalidKeyException, CertificateException, SignatureException { if (signerConfigs.isEmpty()) { throw new IllegalArgumentException("At least one signer config must be provided"); } Loading Loading @@ -378,7 +379,7 @@ public abstract class V1SchemeSigner { private static byte[] generateSignatureFile( List<Integer> apkSignatureSchemeIds, DigestAlgorithm manifestDigestAlgorithm, OutputManifestFile manifest) { OutputManifestFile manifest) throws NoSuchAlgorithmException { Manifest sf = new Manifest(); Attributes mainAttrs = sf.getMainAttributes(); mainAttrs.put(Attributes.Name.SIGNATURE_VERSION, ATTRIBUTE_VALUE_SIGNATURE_VERSION); Loading Loading @@ -447,7 +448,8 @@ public abstract class V1SchemeSigner { @SuppressWarnings("restriction") private static byte[] generateSignatureBlock( SignerConfig signerConfig, byte[] signatureFileBytes) throws InvalidKeyException, CertificateException, SignatureException { throws NoSuchAlgorithmException, InvalidKeyException, CertificateException, SignatureException { List<X509Certificate> signerCerts = signerConfig.certificates; X509Certificate signerCert = signerCerts.get(0); PublicKey signerPublicKey = signerCert.getPublicKey(); Loading @@ -455,16 +457,10 @@ public abstract class V1SchemeSigner { Pair<String, AlgorithmId> signatureAlgs = getSignerInfoSignatureAlgorithm(signerPublicKey, digestAlgorithm); String jcaSignatureAlgorithm = signatureAlgs.getFirst(); byte[] signatureBytes; try { Signature signature = Signature.getInstance(jcaSignatureAlgorithm); signature.initSign(signerConfig.privateKey); signature.update(signatureFileBytes); signatureBytes = signature.sign(); } catch (NoSuchAlgorithmException e) { throw new SignatureException( jcaSignatureAlgorithm + " Signature implementation not found", e); } byte[] signatureBytes = signature.sign(); X500Name issuerName; try { Loading
tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeVerifier.java +23 −33 Original line number Diff line number Diff line Loading @@ -72,6 +72,8 @@ public abstract class V1SchemeVerifier { * * @throws ZipFormatException if the APK is malformed * @throws IOException if an I/O error occurs when reading the APK * @throws NoSuchAlgorithmException if the APK's JAR signatures cannot be verified because a * required cryptographic algorithm implementation is missing */ public static Result verify( DataSource apk, Loading @@ -79,7 +81,7 @@ public abstract class V1SchemeVerifier { Map<Integer, String> supportedApkSigSchemeNames, Set<Integer> foundApkSigSchemeIds, int minSdkVersion, int maxSdkVersion) throws IOException, ZipFormatException { int maxSdkVersion) throws IOException, ZipFormatException, NoSuchAlgorithmException { if (minSdkVersion > maxSdkVersion) { throw new IllegalArgumentException( "minSdkVersion (" + minSdkVersion + ") > maxSdkVersion (" + maxSdkVersion Loading Loading @@ -152,7 +154,7 @@ public abstract class V1SchemeVerifier { Set<Integer> foundApkSigSchemeIds, int minSdkVersion, int maxSdkVersion, Result result) throws ZipFormatException, IOException { Result result) throws ZipFormatException, IOException, NoSuchAlgorithmException { // Find JAR manifest and signature block files. CentralDirectoryRecord manifestEntry = null; Loading Loading @@ -312,6 +314,8 @@ public abstract class V1SchemeVerifier { cdRecords, entryNameToManifestSection, signers, minSdkVersion, maxSdkVersion, result); if (result.containsErrors()) { return; Loading Loading @@ -405,7 +409,7 @@ public abstract class V1SchemeVerifier { @SuppressWarnings("restriction") public void verifySigBlockAgainstSigFile( DataSource apk, long cdStartOffset, int minSdkVersion, int maxSdkVersion) throws IOException, ZipFormatException { throws IOException, ZipFormatException, NoSuchAlgorithmException { byte[] sigBlockBytes = LocalFileHeader.getUncompressedData( apk, 0, Loading Loading @@ -461,7 +465,7 @@ public abstract class V1SchemeVerifier { } try { verifiedSignerInfo = sigBlock.verify(unverifiedSignerInfo, mSigFileBytes); } catch (NoSuchAlgorithmException | SignatureException e) { } catch (SignatureException e) { mResult.addError( Issue.JAR_SIG_VERIFY_EXCEPTION, mSignatureBlockEntry.getName(), Loading Loading @@ -856,7 +860,7 @@ public abstract class V1SchemeVerifier { Map<Integer, String> supportedApkSigSchemeNames, Set<Integer> foundApkSigSchemeIds, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { // Inspect the main section of the .SF file. ManifestParser sf = new ManifestParser(mSigFileBytes); ManifestParser.Section sfMainSection = sf.readSection(); Loading Loading @@ -965,7 +969,7 @@ public abstract class V1SchemeVerifier { boolean createdBySigntool, byte[] manifestBytes, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { Collection<NamedDigest> expectedDigests = getDigestsToVerify( sfMainSection, Loading Loading @@ -1008,7 +1012,7 @@ public abstract class V1SchemeVerifier { ManifestParser.Section manifestMainSection, byte[] manifestBytes, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { Collection<NamedDigest> expectedDigests = getDigestsToVerify( sfMainSection, Loading Loading @@ -1049,7 +1053,7 @@ public abstract class V1SchemeVerifier { ManifestParser.Section manifestIndividualSection, byte[] manifestBytes, int minSdkVersion, int maxSdkVersion) { int maxSdkVersion) throws NoSuchAlgorithmException { String entryName = sfIndividualSection.getName(); Collection<NamedDigest> expectedDigests = getDigestsToVerify( Loading Loading @@ -1344,7 +1348,9 @@ public abstract class V1SchemeVerifier { Collection<CentralDirectoryRecord> cdRecords, Map<String, ManifestParser.Section> entryNameToManifestSection, List<Signer> signers, Result result) throws ZipFormatException, IOException { int minSdkVersion, int maxSdkVersion, Result result) throws ZipFormatException, IOException, NoSuchAlgorithmException { // Iterate over APK contents as sequentially as possible to improve performance. List<CentralDirectoryRecord> cdRecordsSortedByLocalFileHeaderOffset = new ArrayList<>(cdRecords); Loading Loading @@ -1391,22 +1397,8 @@ public abstract class V1SchemeVerifier { continue; } List<NamedDigest> expectedDigests = new ArrayList<>(); for (ManifestParser.Attribute attr : manifestSection.getAttributes()) { String name = attr.getName(); String nameUpperCase = name.toUpperCase(Locale.US); if (!nameUpperCase.endsWith("-DIGEST")) { continue; } String jcaDigestAlgorithm = nameUpperCase.substring(0, nameUpperCase.length() - "-DIGEST".length()); if ("SHA1".equals(jcaDigestAlgorithm)) { jcaDigestAlgorithm = "SHA-1"; } byte[] digest = Base64.getDecoder().decode(attr.getValue()); expectedDigests.add(new NamedDigest(jcaDigestAlgorithm, digest)); } Collection<NamedDigest> expectedDigests = getDigestsToVerify(manifestSection, "-Digest", minSdkVersion, maxSdkVersion); if (expectedDigests.isEmpty()) { result.addError(Issue.JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_MANIFEST, entryName); continue; Loading Loading @@ -1465,21 +1457,19 @@ public abstract class V1SchemeVerifier { return result; } private static MessageDigest getMessageDigest(String algorithm) { try { private static MessageDigest getMessageDigest(String algorithm) throws NoSuchAlgorithmException { return MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("Failed to obtain " + algorithm + " MessageDigest", e); } } private static byte[] digest(String algorithm, byte[] data, int offset, int length) { private static byte[] digest(String algorithm, byte[] data, int offset, int length) throws NoSuchAlgorithmException { MessageDigest md = getMessageDigest(algorithm); md.update(data, offset, length); return md.digest(); } private static byte[] digest(String algorithm, byte[] data) { private static byte[] digest(String algorithm, byte[] data) throws NoSuchAlgorithmException { return getMessageDigest(algorithm).digest(data); } Loading