Certificate pinning in Android

Jake picture Jake · Aug 9, 2014 · Viewed 10k times · Source

I am trying to learn how to do certificate pinning in an Android application. I found the tutorial here. I wanted to clarify I doubt I have based on my testing this code.

I used the code as follows :

public class CertificatePinning {

  static SSLSocketFactory constructSSLSocketFactory(Context context) {

    SSLSocketFactory sslSocketFactory = null;

    try {
        AssetManager assetManager = context.getAssets();
        InputStream keyStoreInputStream = assetManager.open("myapp.store");
        KeyStore trustStore = KeyStore.getInstance("BKS");

        trustStore.load(keyStoreInputStream, "somepass".toCharArray());

        sslSocketFactory = new SSLSocketFactory(trustStore);
        sslSocketFactory.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
    }
    catch(Exception e){

        Log.d("Exception", e.getLocalizedMessage());
    }

    return sslSocketFactory;
}

public static HttpClient getNewHttpClient(Context context) {

    DefaultHttpClient httpClient = null;

    try {

        SSLSocketFactory sslSocketFactory = constructSSLSocketFactory(context);

        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", sslSocketFactory, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        httpClient = new DefaultHttpClient(ccm, params);

    } catch (Exception e) {

        Log.d("Exception", e.getLocalizedMessage() );

        return null;
    }

    return httpClient;
}

}

Quoting a statement from that tutorial :

On the client side, you simply need to distribute the signing certificate 
with your app and validate against it.

On my web server, I have my own CA, which I created using open SSL, and used to sign certificates for different domain names that are used with my app.

This statement indicates that this tutorial is meant for the CA certificate I have. I tested the code using ca.pem (from my CA's crt file) and it works fine.

But I also tested the same code with a certificate I signed with that CA, e.g. server.pem ( from the signed server.crt), and still it works.

Did I do something wrong, or is this code meant for pinning either :

1) a CA certificate (covering all certificates signed by that CA) or

2) a particular certificate (signed by some CA) ?

Answer