Merge "Use duck typing in X509TrustManagerExtensions"

am: 9c3982f75d

* commit '9c3982f75da19e2c0e146e7f251514a44412da0c':
  Use duck typing in X509TrustManagerExtensions
This commit is contained in:
Chad Brubaker
2015-11-12 19:33:31 +00:00
committed by android-build-merger

View File

@@ -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 {
mDelegate = null;
throw new IllegalArgumentException("tm is an instance of " + tm.getClass().getName() +
" which is not a supported type of X509TrustManager");
mTrustManager = null;
mCheckServerTrusted = null;
mIsUserAddedCertificate = null;
return;
}
// Use duck typing if possible.
mDelegate = null;
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 {
return mDelegate.checkServerTrusted(chain, authType, host);
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) {
return mDelegate.isUserAddedCertificate(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());
}
}
}
}
}