diff options
4 files changed, 91 insertions, 9 deletions
diff --git a/common/src/test/java/org/conscrypt/TrustManagerImplTest.java b/common/src/test/java/org/conscrypt/TrustManagerImplTest.java index 3d444713..e1cce50b 100644 --- a/common/src/test/java/org/conscrypt/TrustManagerImplTest.java +++ b/common/src/test/java/org/conscrypt/TrustManagerImplTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; +import java.lang.reflect.Method; import java.security.KeyStore; import java.security.Principal; import java.security.cert.Certificate; @@ -29,6 +30,7 @@ import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.List; import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLPeerUnverifiedException; @@ -165,9 +167,13 @@ public class TrustManagerImplTest { // Override the global default hostname verifier with a Conscrypt-specific one that // always passes. Both scenarios should pass. - Conscrypt.setDefaultHostnameVerifier(new ConscryptHostnameVerifier() { - @Override public boolean verify(String s, SSLSession sslSession) { return true; } - }); + HostnameVerifier alwaysTrue = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(alwaysTrue); certs = tmi.getTrustedChainForServer(chain, "RSA", new FakeSSLSocket(new FakeSSLSession(badHostname, chain), params)); @@ -179,7 +185,7 @@ public class TrustManagerImplTest { // Now set an instance-specific verifier on the trust manager. The bad hostname should // fail again. - Conscrypt.setHostnameVerifier(tmi, new TestHostnameVerifier()); + Conscrypt.setHostnameVerifier(tmi, wrapVerifier(new TestHostnameVerifier())); try { tmi.getTrustedChainForServer(chain, "RSA", @@ -208,6 +214,29 @@ public class TrustManagerImplTest { } } + /* + * Wrap a HostnameVerifier in a ConscryptHostnameVerifier. + * In the Android platform ConscryptHostnameVerifier is a private API and the interface + * definition changed between Android 11 and Android 12. + * If an Android 12 Conscrypt module is present then there will also be a (non-public) + * method to wrap it with the correct interface. + * If an earlier module is present then the interface is the same as in the CTS 11 codebase + * and so we can just wrap it directly with an anonymous class. + * See also b/195615915 + */ + private ConscryptHostnameVerifier wrapVerifier(final HostnameVerifier verifier) throws Exception { + Method wrapMethod = TestUtils.findWrapVerifierMethod(); + if (wrapMethod != null) { + return (ConscryptHostnameVerifier) wrapMethod.invoke(null, verifier); + } + return new ConscryptHostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return verifier.verify(hostname, session); + } + }; + } + private X509TrustManager trustManager(X509Certificate ca) throws Exception { KeyStore keyStore = TestKeyStore.createKeyStore(); keyStore.setCertificateEntry("alias", ca); diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/TrustManagerImplTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/TrustManagerImplTest.java index bff0b7f1..f08a46a3 100644 --- a/repackaged/common/src/test/java/com/android/org/conscrypt/TrustManagerImplTest.java +++ b/repackaged/common/src/test/java/com/android/org/conscrypt/TrustManagerImplTest.java @@ -21,7 +21,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.android.org.conscrypt.java.security.TestKeyStore; import java.io.IOException; +import java.lang.reflect.Method; import java.security.KeyStore; import java.security.Principal; import java.security.cert.Certificate; @@ -30,6 +32,7 @@ import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.List; import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLPeerUnverifiedException; @@ -37,7 +40,6 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.X509TrustManager; -import com.android.org.conscrypt.java.security.TestKeyStore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -169,12 +171,13 @@ public class TrustManagerImplTest { // Override the global default hostname verifier with a Conscrypt-specific one that // always passes. Both scenarios should pass. - Conscrypt.setDefaultHostnameVerifier(new ConscryptHostnameVerifier() { + HostnameVerifier alwaysTrue = new HostnameVerifier() { @Override - public boolean verify(String s, SSLSession sslSession) { + public boolean verify(String hostname, SSLSession session) { return true; } - }); + }; + HttpsURLConnection.setDefaultHostnameVerifier(alwaysTrue); certs = tmi.getTrustedChainForServer(chain, "RSA", new FakeSSLSocket(new FakeSSLSession(badHostname, chain), params)); @@ -186,7 +189,7 @@ public class TrustManagerImplTest { // Now set an instance-specific verifier on the trust manager. The bad hostname should // fail again. - Conscrypt.setHostnameVerifier(tmi, new TestHostnameVerifier()); + Conscrypt.setHostnameVerifier(tmi, wrapVerifier(new TestHostnameVerifier())); try { tmi.getTrustedChainForServer(chain, "RSA", @@ -215,6 +218,30 @@ public class TrustManagerImplTest { } } + /* + * Wrap a HostnameVerifier in a ConscryptHostnameVerifier. + * In the Android platform ConscryptHostnameVerifier is a private API and the interface + * definition changed between Android 11 and Android 12. + * If an Android 12 Conscrypt module is present then there will also be a (non-public) + * method to wrap it with the correct interface. + * If an earlier module is present then the interface is the same as in the CTS 11 codebase + * and so we can just wrap it directly with an anonymous class. + * See also b/195615915 + */ + private ConscryptHostnameVerifier wrapVerifier(final HostnameVerifier verifier) + throws Exception { + Method wrapMethod = TestUtils.findWrapVerifierMethod(); + if (wrapMethod != null) { + return (ConscryptHostnameVerifier) wrapMethod.invoke(null, verifier); + } + return new ConscryptHostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return verifier.verify(hostname, session); + } + }; + } + private X509TrustManager trustManager(X509Certificate ca) throws Exception { KeyStore keyStore = TestKeyStore.createKeyStore(); keyStore.setCertificateEntry("alias", ca); diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java index 222715fa..21d07909 100644 --- a/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java +++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/TestUtils.java @@ -49,6 +49,7 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; @@ -171,6 +172,18 @@ public final class TestUtils { Assume.assumeTrue("SHA2 with DSA signatures not available", available); } + private static Method findMethod(Class<?> cls, String methodName, Class<?>... methodParams) { + try { + return cls.getDeclaredMethod(methodName, methodParams); + } catch (NoSuchMethodException e) { + return null; + } + } + + public static Method findWrapVerifierMethod() { + return findMethod(Conscrypt.class, "wrapHostnameVerifier", HostnameVerifier.class); + } + public static InetAddress getLoopbackAddress() { try { Method method = InetAddress.class.getMethod("getLoopbackAddress"); diff --git a/testing/src/main/java/org/conscrypt/TestUtils.java b/testing/src/main/java/org/conscrypt/TestUtils.java index bfb9b272..a4a798ae 100644 --- a/testing/src/main/java/org/conscrypt/TestUtils.java +++ b/testing/src/main/java/org/conscrypt/TestUtils.java @@ -45,6 +45,7 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; @@ -169,6 +170,18 @@ public final class TestUtils { Assume.assumeTrue("SHA2 with DSA signatures not available", available); } + private static Method findMethod(Class<?> cls, String methodName, Class<?>... methodParams) { + try { + return cls.getDeclaredMethod(methodName, methodParams); + } catch (NoSuchMethodException e) { + return null; + } + } + + public static Method findWrapVerifierMethod() { + return findMethod(Conscrypt.class, "wrapHostnameVerifier", HostnameVerifier.class); + } + public static InetAddress getLoopbackAddress() { try { Method method = InetAddress.class.getMethod("getLoopbackAddress"); |