I have an app that downloads documents from 3rd party sites (to browse offline).
I am using a standard HttpUrlConnection.
It used to work like a charm, but since upgrading to Nougat, one of the site produces a very consistent SSLHandshakeException the others are working fine.
I have tries using the new app certificates, no luck. I have even tried the old trick of the "trust all certs" TrustManager. No luck. The TrustManager id not even queries.
I noticed though that this server is using a fairly old cipher.
...
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : RC4-MD5
...
Can it be the reason for my woes, and if it is how can I add this cipher to my connection ?
Thx
Edit 1: The app is targetting SDK 22 and compiling against API 22 as well
Edit 2: The code has been hacked a bit to test with a "forced" CA (build with the site's certificate) and to test with the "trust all" trust manager as well. It is to note that, when in use, the "trust all" manager is never used.
SSLContext sslContext = null;
if (testWitCa) {
Certificate ca = null;
try {
ca = cf.generateCertificate(caInput);
Log.v(this, "ca = " + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
} else {
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
Log.v(FileDownloader.this, "Checking client with %s", authType);
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
Log.v(FileDownloader.this, "Checking server with %s", authType);
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, null);
}
URL url = new URL(fromUrl);
HttpURLConnection httpConn;
httpConn = (HttpsURLConnection) url.openConnection();
if (sslContext != null) {
((HttpsURLConnection) httpConn).setSSLSocketFactory(sslContext.getSocketFactory());
}
responseCode = httpConn.getResponseCode();
I have tried using the following security config file as well (the root CA for the site the Thawte G3):
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="@raw/site_ca"/>
<certificates src="@raw/thawte_g3_ca"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>