Getting back to more tactical things, I’ve been hacking on some Java code recently for the first time in a long while. I’m trying to grab some data from a vendor’s SOAP interface for trending in Cacti, and having had problems with Perl’s SOAP::Lite library, I switched to using Apache Axis in Java. However, this post isn’t really about my web service client: it’s about how much SSL in Java stinks.
Like most good web services handling potentially sensitive data (like usernames and passwords), our vendor’s interface is secured using SSL. It appears that the fine folks at Sun went off and invented their own native Java implementation of SSL, rather than using the implementation of the underlying operating system. Here are some specific beefs:
- 1.SSL keys and certificates in Java are managed using a Java-specific command line tool called
keytool. The format of the keytool files are specific to Java and cannot be easily manipulated using other tools.
- There is no correlation between the certificates or keys stored in the keytool database and those supplied by the underlying operating system SSL layer, if it exists. The data must be manually propagated, including the SSL certificates of all trusted CAs.
- The keytool database cannot be built into the Java classpath and opened programatically without supplying an absolute path to it, thus limiting portability of an application (e.g. building a standalone JAR with dependencies that one could actually run anywhere)
- Runtime configuration of the SSL layer is done by means of Java system properties passed to the JVM, e.g.
-Djavax.net.ssl.trustStore=/etc/somepath/keystore.dat. This is a rather obtuse way of configuring SSL.
- Error messages thrown by SSL libraries are non-intuitive. If the keystore file is not found, for example, rather than the SSL implementation throwing
java.lang.FileNotFoundException, it throws a
javax.net.ssl.SSLHandshakeExceptionwith some completely irrelevant error message. In my view,
javax.net.ssl.SSLHandshakeExceptionshould be reserved for actual handshaking problems with the remote end, rather than some critical pre-requisite like the keystore file being missing
Now I know, Java is supposed to run everywhere, and not every operating system has the luxury of OpenSSL. But on platforms that do have a native SSL layer, I don’t understand why Java can’t simply use that, or the data files of that layer. Linux, for example, uses OpenSSL, and all information required to make OpenSSL work – trusted CAs, private keys, etc. are already managed within
/etc/pki/tls and can be programatically invoked using OpenSSL libraries. Why not just replace all the heavy lifting of
javax.net.ssl with shims to talk to OpenSSL?