Sunday, October 23, 2011

Java RMI over SSL and a single port

I was lucky with my latest freelance contract that the clients were happy to build on littleware to implement some of their back-end services, and they let me bill a little time to implement a few features - like securing the RMI-based procedure-calls over SSL. Fortunately java includes an RmiSSLSocketFactory, but there are a few integration tricks.

I outlined in a previous post how to configure RMI to export all its objects over a single firewall-friendly port. That was easy to do once I knew the trick. Unfortunately SSL has a few moving parts - some of which I disabled as I really just want the data going over the wire encrypted, and am less concerned over end-point certificate verification.

Anyway, in the end it's not too complicated - it's just a matter of knowing the tricks - which are annoying to track down. Most of the code is in littleware's LittleRemoteObject class that specializes java's UnicastRemoteObject. The server builds a RmiSSLServerSocketFactory using an SSLContext that loads a certificate from a keystore on the classpath. The client builds and RmiSSLClientSocketFactory with a no-op TrustStore that bypasses verification of the server's certificate.

One final trick - the server boots up its own RmiRegistry with its custom RmiSSLServerSocketFactory, and the client connects via LocateRegistry.getRegistry - which accepts the client's socket factory - (littleware's RemoteRetryHelper implements the client's connection). Littleware's client actually exposes its own API that integrates a cache and authentication building on top of the service API that the server exposes via RMI (I'm working on a REST implementation).

Anyway - a boring post about a technology nobody uses. Sweet!