Merge "Add support for Conscrypt APK sig verify with negative modulus" am: fcbd58eed9 am: 5adb7fead6

Original change: https://android-review.googlesource.com/c/platform/tools/apksig/+/1767097

Change-Id: Ibd5933cd1bd1b831e7eea5147eca3799faf0ad1a
diff --git a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
index 6f239ba..9fd0c34 100644
--- a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
+++ b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java
@@ -25,8 +25,6 @@
 import com.android.apksig.util.DataSource;
 import com.android.apksig.util.DataSources;
 
-import org.conscrypt.OpenSSLProvider;
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
@@ -80,7 +78,9 @@
             return;
         }
 
+        // BEGIN-AOSP
         addProviders();
+        // END-AOSP
 
         String cmd = params[0];
         try {
@@ -113,18 +113,20 @@
         }
     }
 
+    // BEGIN-AOSP
     /**
      * Adds additional security providers to add support for signature algorithms not covered by
      * the default providers.
      */
     private static void addProviders() {
         try {
-            Security.addProvider(new OpenSSLProvider());
+            Security.addProvider(new org.conscrypt.OpenSSLProvider());
         } catch (UnsatisfiedLinkError e) {
             // This is expected if the library path does not include the native conscrypt library;
             // the default providers support all but PSS algorithms.
         }
     }
