Revert ^2 "Merge Conscrypt upstream master.""

This reverts commit 55f75a645170bb5cbcd072121c57556d73f8b515.

Reason for revert: Re-landing with fix.

Up until Android 12, BC advertised an X.509 CertificateFactory
so skip testing it on all releases.

Bug: 275484241
Test: atest
MtsConscryptTestCases:com.android.org.conscrypt.java.security.cert.X509CertificateTest
    against an Android 11 device.
Change-Id: I669741e71fbbbdda979dc2e852c68f6636a0a255
diff --git a/common/src/jni/main/cpp/conscrypt/jniutil.cc b/common/src/jni/main/cpp/conscrypt/jniutil.cc
index c609b89..cae86d0 100644
--- a/common/src/jni/main/cpp/conscrypt/jniutil.cc
+++ b/common/src/jni/main/cpp/conscrypt/jniutil.cc
@@ -295,6 +295,7 @@
         case ASN1_R_WRONG_PUBLIC_KEY_TYPE:
             return throwInvalidKeyException(env, message);
             break;
+        case ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED:
         case ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM:
         case ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM:
             return throwNoSuchAlgorithmException(env, message);
diff --git a/common/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java b/common/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java
index beddeb3..581e866 100644
--- a/common/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java
+++ b/common/src/test/java/org/conscrypt/java/security/cert/X509CertificateTest.java
@@ -19,13 +19,17 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
 import java.math.BigInteger;
 import java.nio.charset.Charset;
 import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
