@Test public void testLineageFromAPKWithNoLineageFails() throws Exception { DataSource apkDataSource = Resources.toDataSource(getClass(), "golden-aligned-v1v2-out.apk"); try { SigningCertificateLineage.readFromApkDataSource(apkDataSource); fail("A failure should have been reported due to the APK not containing a V3 signing " + "block"); } catch (IllegalArgumentException expected) {} apkDataSource = Resources.toDataSource(getClass(), "golden-aligned-v1v2v3-out.apk"); try { SigningCertificateLineage.readFromApkDataSource(apkDataSource); fail("A failure should have been reported due to the APK containing a V3 signing " + "block without the lineage attribute"); } catch (IllegalArgumentException expected) {} apkDataSource = Resources.toDataSource(getClass(), "v1v2v3-with-rsa-2048-lineage-3-signers-invalid-lineage-attr.apk"); try { SigningCertificateLineage.readFromApkDataSource(apkDataSource); fail("A failure should have been reported due to the APK containing a V3 signing " + "block with a modified lineage attribute ID"); } catch (IllegalArgumentException expected) {} }
public static SigningCertificateLineage readFromApkDataSource(DataSource apk) throws IOException, ApkFormatException { SignatureInfo signatureInfo; try { ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk); ApkSigningBlockUtils.Result result = new ApkSigningBlockUtils.Result( ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V3); signatureInfo = ApkSigningBlockUtils.findSignature(apk, zipSections, V3SchemeSigner.APK_SIGNATURE_SCHEME_V3_BLOCK_ID, result); } catch (ZipFormatException e) { throw new ApkFormatException(e.getMessage()); } catch (ApkSigningBlockUtils.SignatureNotFoundException e) { throw new IllegalArgumentException( "The provided APK does not contain a valid V3 signature block."); } ByteBuffer signers = getLengthPrefixedSlice(signatureInfo.signatureBlock); List<SigningCertificateLineage> lineages = new ArrayList<>(1); while (signers.hasRemaining()) { ByteBuffer signer = getLengthPrefixedSlice(signers); ByteBuffer signedData = getLengthPrefixedSlice(signer); try { SigningCertificateLineage lineage = readFromSignedData(signedData); lineages.add(lineage); } catch (IllegalArgumentException ignored) { } } SigningCertificateLineage result; if (lineages.isEmpty()) { throw new IllegalArgumentException( "The provided APK does not contain a valid lineage."); } else if (lineages.size() > 1) { result = consolidateLineages(lineages); } else { result = lineages.get(0); } return result; }
SigningCertificateLineage { public static SigningCertificateLineage readFromApkDataSource(DataSource apk) throws IOException, ApkFormatException { SignatureInfo signatureInfo; try { ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk); ApkSigningBlockUtils.Result result = new ApkSigningBlockUtils.Result( ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V3); signatureInfo = ApkSigningBlockUtils.findSignature(apk, zipSections, V3SchemeSigner.APK_SIGNATURE_SCHEME_V3_BLOCK_ID, result); } catch (ZipFormatException e) { throw new ApkFormatException(e.getMessage()); } catch (ApkSigningBlockUtils.SignatureNotFoundException e) { throw new IllegalArgumentException( "The provided APK does not contain a valid V3 signature block."); } ByteBuffer signers = getLengthPrefixedSlice(signatureInfo.signatureBlock); List<SigningCertificateLineage> lineages = new ArrayList<>(1); while (signers.hasRemaining()) { ByteBuffer signer = getLengthPrefixedSlice(signers); ByteBuffer signedData = getLengthPrefixedSlice(signer); try { SigningCertificateLineage lineage = readFromSignedData(signedData); lineages.add(lineage); } catch (IllegalArgumentException ignored) { } } SigningCertificateLineage result; if (lineages.isEmpty()) { throw new IllegalArgumentException( "The provided APK does not contain a valid lineage."); } else if (lineages.size() > 1) { result = consolidateLineages(lineages); } else { result = lineages.get(0); } return result; } }
SigningCertificateLineage { public static SigningCertificateLineage readFromApkDataSource(DataSource apk) throws IOException, ApkFormatException { SignatureInfo signatureInfo; try { ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk); ApkSigningBlockUtils.Result result = new ApkSigningBlockUtils.Result( ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V3); signatureInfo = ApkSigningBlockUtils.findSignature(apk, zipSections, V3SchemeSigner.APK_SIGNATURE_SCHEME_V3_BLOCK_ID, result); } catch (ZipFormatException e) { throw new ApkFormatException(e.getMessage()); } catch (ApkSigningBlockUtils.SignatureNotFoundException e) { throw new IllegalArgumentException( "The provided APK does not contain a valid V3 signature block."); } ByteBuffer signers = getLengthPrefixedSlice(signatureInfo.signatureBlock); List<SigningCertificateLineage> lineages = new ArrayList<>(1); while (signers.hasRemaining()) { ByteBuffer signer = getLengthPrefixedSlice(signers); ByteBuffer signedData = getLengthPrefixedSlice(signer); try { SigningCertificateLineage lineage = readFromSignedData(signedData); lineages.add(lineage); } catch (IllegalArgumentException ignored) { } } SigningCertificateLineage result; if (lineages.isEmpty()) { throw new IllegalArgumentException( "The provided APK does not contain a valid lineage."); } else if (lineages.size() > 1) { result = consolidateLineages(lineages); } else { result = lineages.get(0); } return result; } private  SigningCertificateLineage(int minSdkVersion, List<SigningCertificateNode> list); }
SigningCertificateLineage { public static SigningCertificateLineage readFromApkDataSource(DataSource apk) throws IOException, ApkFormatException { SignatureInfo signatureInfo; try { ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk); ApkSigningBlockUtils.Result result = new ApkSigningBlockUtils.Result( ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V3); signatureInfo = ApkSigningBlockUtils.findSignature(apk, zipSections, V3SchemeSigner.APK_SIGNATURE_SCHEME_V3_BLOCK_ID, result); } catch (ZipFormatException e) { throw new ApkFormatException(e.getMessage()); } catch (ApkSigningBlockUtils.SignatureNotFoundException e) { throw new IllegalArgumentException( "The provided APK does not contain a valid V3 signature block."); } ByteBuffer signers = getLengthPrefixedSlice(signatureInfo.signatureBlock); List<SigningCertificateLineage> lineages = new ArrayList<>(1); while (signers.hasRemaining()) { ByteBuffer signer = getLengthPrefixedSlice(signers); ByteBuffer signedData = getLengthPrefixedSlice(signer); try { SigningCertificateLineage lineage = readFromSignedData(signedData); lineages.add(lineage); } catch (IllegalArgumentException ignored) { } } SigningCertificateLineage result; if (lineages.isEmpty()) { throw new IllegalArgumentException( "The provided APK does not contain a valid lineage."); } else if (lineages.size() > 1) { result = consolidateLineages(lineages); } else { result = lineages.get(0); } return result; } private  SigningCertificateLineage(int minSdkVersion, List<SigningCertificateNode> list); static SigningCertificateLineage readFromFile(File file); static SigningCertificateLineage readFromDataSource(DataSource dataSource); static SigningCertificateLineage readFromV3AttributeValue(byte[] attrValue); static SigningCertificateLineage readFromApkFile(File apkFile); static SigningCertificateLineage readFromApkDataSource(DataSource apk); static SigningCertificateLineage readFromSignedData(ByteBuffer signedData); void writeToFile(File file); void writeToDataSink(DataSink dataSink); SigningCertificateLineage spawnDescendant(SignerConfig parent, SignerConfig child); SigningCertificateLineage spawnDescendant(
            SignerConfig parent, SignerConfig child, SignerCapabilities childCapabilities); int size(); byte[] generateV3SignerAttribute(); List<DefaultApkSignerEngine.SignerConfig> sortSignerConfigs(
            List<DefaultApkSignerEngine.SignerConfig> signerConfigs); SignerCapabilities getSignerCapabilities(SignerConfig config); SignerCapabilities getSignerCapabilities(X509Certificate cert); void updateSignerCapabilities(SignerConfig config, SignerCapabilities capabilities); List<X509Certificate> getCertificatesInLineage(); boolean isSignerInLineage(SignerConfig config); boolean isCertificateInLineage(X509Certificate cert); SigningCertificateLineage getSubLineage(X509Certificate x509Certificate); static SigningCertificateLineage consolidateLineages(
            List<SigningCertificateLineage> lineages); }
