I tried today to code a web application that allow access to a web virtual desktop.

Problem is that this virtual desktop solution could be hosted on a web server with a self-signed certificate. By default, android WebView doesn't allow you to handle ssl certificates fault. (In facts, the default behaviour is to display you a blank screen without asking user if he want to accept certificate).

I well know that unsigned certificates should not be a good way to manage security of a website. But the fact is that in some case, you can afford this little weak.

To resolve this problem under IPhone we have to use a private interface of the webview object. That doesn't ensure us that apple will approve application. Besides, we had to find the trick on a web snippet (and wasn't easy to find).

On android, to solve problem, we will also use private interface (not published on sdk but well present in real java class). Process I use may also be applicable to access any other not published interface.

First step : find the private interface.

Use the fact android source code is open !! http://android.git.kernel.org/ So investigate into Browser source code. Here we discover WebViewClient has a perfect method to handle ssl errors. Browser handle it asking user what to do with certificate.

Second step : get corresponding class source

Well here go the tricky part. We will get real java source code (not the one provided by sdk, but the one that is in java class path at runtime on android). In our case, we have emphasized that WebViewClient is the class we want to hack. So just get it from source from git (WebViewClient.java). You also have to get ../net/http/SslError.java. Luckily, WebViewClient has only this dependency on privates methods. If you want to access WebView apis, you may need to get a lot of files. At this point you have to be aware that if private api are private, they could change ! So check by browsing revisions if privates api/code has not changed between different API versions. What we are about to do is potentially overwrite an existing java class.

Third step : override java class

Now, we will import class into android project. Just replicate packages from sources you get. Source tree

Last step : use private api

That's all folk's ;). Now you just have to use new class.

// It could be a private static member, here just for demo
WebViewClient mWebviewclient = new WebViewClient(){
     public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
          handler.proceed();
     }
};

//Where myWebview is the WebView object
myWebView.setWebViewClient(mWebviewclient);

Here I just proceed if i detect an ssl certificate error. A good idea should be to check we are talking to the good website (IP configured into you application, and maybe also consider connection type and maybe finally get certificate to be able to compare later).