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

Commit a26cafc2 authored by Chad Brubaker's avatar Chad Brubaker Committed by android-build-merger
Browse files

Merge "Use duck typing in X509TrustManagerExtensions"

am: 9c3982f7

* commit '9c3982f7':
  Use duck typing in X509TrustManagerExtensions
parents 1ff9f8ad 9c3982f7
Loading
Loading
Loading
Loading
+66 −7
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package android.net.http;

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.X509Certificate;
import java.util.List;
@@ -34,7 +37,11 @@ import javax.net.ssl.X509TrustManager;
 */
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.
@@ -45,10 +52,31 @@ public class X509TrustManagerExtensions {
    public X509TrustManagerExtensions(X509TrustManager tm) throws IllegalArgumentException {
        if (tm instanceof TrustManagerImpl) {
            mDelegate = (TrustManagerImpl) tm;
        } else {
            mTrustManager = null;
            mCheckServerTrusted = null;
            mIsUserAddedCertificate = null;
            return;
        }
        // Use duck typing if possible.
        mDelegate = null;
            throw new IllegalArgumentException("tm is an instance of " + tm.getClass().getName() +
                    " which is not a supported type of X509TrustManager");
        mTrustManager = tm;
        // 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,
                                                    String host) throws CertificateException {
        if (mDelegate != null) {
            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.
     */
    public boolean isUserAddedCertificate(X509Certificate cert) {
        if (mDelegate != null) {
            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());
                }
            }
        }
    }
}