okhttp 4.3.0 crash with custom X509TrustManager
See original GitHub issueAndroid 10 specific.
Custom X509TrustManager
in use, extending from X509ExtendedTrustManager
, installed with OkHttpClient.Builder#sslSocketFactory()
.
Updating okhttp from 4.2.2 to 4.3.0 causes a crash when installing the trust manager:
java.lang.IllegalArgumentException: Required method checkServerTrusted(X509Certificate[], String, String, String) missing
at android.net.http.X509TrustManagerExtensions.<init>(X509TrustManagerExtensions.java:71)
at okhttp3.internal.platform.android.Android10CertificateChainCleaner.<init>(Android10CertificateChainCleaner.kt:36)
at okhttp3.internal.platform.Android10Platform.buildCertificateChainCleaner(Android10Platform.kt:62)
at okhttp3.internal.tls.CertificateChainCleaner$Companion.get(CertificateChainCleaner.kt:42)
at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.kt:735)
Looking up the commits this seems to be introduced by https://github.com/square/okhttp/commit/a41361efcb0d4ed2e7f09313c9e9fcc3d72e837b that cut down on reflective calls on the trust manager.
Fixed this by adding an implementation of the missing method in the custom trust manager. Note the Android platform exception message is off-by-one String
arg.
private X509ExtendedTrustManager delegate;
private Method checkServerTrusted;
CustomExtendedTrustManager(@NonNull X509ExtendedTrustManager delegate) {
this.delegate = delegate;
try {
checkServerTrusted = delegate.getClass().getMethod("checkServerTrusted",
X509Certificate[].class,
String.class,
String.class);
} catch (NoSuchMethodException ignored) {
}
}
@SuppressWarnings("unused")
@Keep
public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
if (checkServerTrusted == null) {
throw new CertificateException("checkServerTrusted(X509Certificate[], String, String) not implemented in delegate");
}
List<X509Certificate> list;
try {
//noinspection unchecked
list = (List<X509Certificate>) checkServerTrusted.invoke(delegate, 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());
}
return list;
}
With this in place the app is no longer crashing and not really expecting okhttp to change here. Posting this issue as a reference to others who might have the same issue.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:11 (5 by maintainers)
Top GitHub Comments
@laalto this is one of the nicest issue reports I’ve seen. Thanks!
Thanks, much appreciated!