SigningCertificateLineage { public static SigningCertificateLineage readFromApkDataSource(DataSource apk) throws IOException, ApkFormatException { SignatureInfo signatureInfo; try { ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk); ApkSigningBlockUtils.Result result = new ApkSigningBlockUtils.Result( ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V3); signatureInfo = ApkSigningBlockUtils.findSignature(apk, zipSections, V3SchemeSigner.APK_SIGNATURE_SCHEME_V3_BLOCK_ID, result); } catch (ZipFormatException e) { throw new ApkFormatException(e.getMessage()); } catch (ApkSigningBlockUtils.SignatureNotFoundException e) { throw new IllegalArgumentException( "The provided APK does not contain a valid V3 signature block."); } ByteBuffer signers = getLengthPrefixedSlice(signatureInfo.signatureBlock); List<SigningCertificateLineage> lineages = new ArrayList<>(1); while (signers.hasRemaining()) { ByteBuffer signer = getLengthPrefixedSlice(signers); ByteBuffer signedData = getLengthPrefixedSlice(signer); try { SigningCertificateLineage lineage = readFromSignedData(signedData); lineages.add(lineage); } catch (IllegalArgumentException ignored) { } } SigningCertificateLineage result; if (lineages.isEmpty()) { throw new IllegalArgumentException( "The provided APK does not contain a valid lineage."); } else if (lineages.size() > 1) { result = consolidateLineages(lineages); } else { result = lineages.get(0); } return result; } private  SigningCertificateLineage(int minSdkVersion, List<SigningCertificateNode> list); static SigningCertificateLineage readFromFile(File file); static SigningCertificateLineage readFromDataSource(DataSource dataSource); static SigningCertificateLineage readFromV3AttributeValue(byte[] attrValue); static SigningCertificateLineage readFromApkFile(File apkFile); static SigningCertificateLineage readFromApkDataSource(DataSource apk); static SigningCertificateLineage readFromSignedData(ByteBuffer signedData); void writeToFile(File file); void writeToDataSink(DataSink dataSink); SigningCertificateLineage spawnDescendant(SignerConfig parent, SignerConfig child); SigningCertificateLineage spawnDescendant(
            SignerConfig parent, SignerConfig child, SignerCapabilities childCapabilities); int size(); byte[] generateV3SignerAttribute(); List<DefaultApkSignerEngine.SignerConfig> sortSignerConfigs(
            List<DefaultApkSignerEngine.SignerConfig> signerConfigs); SignerCapabilities getSignerCapabilities(SignerConfig config); SignerCapabilities getSignerCapabilities(X509Certificate cert); void updateSignerCapabilities(SignerConfig config, SignerCapabilities capabilities); List<X509Certificate> getCertificatesInLineage(); boolean isSignerInLineage(SignerConfig config); boolean isCertificateInLineage(X509Certificate cert); SigningCertificateLineage getSubLineage(X509Certificate x509Certificate); static SigningCertificateLineage consolidateLineages(
            List<SigningCertificateLineage> lineages); final static int MAGIC; }