Classic Notes: How to import self signed certificates into your Domino Java environment
If you get errors like “PKIX path building failed”... such as ...
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
... you may have a problem with self-signed certificates in your Java environment. Read more about how to fix this in this article!
I show you how to export certificates with Chrome, and how to add this to your so-called keystore in your Java environment. In the end you will have both your Eclipse and Domino environment accept the self-signed certificate.
UPDATE Jan 19th, 2016 15:31 CET: René Winkelmeyer informed me about his blog where he has already described a much more elegant appoach for Domino - which also survives an update! ... Head over to his blog and check it out. Thanks a lot René for the pointer! René's blog points you further to Simon O'Doherty’s answer on Serverfault (Hi Simon, long time since the “chineese API syndrome” ).
This article is a write-up for my own environment (mostly Eclipse and Domino Designer, with Chrome on Windows 10 x64) mostly in order for myself to remember how to fix it for the future. Searching the net on "PKIX path building failed" found a bunch of posts addressing the issue, but unfortunately also focused on cumbersome command line tools, and not so much on my environment.
I however found the concise and to-the-point list from Sarel Botha here http://stackoverflow.com/questions/11617210/how-to-properly-import-a-selfsigned-certificate-into-java-keystore-that-is-avail and that is the basis for this write-up.
Why do you get the "PKIX path building failed"? If you Java code ever needs to communicate via SSL such as for example retrieve a REST Service response over HTTPS, your Java Virtual Machine (JVM) won't allow the communication to happen unless the certificate of the target is trusted.
If your target server (the one running the HTTPS-service which you connect to) has purchased a SSL certificate from one of the large Certificate Authorities, you won't probably see the problem, as your JVM already has a list of trusted certificate authorities.
This doesn't happen if your target server uses a self signed certificate. What does this mean? The target server does indeed have a SSL certificate, but the certificate is homemade!! Almost the same as if you print your own drivers license.
So in order to trust such a certificate you really need to trust the target server. In this is where the manual process described here comes in.
First, you need the certificate itself (think of it as a huge string of characters and numbers). Several ways exist to retrieve it from the server,and command line tools like keytool and IKeyMan can help you out. I like to just use the Chrome browser.
Step 1 - Get the certificate from the target server
This step retrieves the certificate from the target server
- We get the certificate from the target server simply by communicating with it.
Open up an https URL towards the server you want to access. For example, use a REST URL like this https://blabla.com/api/domino/empolyees/employeenbr/12345. My test URL requires me to input a username and password;
If everything is correct you will now receive the data you ask for with the URL.
- Click on the lock icon to retrieve information about the certificate.
- You will see a dialog box with the initial certificate information. Click on the Connection tab
Then click on the "Certificate information" link to open the next dialog box.
- The "Certificate" dialog box
Click on the "Details" tab to get the next dialog box
- The "Details" tab
Click on the "Copy to File..." button to initiate the Certificate Export Wizard.
- The "Certificate Export Wizard" dialog boxes
Click on "Next"
Accept the default (DER encoded binary X.509 (.CER)) and click "Next"
Specify an output file, in my example "c:\temp\Target Server Self Signed Cert.cer". Click on "Next"
Click on "Finish". If everything goes OK, you'll see the following confirmation;
You now got the target server certificate stored in a file on your computer.
Step 2 - Keystore?! cacerts?! What - Where!!
- Keystore, what is that?!? - you might ask. Simply a file where the list of trusted certificates lives.
- Where do I find it? Ahh, remember the introduction?. Every JVM has it's own keystore!! The file name of the keystore is cacerts (yes, without file extension). If you search your computer, you will most probably find several keystore-files. This is especially true on 64-bit systems. Use the search tool in Explorer, or use a command like c:\DIR cacerts /s from a command prompt. Even better, use a power-tool like Everything Search from http://voidtools.com/. This is by far the fastest way to search your computer for files, as it searches the master file table instead of the file system. You have instant answer in other words! Below you see all the cacerts on my system;
- How to pick the right one?! - you might ask! One certain way is to add the following line into some java code in your JVM and run it;
If I run this in my Eclipse-environment I get "C:\Program Files (x86)\Java\jre1.8.0_66" (marked by 1) above. And if I execute the same in java code in my IBM Domino Designer, I get "C:\Program Files (x86)\IBM\Notes\jvm" (marked by 2) above. If you need some help to write java code in Domino, see the small tutorial at the end of this article.
Ok, so now you presumably know which cacerts to work on.
Step 3 - How to import the target server certificate into your keystore - part 1
As mentioned, you can do this the hard way by using keytool or other similar tools.
I like the Portecle tool (http://portecle.sourceforge.net/) which can be downloaded for free. It puts a user interface ontop of the command line tools.
Since Portecle is a java application, it means that you need the Java SDK (at least the 1.7 version is required). If you don't have standalone Java installed, head over to https://www.java.com/en/download/ and install that first-
I like to have a shortcut on my desktop, and here is how I created that.
On my system, I stored Portecle in "D:\Programs\portecle-1.9"
Why not use the fantastic Everything Search again to find the correct java.exe
Enter the full path to your java.exe file. On my computer this was "C:\Program Files (x86)\Java\jre1.8.0_66\bin\java.exe". Click "Next" when finished.
Click "Finish", and voila, you have a shortcut to the java executable.
- Locate the short cut on the Desktop and right click it to open it's properties dialog box
In the "Target"-field, place the cursor at the end and append the following parameters (with the path to your portecle.jar file of course)
On my system the whole Target-field contains this string
"C:\Program Files (x86)\Java\jre1.8.0_66\bin\java.exe" -jar D:\Programs\portecle-1.9\portecle.jar
Change the icon too if you want to, by clicking on the "Change Icon"-button and navigate to the Portecle-directory.
Step 4 - How to import the target server certificate into your keystore - part 2
Ok, Portecle is in place, time to make it work!
First, coming here you have your certificate (the .cer file) from the first step saved somewhere. You also know which cacerts-file you want to work with from step 2.
This is the process to import the certificate into your correct keystore.
- Copy the cacerts file to another directory
Why? Because Windows 7 and newer don't like you messing around with the files in the Program Files subdirectories. By copying it to another directory, such as C:\Temp, we can work with it, and later copy it back to it's original position.
I my example I copy the cacerts from "C:\Program Files (x86)\IBM\Notes\jvm\lib\security" to "C:\temp".
- Launch Portecle
Nothing existing yet. Click on the menu File -> Open Keystore File;
- Navigate to the directory where you copied the cacerts from step 1.
In my case that is C:\Temp
- Enter the password for the keystore file - "changeit" is the default
- Portecle opens up the keystore file and we are ready to import our certificate
Choose the menu Tools -> Import Trusted Certificate
- Navigate to the directory where you have stored your certificate file
In my case this was also the C:\Temp.
- Review the certificate
- Choose the menu File -> Save to save the keystore file
You may then exit Portecle.
- The last step is now to copy the modified cacerts file back to the original position.
Why not backup the original before overwriting it
If you get any warnings from Windows, it mean that the User Access Control-feature (UAC) in Windows tries to protect you from doing something stupid in the directory. Remember, you can always restore the original cacerts from your backup, right?
Congratulations! You are finished!! Try to execute your Java-stuff again and watch how your JVM now gracefully accepts your self-signed sertificate