⇓ ... now forked at GitHub
added on 2017-10-21Many of the Java folks, who ever dealt with SSL-enabled protocols and self-made SSL certificates, know of the InstallCert tool. This simple command-line tool, published in 2006 by Andreas Sterbenz at the official Sun blog, allows obtaining SSL certificates as they are presented by the hosts we connect to, with further optional saving them to the system trust store.
Sun's blog is not with us any more, but a copy of the original InstallCert publication and code is still available from some of the users' blogs, like this one, or archives like that one. Curiously, one of the current blogs at Oracle mentions this tool, but without reference to the original author, and with a reference (currently somewhat outdated) to the mentioned user blog instead... ☺
Well, the original Andreas' tool served faithfully to me for quite a while, but every good thing has its limitations... In particular, the original InstallCert could not deal with hosts that operate using STARTTLS technique.
The new code
Diving into STARTTLS required quite a refactoring of the original code, though the main parts of it are still in place ☺. In particular, modular approach was taken to deal with STARTTLS implementations for different protocols, so the code does not fit in single Java file any more, but is rather packaged as an executable .jar.
It is now possible to obtain certificates from hosts that not only speak plain SSL/TLS, but also expose their certificates via STARTTLS over IMAP, POP3, SMTP and LDAP.
For new application-level protocols with STARTTLS extension to be supported, an abstract STARTTLS handler is defined as a
StarttlsHandler
interface. This interface needs to be implemented by every new protocol handler, and the latter is to be registered with the Starttls
wrapper class. This registration needs to be hard-coded so far. But keeping in mind the small number of STARTTLS-compatible application-level protocols yet to be implemented, this should not be a problem ☺.The certificates collected by the program are now stored at two locations:
- the standard
jssecacerts
keystore in thelib/security
folder of your JRE; - in an
extracerts
keystore in your current directory; the latter may be handy in order to save collected certificates in pure form for further redistribution.
Downloads
The following downloads are available:
- binary:
- source:
Usage – HOW-TO
Prerequisites
Obtaining a certificate from a plain SSL/TLS or an LDAP/STARTTLS server
Run the program like this:
java -jar installcert-usn-20140115.jar host_nameor
java -jar installcert-usn-20140115.jar host_name:portor
java -jar installcert-usn-20140115.jar host_name:port truststore_password
The default port is 443 (for HTTPS). The default truststore password is "changeit" as per JSSE convention.
Obtaining a certificate from an IMAP / POP3 / SMTP server with STARTTLS extension
In this case you will need the JavaMail library, and make sure you have it on your classpath. Please also keep in mind that it is necessary to indicate the main class explicitly in the command line if you have more than one jar.
To make things easier, two shell scripts are provided:
run-with-javamail-starttls.sh
for Unix and run-with-javamail-starttls.cmd
for Windows. You will have to edit at least one of them first, so to reflect the actual location of the JavaMail .jar file.General notes and final housekeeping
If the program succeeds in obtaining a certificate (or several of them), and the certificates are not known yet, it will ask you whether you wish to save them. Upon successful run the program saves the new certificate(s) to two files, as mentioned above:
- the standard
jssecacerts
keystore in thelib/security
folder of your JRE; - an
extracerts
keystore in your current directory; this one may be handy in order to save collected certificates in pure form for further redistribution.
Please keep in mind that in order to have the standard
jssecacerts
keystore file in the lib/security
folder of your JRE successfully created/modified, you will most likely need to have administrative (superuser, root) privileges.Enjoy! ☺
... rebuilt for Java 1.6 and fixed
added on 2014-01-15The download links and examples were updated to reflect the new build made to be compatible with Java 1.6 as per Eric's comment. The certificate handling logic was also improved for better discrimination of new certificates vs known ones.
... now forked at GitHub
added on 2017-10-21This code is now forked and available at Github: https://github.com/spyhunter99/installcert . The fork was created with an intention to achieve embeddability, and looks actively developed...
Thanks this helped me quite a bit, the only snag I came across was due to the fact that I'm still on Java 1.6. I installed 1.7 and was able to run the program successfully. Then I just merged the new extracerts keystore with the 1.6 keystore I was looking to update.
ReplyDeleteThanks again!
-Eric
Wow! :) Thank you for pointing this out. To be frank, I completely forgot people can be still using Java 1.6 :) And in fact nothing in the code prevents running it under 1.6. I'll look into getting it complied for 1.6.
DeleteJust curious: did your case really require STARTTLS handling?
Well, the new build compatible with Java 1.6 is available for download instead of the old one... Some minor bug fixes were made also...
DeleteYes, our mail server only enabledd SSL via STARTTLS, the previous version of installcert won't work so this helped big time. Thanks again.
DeleteI was looking for a solution to fetch domain controller's certificate from ldap port 389 (starttls)
ReplyDeleteYour code works great.:-)
Thanks Sergey
That's my pleasure :)
DeleteThank you for letting me know :)
It was so simple to use it that I first solved the problem (inadvertently) using your binary and then actually deep dived to understand the problem and solution.
ReplyDeleteWorks like a charm Sergey :-)
Baaton, thank you for the pleasure to know someone is using it :)
DeleteCould you drop a line just for my curiousity :) - what kind of protocol did you use it for, and whether STARTTLS was really involved?
This comment has been removed by the author.
DeleteHello Sergey ,
ReplyDeleteactually still some ppl use even jre1.5 -:))
[nxuser@as1 installcert-usn-20140115]$ java -jar installcert-usn-20140115.jar xx.xx.xx.xx:xx
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
[nxuser@as1 installcert-usn-20140115]$ java -version
java version "1.5.0_14"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
Java HotSpot(TM) Server VM (build 1.5.0_1
Hi i getting below on typing this command java -jar installcert-usn-20140115.jar webservice.ibancomplete.com
ReplyDelete================================================= Error connecting to remote host : java.net.connectException connection timedout
Hi i getting below error on typing this command java -jar installcert-usn-20140115.jar webservice.ibancomplete.com
ReplyDelete================================================= Error connecting to remote host : java.net.connectException connection timed out
Well Naidu, this is the response that I got for your command:
ReplyDelete...>java -jar installcert-usn-20140115.jar webservice.ibancomplete.com
... loading system truststore from 'C:\Program Files\Java\jre1.8.0_121\lib\security\cacerts' ...
... creating extra truststore as a new one ...
... opening connection to webservice.ibancomplete.com:443 ...
... starting SSL handshake ...
No errors, certificate is already trusted.
No new certificates found to be added to the extra truststore.
And it sounds reasonable, as the certificate is issued by Trustwave...
My first idea is that your networking settings may prohibit connection to webservice.ibancomplete.com over port 443. Could you maybe cross-check it with telnet?
> telnet webservice.ibancomplete.com 443
I get a connection for such a command too...
hello,
ReplyDeleteI couldn't access/download the source/binary , not sure if its still available.
Thanks,
Raj
Hi Raj, I've just tested the download links, and they worked for me...
DeleteI admit the hosting site may be down occasionally from time to time. Please try again and let me know. If the problem persists, we can discuss some other options for getting the tool available to you...
Thanks for the reply. May be the issue is at the network level at my end because of which i'm not able to get the file downloaded.
DeleteHi Raaj, try these Google Drive links then:
Delete- https://drive.google.com/file/d/0B2nLiheurgV7Z1hxc3hMMGo0NWc/view and
- https://drive.google.com/file/d/0B2nLiheurgV7WU9lOU9tdXpPR2c/view
And I'll be glad to know if you succeed with downloading and further usage... :)
I am struggling with installing a cert from an LDAP server that runs on port 389. If I run the tool against this port, I get an SSL handshake exception "java.net.SocketException: Connection reset". Is it possible anyway to retrieve the cert via that port?
ReplyDeleteHi Guido,
ReplyDeletecan you provide more info? Is the exception accompanied with a stacktrace? Can you publish it here?
I'm trying to automate this, is there a way to accept the cert without prompting the user?
ReplyDeleteHi B-ran,
Deletethere is a fork of this code at Github: https://github.com/spyhunter99/installcert .
That fork was created with an intention to achieve embeddability ( see https://stackoverflow.com/questions/7084482/how-to-save-the-ldap-ssl-certificate-from-openssl/20280562#comment78250553_20280562 ), so your wish for promptless operation might have already been implemented. The project seems to be actively developed, so you may be welcome there with your ideas...
Hi Sergey, I am getting below exception, can u guide me
ReplyDeletejava -jar installcert-usn-20140115.jar xxxxxxxxx
... loading system truststore from '/opt/jdk1.8.0_131/jre/lib/security/cacerts' ...
... creating extra truststore as a new one ...
... opening connection to xxxx.xxx.xx:443 ...
... starting SSL handshake ...
Exception in thread "main" java.lang.NullPointerException
at usn.net.ssl.util.InstallCert.main(InstallCert.java:277)