1

I want to use custom certificate located in p12 pack to make a https connection. I already did it on iPhone (so I can verify, that everything is fine with the certificate, server, etc.), but have some problems with Android.

I followed the How to request a URL that requires a client certificate for authentication answear, but as a result I get a following exception:

12-13 12:32:44.545: W/System.err(4407): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 12-13 12:32:44.545: W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374) 12-13 12:32:44.545: W/System.err(4407): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209) 12-13 12:32:44.545: W/System.err(4407): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478) 12-13 12:32:44.545: W/System.err(4407): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433) 12-13 12:32:44.545: W/System.err(4407): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289) 12-13 12:32:44.550: W/System.err(4407): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239) 12-13 12:32:44.550: W/System.err(4407): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80) 12-13 12:32:44.550: W/System.err(4407): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:165) 12-13 12:32:44.550: W/System.err(4407): at com.geckolab.httptestandroid.MainActivity.downloadUrlHttps(MainActivity.java:172) 12-13 12:32:44.550: W/System.err(4407): at com.geckolab.httptestandroid.MainActivity.access$0(MainActivity.java:151) 12-13 12:32:44.550: W/System.err(4407): at com.geckolab.httptestandroid.MainActivity$DownloadWebPageTextHttps.doInBackground(MainActivity.java:99) 12-13 12:32:44.550: W/System.err(4407): at com.geckolab.httptestandroid.MainActivity$DownloadWebPageTextHttps.doInBackground(MainActivity.java:1) 12-13 12:32:44.550: W/System.err(4407): at android.os.AsyncTask$2.call(AsyncTask.java:287) 12-13 12:32:44.550: W/System.err(4407): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 12-13 12:32:44.555: W/System.err(4407): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 12-13 12:32:44.555: W/System.err(4407): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 12-13 12:32:44.555: W/System.err(4407): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 12-13 12:32:44.555: W/System.err(4407): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 12-13 12:32:44.555: W/System.err(4407): at java.lang.Thread.run(Thread.java:856) 12-13 12:32:44.555: W/System.err(4407): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 12-13 12:32:44.560: W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:192) 12-13 12:32:44.560: W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:163) 12-13 12:32:44.560: W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:573) 12-13 12:32:44.560: W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method) 12-13 12:32:44.560: W/System.err(4407): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371) 12-13 12:32:44.560: W/System.err(4407): ... 18 more 12-13 12:32:44.560: W/System.err(4407): Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 12-13 12:32:44.560: W/System.err(4407): ... 23 more

My connection code looks as follow:

KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(context.getResources().openRawResource(R.raw.gecko_cert_1), "gecko_cert_1".toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
        kmf.init(ks, "gecko_cert_1".toCharArray());
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(kmf.getKeyManagers(), null, null);


        //request
        URL serverURL = new URL(myurl); 
        HttpsURLConnection conn = (HttpsURLConnection)serverURL.openConnection();
        conn.setSSLSocketFactory(sc.getSocketFactory());
        //conn.setHostnameVerifier(DO_NOT_VERIFY);
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Starts the query
        conn.connect();

Cheers, Marcin

Community
  • 1
  • 1
Marcin Szulc
  • 141
  • 2
  • 13
  • In your post you mentioned you got certificate authentication working in iOS. Can you provide the code you used to get certificate authentication working on iOS? – njtman Feb 05 '14 at 20:42

1 Answers1

-4

It works for me now.

I added the following snippet on top of the connection method:

       X509TrustManager[] tm = new X509TrustManager[] { new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        } };

And then swap the line:

sc.init(kmf.getKeyManagers(), null, null);

to:

sc.init(kmf.getKeyManagers(), tm, null);

I also uncommented this line:

conn.setHostnameVerifier(DO_NOT_VERIFY);

Cheers, Marcin

Marcin Szulc
  • 141
  • 2
  • 13
  • 6
    This is bad, bad, bad. It will allow and trust *any* certificate, opening your app to man-in-the-middle attacks. Get you server certificate, add it to a truststore and initialize your connection with it. Some details and code here: http://nelenkov.blogspot.jp/2011/12/using-custom-certificate-trust-store-on.html – Nikolay Elenkov Dec 14 '12 at 03:35