7

I'm currently writing a client part for Android (2.2) and a server using SSL. I managed to exchange messages between the server and a normal client, but Android doesn't seem to be too happy about self signed certificates. I've searched Stackoverflow and Googled A LOT and LOTS of people are having similar problems. All the answers I've found so far either wasn't working or didn't make any sense. Most of the code samples out there are for HTTPS, but this I cannot use, as I need to communicate through a socket (SSLSocket is my best guess). I've tried lots of different code, but right now I'm kinda back at zero again.

So far I've figured out that I have to create a certificate (think I got that right) and a custom TrustManager. Obviously I haven't been able to find any working code, which is why I ask here, as there usually are some really helpful people.

I'm looking for a detailed description of what is supposed to be done, and some code, which can be made into a working Android client code.

Thanks in advance

Casper
  • 465
  • 2
  • 7
  • 16

4 Answers4

1
public class MySSLSocketFactory extends SSLSocketFactory {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);

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

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

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        sslContext.init(null, new TrustManager[] { tm }, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
}

And you Httpclient is

public HttpClient getNewHttpClient() {
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore
                    .getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory
                    .getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(
                    params, registry);

            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            return new DefaultHttpClient();
        }
    }

Hope it helps you.

SHASHIDHAR MANCHUKONDA
  • 3,302
  • 2
  • 19
  • 40
1

I have done it with porting native android browser. I just changed how ssl context is created. I promised that I will also put some working example on SandroB site but... :)

https://market.android.com/details?id=org.sandrob

http://code.google.com/p/sandrob/source/browse/misc/examples/HttpsConnection.java

SandroB
  • 29
  • 1
  • Thanks for your reply. I've looked at the code you linked to, and it looks interesting. The problem is that it uses a lot of classes, which seems to be custom made. I looked up some of them on Google and found that they have been implemented in other libraries. Lets take the CertificateChainValidator seems to be supposed to be in the package android.net.http - but it's not there. Is there a simplified full working example, using standard libraries? – Casper Mar 29 '11 at 11:06
1

CertificateChainValidator is part of android sources. At least in version/tag 2.2.1_r1

To make it work you can build Browser from android sources and change just how SSLContext is initialized in HttpsConnection.java file.

You need keyManagers(initialized with cerfile/password) and trustManagers (trust all).

sslContext.engineInit(keyManagers, trustManagers, null, cache, null);

SandroB
  • 29
  • 1
  • 1
    Hi. I can't seem to import it, and according to http://developer.android.com/reference/android/net/http/package-summary.html the function doesn't seem to exist. As far as I know I'll have to create customs managers to handle the certificates, but I am yet to find some working code. I am using Android 2.2 (API 8) by the way. – Casper Mar 29 '11 at 16:34
0

https://market.android.com/details?id=org.sandrob.sslexample

Feel free to change sources as you needed.

SandroB
  • 29
  • 1