Search code examples
androidsslhttpsandroid-ionion-koush

How do i get ion library to trust self signed certificates


I am trying to connect to REST Service that has to use self signed certificates (it's a Unify PBXs Web Services Interface). The System will regenerate it's Certificates on Software updates and unless you load a certificate into the system there will always be a self signed one. When trying to connect with ion the connection is closed because of the self signed certificate (as far as google took me...). What do i need to add to my implementation to make io accept this cert? I am using ion as follows.

Ion.with(context)
     .load(...)
     .asString()
     .setCallback(new FutureCallback<String>() {
           @Override
           public void onCompleted(Exception e, String result) {
           }
      });

Solution

  • You can specify custom SSL Contexts and trust managers to use self signed certificates.

    Here's an example from a unit test:

    public void testKeys() throws Exception {
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    
        ks.load(getContext().getResources().openRawResource(R.raw.keystore), "storepass".toCharArray());
        kmf.init(ks, "storepass".toCharArray());
    
    
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
        ts.load(getContext().getResources().openRawResource(R.raw.keystore), "storepass".toCharArray());
        tmf.init(ts);
    
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    
        AsyncHttpServer httpServer = new AsyncHttpServer();
        httpServer.listenSecure(8888, sslContext);
        httpServer.get("/", new HttpServerRequestCallback() {
            @Override
            public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
                response.send("hello");
            }
        });
    
        Thread.sleep(1000);
    
        AsyncHttpClient.getDefaultInstance().getSSLSocketMiddleware().setSSLContext(sslContext);
        AsyncHttpClient.getDefaultInstance().getSSLSocketMiddleware().setTrustManagers(tmf.getTrustManagers());
        AsyncHttpClient.getDefaultInstance().executeString(new AsyncHttpGet("https://localhost:8888/"), null).get();
    }
    

    You'll need to access ion's underlying http client instance as follows:

    Ion.getDefault(getContext()).getHttpClient().getSSLSocketMiddleware().setTrustManagers(...);
    Ion.getDefault(getContext()).getHttpClient().getSSLSocketMiddleware().setSSLContext(...);
    

    The key is a bks key store, bouncy castle.