+import java.security.SignatureException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertificateParsingException;
@@ -168,6 +172,30 @@
             + "-----END CERTIFICATE-----\n";
 
     /**
+     * This cert is signed using MD5, which is no longer supported by BoringSSL.
+     */
+    private static final String MD5_SIGNATURE =
+        "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx\n"
+            + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD\n"
+            + "VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv\n"
+            + "biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy\n"
+            + "dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t\n"
+            + "MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB\n"
+            + "MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG\n"
+            + "A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp\n"
+            + "b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl\n"
+            + "cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv\n"
+            + "bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE\n"
+            + "VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ\n"
+            + "ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR\n"
+            + "uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG\n"
+            + "9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI\n"
+            + "hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM\n"
+            + "pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==\n"
+            + "-----END CERTIFICATE-----";
+
+    /**
      * This is an X.509v1 certificatea, so most fields are missing. It exists to test accessors
      * correctly handle the lack of fields. It was constructed by hand, so the signature itself is
      * invalid.
@@ -444,6 +472,7 @@
                 public void test(Provider p, String algorithm) throws Exception {
                     X509Certificate c = certificateFromPEM(p, VALID_CERT);
                     assertEquals("SHA256WITHRSA", c.getSigAlgName().toUpperCase());
+                    c.verify(c.getPublicKey());
                 }
             });
     }
@@ -457,6 +486,41 @@
                 public void test(Provider p, String algorithm) throws Exception {
                     X509Certificate c = certificateFromPEM(p, UNKNOWN_SIGNATURE_OID);
                     assertEquals("1.2.840.113554.4.1.72585.2", c.getSigAlgOID());
+                    assertThrows(NoSuchAlgorithmException.class, () -> c.verify(c.getPublicKey()));
+                }
+            });
+    }
+
+    // MD5 signed certificates no longer supported by BoringSSL but still supported by OpenJDK 8
+    // and by BC where present (up until Android 12)
+    @Test
+    public void unsupportedDigestType() {
+        ServiceTester.test("CertificateFactory")
+            .withAlgorithm("X509")
+            .skipProvider("SUN")
+            .skipProvider("BC")
+            .run(new ServiceTester.Test() {
+                @Override
+                public void test(Provider p, String algorithm) throws Exception {
+                    X509Certificate c = certificateFromPEM(p, MD5_SIGNATURE);
+                    assertThrows(NoSuchAlgorithmException.class, () -> c.verify(c.getPublicKey()));
+                }
+            });
+    }
+
+    @Test
+    public void invalidSignature() {
+        // Mutate the signature of VALID_CERT slightly
+        int index = VALID_CERT.lastIndexOf('9');
+        assertTrue(index > 0);
+        String invalidCert = VALID_CERT.substring(0, index) + "8" + VALID_CERT.substring(index + 1);
+        ServiceTester.test("CertificateFactory")
+            .withAlgorithm("X509")
+            .run(new ServiceTester.Test() {
+                @Override
+                public void test(Provider p, String algorithm) throws Exception {
+                    X509Certificate c = certificateFromPEM(p, invalidCert);
+                    assertThrows(SignatureException.class, () -> c.verify(c.getPublicKey()));
                 }
             });
     }
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/cert/X509CertificateTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/cert/X509CertificateTest.java
index 473b176..30e73fd 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/cert/X509CertificateTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/cert/X509CertificateTest.java
@@ -20,6 +20,8 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import com.android.org.conscrypt.TestUtils;
@@ -27,7 +29,9 @@
 import java.math.BigInteger;
 import java.nio.charset.Charset;
 import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
+import java.security.SignatureException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertificateParsingException;
@@ -171,6 +175,29 @@
             + "-----END CERTIFICATE-----\n";
 
     /**
+     * This cert is signed using MD5, which is no longer supported by BoringSSL.
+     */
+    private static final String MD5_SIGNATURE = "-----BEGIN CERTIFICATE-----\n"
+            + "MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx\n"
+            + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD\n"
+            + "VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv\n"
+            + "biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy\n"
+            + "dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t\n"
+            + "MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB\n"
+            + "MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG\n"
+            + "A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp\n"
+            + "b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl\n"
+            + "cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv\n"
+            + "bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE\n"
+            + "VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ\n"
+            + "ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR\n"
+            + "uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG\n"
+            + "9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI\n"
+            + "hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM\n"
+            + "pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==\n"
+            + "-----END CERTIFICATE-----";
+
+    /**
      * This is an X.509v1 certificatea, so most fields are missing. It exists to test accessors
      * correctly handle the lack of fields. It was constructed by hand, so the signature itself is
      * invalid.
@@ -447,6 +474,7 @@
                 public void test(Provider p, String algorithm) throws Exception {
                     X509Certificate c = certificateFromPEM(p, VALID_CERT);
                     assertEquals("SHA256WITHRSA", c.getSigAlgName().toUpperCase());
+                    c.verify(c.getPublicKey());
                 }
             });
     }
@@ -460,6 +488,43 @@
                     public void test(Provider p, String algorithm) throws Exception {
                         X509Certificate c = certificateFromPEM(p, UNKNOWN_SIGNATURE_OID);
                         assertEquals("1.2.840.113554.4.1.72585.2", c.getSigAlgOID());
+                        assertThrows(
+                                NoSuchAlgorithmException.class, () -> c.verify(c.getPublicKey()));
+                    }
+                });
+    }
+
+    // MD5 signed certificates no longer supported by BoringSSL but still supported by OpenJDK 8
+    // and by BC where present (up until Android 12)
+    @Test
+    public void unsupportedDigestType() {
+        ServiceTester.test("CertificateFactory")
+                .withAlgorithm("X509")
+                .skipProvider("SUN")
+                .skipProvider("BC")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        X509Certificate c = certificateFromPEM(p, MD5_SIGNATURE);
+                        assertThrows(
+                                NoSuchAlgorithmException.class, () -> c.verify(c.getPublicKey()));
+                    }
+                });
+    }
+
+    @Test
+    public void invalidSignature() {
+        // Mutate the signature of VALID_CERT slightly
+        int index = VALID_CERT.lastIndexOf('9');
+        assertTrue(index > 0);
+        String invalidCert = VALID_CERT.substring(0, index) + "8" + VALID_CERT.substring(index + 1);
+        ServiceTester.test("CertificateFactory")
+                .withAlgorithm("X509")
+                .run(new ServiceTester.Test() {
+                    @Override
+                    public void test(Provider p, String algorithm) throws Exception {
+                        X509Certificate c = certificateFromPEM(p, invalidCert);
+                        assertThrows(SignatureException.class, () -> c.verify(c.getPublicKey()));
                     }
                 });
     }