Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c3982f7 authored by Chad Brubaker's avatar Chad Brubaker Committed by Gerrit Code Review
Browse files

Merge "Use duck typing in X509TrustManagerExtensions"

parents 8f879493 bfcd67f7
Loading
Loading
Loading
Loading
+66 −7
Original line number Original line Diff line number Diff line
@@ -18,6 +18,9 @@ package android.net.http;


import com.android.org.conscrypt.TrustManagerImpl;
import com.android.org.conscrypt.TrustManagerImpl;


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.cert.CertificateException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.List;
@@ -34,7 +37,11 @@ import javax.net.ssl.X509TrustManager;
 */
 */
public class X509TrustManagerExtensions {
public class X509TrustManagerExtensions {


    final TrustManagerImpl mDelegate;
    private final TrustManagerImpl mDelegate;
    // Methods to use when mDelegate is not a TrustManagerImpl and duck typing is being used.
    private final X509TrustManager mTrustManager;
    private final Method mCheckServerTrusted;
    private final Method mIsUserAddedCertificate;


    /**
    /**
     * Constructs a new X509TrustManagerExtensions wrapper.
     * Constructs a new X509TrustManagerExtensions wrapper.
@@ -45,10 +52,31 @@ public class X509TrustManagerExtensions {
    public X509TrustManagerExtensions(X509TrustManager tm) throws IllegalArgumentException {
    public X509TrustManagerExtensions(X509TrustManager tm) throws IllegalArgumentException {
        if (tm instanceof TrustManagerImpl) {
        if (tm instanceof TrustManagerImpl) {
            mDelegate = (TrustManagerImpl) tm;
            mDelegate = (TrustManagerImpl) tm;
        } else {
            mTrustManager = null;
            mCheckServerTrusted = null;
            mIsUserAddedCertificate = null;
            return;
        }
        // Use duck typing if possible.
        mDelegate = null;
        mDelegate = null;
            throw new IllegalArgumentException("tm is an instance of " + tm.getClass().getName() +
        mTrustManager = tm;
                    " which is not a supported type of X509TrustManager");
        // Check that the hostname aware checkServerTrusted is present.
        try {
            mCheckServerTrusted = tm.getClass().getMethod("checkServerTrusted",
                    X509Certificate[].class,
                    String.class,
                    String.class);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Required method"
                    + " checkServerTrusted(X509Certificate[], String, String, String) missing");
        }
        // Check that isUserAddedCertificate is present.
        try {
            mIsUserAddedCertificate = tm.getClass().getMethod("isUserAddedCertificate",
                    X509Certificate.class);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException(
                    "Required method isUserAddedCertificate(X509Certificate) missing");
        }
        }
    }
    }


@@ -64,7 +92,24 @@ public class X509TrustManagerExtensions {
     */
     */
    public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
    public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
                                                    String host) throws CertificateException {
                                                    String host) throws CertificateException {
        if (mDelegate != null) {
            return mDelegate.checkServerTrusted(chain, authType, host);
            return mDelegate.checkServerTrusted(chain, authType, host);
        } else {
            try {
                return (List<X509Certificate>) mCheckServerTrusted.invoke(mTrustManager, chain,
                        authType, host);
            } catch (IllegalAccessException e) {
                throw new CertificateException("Failed to call checkServerTrusted", e);
            } catch (InvocationTargetException e) {
                if (e.getCause() instanceof CertificateException) {
                    throw (CertificateException) e.getCause();
                }
                if (e.getCause() instanceof RuntimeException) {
                    throw (RuntimeException) e.getCause();
                }
                throw new CertificateException("checkServerTrusted failed", e.getCause());
            }
        }
    }
    }


    /**
    /**
@@ -78,6 +123,20 @@ public class X509TrustManagerExtensions {
     * otherwise.
     * otherwise.
     */
     */
    public boolean isUserAddedCertificate(X509Certificate cert) {
    public boolean isUserAddedCertificate(X509Certificate cert) {
        if (mDelegate != null) {
            return mDelegate.isUserAddedCertificate(cert);
            return mDelegate.isUserAddedCertificate(cert);
        } else {
            try {
                return (Boolean) mIsUserAddedCertificate.invoke(mTrustManager, cert);
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Failed to call isUserAddedCertificate", e);
            } catch (InvocationTargetException e) {
                if (e.getCause() instanceof RuntimeException) {
                    throw (RuntimeException) e.getCause();
                } else {
                    throw new RuntimeException("isUserAddedCertificate failed", e.getCause());
                }
            }
        }
    }
    }
}
}