Iam having this strange issue in which the retrofit keeps throwing me
"SSL handshake aborted: ssl=0x618d9c18: I/O error during system call, Connection reset by peer"
in kitkat, whereas the same code working fine in lollipop devices. Iam using an OkHttpClient client like the following
public OkHttpClient getUnsafeOkHttpClient() {
try {
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
} };
int cacheSize = 10 * 1024 * 1024; // 10 MB
Cache cache = new Cache(getCacheDir(), cacheSize);
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, trustAllCerts,
new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext
.getSocketFactory();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient = okHttpClient.newBuilder()
.cache(cache)
.sslSocketFactory(sslSocketFactory)
.hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Iam using this client in retrofit like this
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.client(getUnsafeOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
EDIT : adding the getUnsafeOkHttpClient()
has no effect here and it is not at all recommended to bypass the ssl check by using getUnsafeOkHttpClient()
FYI : The issue was because the api endpoint supports only TLS 1.2
which was disabled by default on android devices 16<device<20
. So for 16<device<20
, create a custom SSLSocketFactory
Finally found a solution to this issue, its not a complete solution as it is a hack mentioned by Jesse Wilson from okhttp, square here. As i mentioned it was a simple hack where i had to rename my SSLSocketFactory variable to
notice that it would throw error if you give any name other than delegate. Iam posting my complete solution below
This is my TLSSocketFactory class
and this is how i used it with okhttp and retrofit
EDIT : The method
public Builder sslSocketFactory(SSLSocketFactory sslSocketFactory)
is now deprecated and we should usepublic Builder sslSocketFactory( SSLSocketFactory sslSocketFactory, X509TrustManager trustManager)
as i have updated in the answer. This is becauseX509TrustManager
is a field that OkHttp needs to build a clean certificate chain, which was not paased in the deprecated method.You may also check this for more info