+    // END-AOSP
 
     private static void sign(String[] params) throws Exception {
         if (params.length == 0) {
diff --git a/src/main/java/com/android/apksig/SigningCertificateLineage.java b/src/main/java/com/android/apksig/SigningCertificateLineage.java
index 767a1f6..6c505be 100644
--- a/src/main/java/com/android/apksig/SigningCertificateLineage.java
+++ b/src/main/java/com/android/apksig/SigningCertificateLineage.java
@@ -124,6 +124,11 @@
         return signingCertificateLineage.spawnDescendant(parent, child, childCapabilities);
     }
 
+    public static SigningCertificateLineage readFromBytes(byte[] lineageBytes)
+            throws IOException {
+        return readFromDataSource(DataSources.asDataSource(ByteBuffer.wrap(lineageBytes)));
+    }
+
     public static SigningCertificateLineage readFromFile(File file)
             throws IOException {
         if (file == null) {
@@ -283,6 +288,10 @@
         return result;
     }
 
+    public byte[] getBytes() {
+        return write().array();
+    }
+
     public void writeToFile(File file) throws IOException {
         if (file == null) {
             throw new NullPointerException("file == null");
diff --git a/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java b/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java
index b4ae71a..9cd7b1f 100644
--- a/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java
+++ b/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampVerifier.java
@@ -26,7 +26,6 @@
 import com.android.apksig.internal.apk.ApkSupportedSignature;
 import com.android.apksig.internal.apk.NoApkSupportedSignaturesException;
 import com.android.apksig.internal.apk.SignatureAlgorithm;
-import com.android.apksig.internal.apk.v3.V3SigningCertificateLineage;
 import com.android.apksig.internal.util.ByteBufferUtils;
 import com.android.apksig.internal.util.GuaranteedEncodedFormX509Certificate;
 
diff --git a/src/main/java/com/android/apksig/internal/apk/stamp/V2SourceStampVerifier.java b/src/main/java/com/android/apksig/internal/apk/stamp/V2SourceStampVerifier.java
index 5ba3618..a215b98 100644
--- a/src/main/java/com/android/apksig/internal/apk/stamp/V2SourceStampVerifier.java
+++ b/src/main/java/com/android/apksig/internal/apk/stamp/V2SourceStampVerifier.java
@@ -148,7 +148,12 @@
                 apkContentDigests.entrySet()) {
             digests.add(Pair.of(apkContentDigest.getKey().getId(), apkContentDigest.getValue()));
         }
-        Collections.sort(digests, Comparator.comparing(Pair::getFirst));
+        Collections.sort(digests, new Comparator<Pair<Integer, byte[]>>() {
+            @Override
+            public int compare(Pair<Integer, byte[]> pair1, Pair<Integer, byte[]> pair2) {
+                return pair1.getFirst() - pair2.getFirst();
+            }
+        });
         return digests;
     }
 }
diff --git a/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeSigner.java b/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeSigner.java
index 0a8b7ee..74aa629 100644
--- a/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeSigner.java
+++ b/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeSigner.java
@@ -171,7 +171,7 @@
         final V4Signature.SigningInfo signingInfoNoSignature = new V4Signature.SigningInfo(apkDigest,
                 encodedCertificate, additionaData, publicKey.getEncoded(), -1, null);
 
-        final byte[] data = V4Signature.getSigningData(fileSize, hashingInfo,
+        final byte[] data = V4Signature.getSignedData(fileSize, hashingInfo,
                 signingInfoNoSignature);
 
         // Signing.
@@ -314,8 +314,6 @@
         return bestDigest;
     }
 
-    // Use the same order as in the ApkSignatureSchemeV3Verifier to make sure the digest
-    // verification in framework works.
     public static int digestAlgorithmSortingOrder(ContentDigestAlgorithm contentDigestAlgorithm) {
         switch (contentDigestAlgorithm) {
             case CHUNKED_SHA256:
diff --git a/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java b/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java
index 0a8484b..a6cd9db 100644
--- a/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java
+++ b/src/main/java/com/android/apksig/internal/apk/v4/V4SchemeVerifier.java
@@ -93,7 +93,7 @@
         V4Signature.SigningInfo signingInfo = V4Signature.SigningInfo.fromByteArray(
                 signature.signingInfo);
 
-        final byte[] signedData = V4Signature.getSigningData(apk.size(), hashingInfo, signingInfo);
+        final byte[] signedData = V4Signature.getSignedData(apk.size(), hashingInfo, signingInfo);
 
         // First, verify the signature over signedData.
         ApkSigningBlockUtils.Result.SignerInfo signerInfo = parseAndVerifySignatureBlock(
diff --git a/src/main/java/com/android/apksig/internal/apk/v4/V4Signature.java b/src/main/java/com/android/apksig/internal/apk/v4/V4Signature.java
index e36ed60..deabe12 100644
--- a/src/main/java/com/android/apksig/internal/apk/v4/V4Signature.java
+++ b/src/main/java/com/android/apksig/internal/apk/v4/V4Signature.java
@@ -134,7 +134,7 @@
         writeBytes(stream, this.signingInfo);
     }
 
-    static byte[] getSigningData(long fileSize, HashingInfo hashingInfo, SigningInfo signingInfo) {
+    static byte[] getSignedData(long fileSize, HashingInfo hashingInfo, SigningInfo signingInfo) {
         final int size =
                 4/*size*/ + 8/*fileSize*/ + 4/*hash_algorithm*/ + 1/*log2_blocksize*/ + bytesSize(
                         hashingInfo.salt) + bytesSize(hashingInfo.rawRootHash) + bytesSize(
diff --git a/src/main/java/com/android/apksig/internal/util/DelegatingX509Certificate.java b/src/main/java/com/android/apksig/internal/util/DelegatingX509Certificate.java
index 8f9e1fd..2a890f6 100644
--- a/src/main/java/com/android/apksig/internal/util/DelegatingX509Certificate.java
+++ b/src/main/java/com/android/apksig/internal/util/DelegatingX509Certificate.java
@@ -34,6 +34,7 @@
 import java.util.Date;
 import java.util.List;
 import java.util.Set;
+
 import javax.security.auth.x500.X500Principal;
 
 /**
@@ -210,6 +211,7 @@
     }
 
     @Override
+    @SuppressWarnings("AndroidJdkLibsChecker")
     public void verify(PublicKey key, Provider sigProvider) throws CertificateException,
             NoSuchAlgorithmException, InvalidKeyException, SignatureException {
         mDelegate.verify(key, sigProvider);
diff --git a/src/test/java/com/android/apksig/SigningCertificateLineageTest.java b/src/test/java/com/android/apksig/SigningCertificateLineageTest.java
index 14cab83..d5dc71d 100644
--- a/src/test/java/com/android/apksig/SigningCertificateLineageTest.java
+++ b/src/test/java/com/android/apksig/SigningCertificateLineageTest.java
@@ -90,6 +90,23 @@
     }
 
     @Test
+    public void testLineageFromBytesContainsExpectedSigners() throws Exception {
+        // This file contains the lineage with the three rsa-2048 signers
+        DataSource lineageDataSource = Resources.toDataSource(getClass(),
+                "rsa-2048-lineage-3-signers");
+        SigningCertificateLineage lineage = SigningCertificateLineage.readFromBytes(
+                lineageDataSource.getByteBuffer(0, (int) lineageDataSource.size()).array());
+        List<SignerConfig> signers = new ArrayList<>(3);
+        signers.add(
+                Resources.toLineageSignerConfig(getClass(), FIRST_RSA_2048_SIGNER_RESOURCE_NAME));
+        signers.add(
+                Resources.toLineageSignerConfig(getClass(), SECOND_RSA_2048_SIGNER_RESOURCE_NAME));
+        signers.add(
+                Resources.toLineageSignerConfig(getClass(), THIRD_RSA_2048_SIGNER_RESOURCE_NAME));
+        assertLineageContainsExpectedSigners(lineage, signers);
+    }
+
+    @Test
     public void testLineageFromFileContainsExpectedSigners() throws Exception {
         // This file contains the lineage with the three rsa-2048 signers
         DataSource lineageDataSource = Resources.toDataSource(getClass(),
@@ -131,6 +148,17 @@
     }
 
     @Test
+    public void testLineageWrittenToBytesContainsExpectedSigners() throws Exception {
+        SigningCertificateLineage lineage = createLineageWithSignersFromResources(
+                FIRST_RSA_2048_SIGNER_RESOURCE_NAME, SECOND_RSA_2048_SIGNER_RESOURCE_NAME);
+        lineage = updateLineageWithSignerFromResources(lineage,
+                THIRD_RSA_2048_SIGNER_RESOURCE_NAME);
+        byte[] lineageBytes = lineage.getBytes();
+        lineage = SigningCertificateLineage.readFromBytes(lineageBytes);
+        assertLineageContainsExpectedSigners(lineage, mSigners);
+    }
+
+    @Test
     public void testLineageWrittenToFileContainsExpectedSigners() throws Exception {
         SigningCertificateLineage lineage = createLineageWithSignersFromResources(
                 FIRST_RSA_2048_SIGNER_RESOURCE_NAME, SECOND_RSA_2048_SIGNER_RESOURCE_NAME);