I have on my hands an Android app, targeting SDK level 21. Therein I'm trying to connect to AWS' alive.json using java.net.HttpURLConnection
.
The trust chain looks like so:
- Baltimore CyberTrust Root (trusted by dev device)
- DigiCert Baltimore CA-2 G2 (dev device trusts DigiCert Assured ID Root G2, Global Root CA, Global Root G2 among other DigiCerts - is this sufficient?)
- AWS (*.us-east-etc.amazonaws.com)
My AndroidManifest.xml features <uses-permission android:name="android.permission.INTERNET"/>
.
The code [boils down to] the following. It's called on a separate thread (which executes requests one by one - there's just this one for now), from NDK.
// init() -- all optional
System.setProperty("http.keepAlive", "false");
HttpURLConnection.setDefaultAllowUserInteraction(false);
// makeRequest(HttpRequest request)
URL url = new URL(request.url);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setUseCaches(false);
http.setReadTimeout(timeoutMs);
http.setChunkedStreaingMode(0); // optional
http.setDoInput(true);
http.setRequestMethod("GET"); // optional
http.setRequestProperty("X-Correlation-ID", x); // optional
http.connect();
Now, if I set the timeout to 80ms, I will get an javax.net.ssl.SSLHandshakeException: SSL handshake timed out
. Beyond that (800ms), it will hang forever in http.connect()
.
https://developer.android.com/training/articles/security-ssl.html#HttpsExample and the surrounding article details how this should be done. My understanding is that I should not need certificate pinning for this exercise.
If I do add one (along the lines of the above article), I get a javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
.
Connecting to a http:// resource works just fine.
What am I doing wrong? What extra configuration is needed on my part and why?
UPDATE:
1, OkHttp based implementation manifests the exact same behaviour.
2, Certificate pinning did not help get around the issue. Note that this is only a desperate measure, and not something for production - obviously we don't want to break when Amazon's certificates get updated.