Using pinned self-signed SSL certificate with Android Volley

Recently for one of my Android apps I wanted to use a self-signed certificate on the server-side. However, if you try to connect to such a server with default settings, the connection is going to be refused. This is because it has been signed by you (your server domain), and ‘you’ is not trusted by any system.

Read the excellent article – Android security – Implementation of Self-signed SSL certificate for your App. This describes all the concepts and the pros and cons of pinning. However, it does not describe how to do this in Volley. The internet is littered with many articles on this, and most of them are outdated and can’t be used now.

So, here is an updated guide. I have tested this on my app which uses Android API 22 and Volley code downloaded on Jan 2015.

First use the official guide to create a singleton class to get the request queue. Now below is the modified code which takes care of the SSL pinning.

public class MySingleton {
    private static char[] KEYSTORE_PASSWORD = "YourKeyStorePass".toCharArray();


    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new HurlStack(null, newSslSocketFactory()));
        return mRequestQueue;


    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = mCtx.getApplicationContext().getResources().openRawResource(R.raw.codeprojectssl);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Provide the password of the keystore
                trusted.load(in, KEYSTORE_PASSWORD);
            } finally {

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);

            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);

            SSLSocketFactory sf = context.getSocketFactory();
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);

Please note, that the above solution will work for Android API 9 and above. To support the below versions you need to pass an instance of HttpClientStack instead of HurlStack. So, replacing the line

mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new HurlStack(null, newSslSocketFactory()));


mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new HttpClientStack(new MyHttpClient()));

might work. Where MyHttpClient is the one defined in the CodeProject article. I haven’t tested this part though.

Relief Trust India review – It’s a Scam!

I should admit that I donated to them once after a preliminary cross-check. However, it seems I still got fooled. After that they started calling me at any time for more donations, and tried to use their “pressure” tactics. I requested them many times not to call me, but just send me an email. However, they continue to ignore this and call me up at odd hours (sometimes). Anyway some more Googling brought me to this post. This post looks genuine enough, if you read its long comments section.

Sting Operation – Relief Trust India review – It’s a Scam! – Complete review and analysis with proofs!.

ADF: Entity-State vs Post-State

There are lots of blog posts on this but all copy and paste the content of EntityImpl javadoc, which is very obscure. I finally found a sensible explanation in Dive into Oracle ADF, but that is usually buried deep in Google results.

I will restate the Dive into Oracle ADF post here, and will add few finer details.

In DB you can run the DML queries as many times as you want without committing them. When we are saving data to DB the call chain is like – transaction.postChanges() -> entity.postChanges() -> entity.prepareForDML() -> entity.doDML(). The entity’s DML operations depend on the post-state. So, transaction.postChanges() effectively make all entities to write their data to DB. They do that by checking their internal post-states and creating appropriate DML queries based on those states. After the DML action the post-state is updated. So, if before postChanges() if the post-state was STATUS_NEW, then after that it would be STATUS_UNMODIFIED, so that on next postChanges() call it doesn’t try to insert the row again.

Entity-state on the other hand represents the entity’s state irrespective of the fact that the changes has been posted (written) to the DB. So, even if all changes in entity are posted, the entity-state remains STATUS_MODIFIED. Entity-state changes only after commit is invoked on the transaction. Unless and until a transaction is committed the changes done in the transaction is not visible in other transactions (this is a feature of relational DB), so, when entity-state changes we know that those changes are now visible to all transactions.

An example:

row = vo.first();  /* read a row in from DB.  Both EO states are UNMODIFIED */

row.setAttribute("SomeAttr", someValue); /* After this, both states are MODIFIED */

am.getTransaction().postChanges(); /* Changes are written to DB. Trans not committed yet */
                                   /* After this, post-state is UNMODIFIED. Entity-state is MODIFIED */

am.getTransaction().commit(); /* Transaction committed. After this, both states are UNMODIFIED */

If you see EntityImpl’s javadoc then you will notice that we have one extra post-state – STATUS_INITIALIZED. Entities have this post-state only when it is newly created. The moment one of its attribute is set, this changes to STATUS_NEW. When postChanges() is invoked then DML action is skipped if post-state is STATUS_INITIALIZED. This prevents blank rows from getting inserted. Entity-state never has this value since entity-state is meant to be used for writing business logic, and from that perspective STATUS_NEW and STATUS_INITIALIZED makes no difference.