0

I am doing a HTTPS request using a HttpsURLConnection.

The server I'm trying to contact has a self-signed certificate, so this logically causes the request to fail.

However, the failure isn't signaled to my program by an exception. It just fails and I can see why in the logcat.

03-22 17:54:35.203: W/System.err(21147): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
03-22 17:54:35.203: W/System.err(21147):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:381)

Here is the code I use for the request:

HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setAllowUserInteraction(false);
connection.connect();

Ideally, I'd like my program to react like browser do: popup a dialog indicating that the certificate is not trusted and possibly add it to some key-store and retry the request.

But since I can't figure out a way of getting the exception, I really don't know what to do here.

Any clue ?

ereOn
  • 53,676
  • 39
  • 161
  • 238
  • 1
    did you try this? http://stackoverflow.com/questions/2012497/accepting-a-certificate-for-https-on-android?rq=1 – petey Mar 22 '13 at 17:09

2 Answers2

2

While huge is correct that you need to implement a custom TrustManager, you should absolutely not just blindly accept all SSL certificates.

Nikolay Elenikov has an excellent blog post describes how to set up a custom TrustManager to validate such certificates

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks for the resource. I indeed won't blindly accept all certificates, that would be just dumb. I don't know why so many people keep suggesting such "solutions" which defeat all the purpose of having HTTPS in the first place. A comment in the blog post you linked asked exactly what I want (that is: how to get the untrusted certificate object for inspection to let the user choose) and got answered so thank you again. – ereOn Mar 23 '13 at 08:52
-4

You can do it like this:

SSLContext sc = SSLContext.getInstance("TLS");
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return;
}
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return;
    }
} };
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpURLConnection = connection = endPoint.openConnection();
huge
  • 123
  • 2