In the previous posting (HCI First Steps Part 7 – Handling errors) we covered implementing error handling. However subsequently it appears that not all tenants come configured with the correct certificates to enable the tenant to connect to an HTTPS server. Without Root and Intermediate CA’s the tenant will be unable to make a secure connection and the connection will fail.
After implementing the iFlow and testing it many people ran into the problem that the iFlow would not deliver mail. The error returned was
Could not convert socket to TLS;
nested exception is:
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, cause: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The key to understanding this error is the message unable to find valid certification path to requested target. This is saying that the certificate or a certificate on the path is missing in the system.jks artifact.
First however, a little bit of background around the use of certificates in SSL/TLS. Whilst SSL has been deprecated and no one really uses it these days since it has been replaced by TLS. It is unfortunate that SSL acronym is still more well known than TLS. In the rest of this document SSL is synonymous with TLS.
The infrastructure for SSL relies on the use of certificates to provide identity. Certificates are issues by a Certificate Authority, often abbreviated to CA. The topmost CA is called the Root CA and is implicitly trusted by you and the browser. This CA can then issue certificates to other entities that are then allowed to issue certificates to other entities. These certificate issuing entities are called Intermediate Certificate Authorities or Intermediate CA’s. At the end of the chain there will be a client certificate which is the one issued to the website by the Root or intermediate CA. The client certificate can prove that it has not been tampered with by being able to prove a path of trust from itself to the root CA. Of course the Root CA normally comes with the browser and there are very few Root CA’s in the browser since these are the only trusted certificates in the system and so any certificate that is presented to the browser will have to prove itself to one of the Root CA’s in order to be securely used by the browser. If a Root CA is added to the browser or computer then you are asserting that you trust this certificate to validate any certificates that are supplied to the browser.
When connecting to a website using SSL, the website will provide a certificate and it will be then up to the browser to check all certificates to form a path of trust to make sure the certificate is provided by a known Root CA and also that the certificate in the chain has not been revoked or expired.
To obtain a certificate from one of the Root CA’s or one of the intermediate CA’s requires an account with the CA. On the webserver a public/private keypair will be generated and stored. Tools can be used to generate the private key (which you store securely) and the public key as a certificate signing request (CSR). The public key is contained within the signing request so the CSR is effectively a proxy for the public portion of the key pair. This request is sent to the CA to be signed by the CA. The CA takes the supplied request and creates a certificate from it. The response from the CA can then be imported into your web server and will be presented whenever a client connects with SSL/TLS. The CA never has access to your private key, it just places a wrapper around the supplied data (after validating it of course).
It is important to remember that anyone can have a certificate since the certificate just proves it has not been tampered with. It does not prove identity or even perform encryption. When a browser/client is presented with a certificate it uses that to encrypt a secret using the public key so then only the webserver can decrypt it since it is the only one in possession of the private key. It then uses this to establish a trusted session with the client.
- The handshake begins when a client connects to a TLS-enabled server requesting a secure connection and presents a list of supported cipher suites (ciphers and hash functions).
- From this list, the server picks a cipher and hash function that it also supports and notifies the client of the decision.
- The server usually then sends back its identification in the form of a digital certificate. The certificate usually contains the server name, the trusted certificate authority (CA) and the server’s public encryption key.
- The client may contact the server that issued the certificate (the trusted CA as above) and confirm the validity of the certificate before proceeding.
- In order to generate the session keys used for the secure connection, the client either:
a) Encrypts a random number with the server’s public key and sends the result to the server (which only the server should be able to decrypt withits private key); both parties then using the random number to generate a unique session key for subsequent encryption and decryption of data during the session
b) uses Diffie-Hellman key exchange to securely generate a random and unique session key for encryption and decryption that has the additional property of forward secrecy: if the server’s private key is disclosed in future, it cannot be used to decrypt the current session, even if the session is intercepted and recorded by a third party.
- This concludes the handshake and begins the secured connection, which is encrypted and decrypted with the session key until the connection closes. If any one of the above steps fail, the TLS handshake fails, and the connection is not created.
Below is an example of the certificate for the SAP OnDemand service
Here we have a certificate with a root CA as “Baltimore CyberTrust Root”. This has delegated “Verison Public SureServer CA G14-SHA2” as an intermediate CA who is entitled to issue certificates on behalf of Baltimore CyberTrust. Finally we have “*.hana.ondemand.com” as the certificate for the web server. The “*” is a special designator saying that this certificate can be used by any server attached to the hana.ondemand.com domain. Normally the specific DNS name of the server is required. Also since this site is trusted, communications between the browser and the site can then be negotiated.
To add the certificate to the keystore, If there are many people working on the tenant then the tenant will probably have a system.jks keystore already deployed. This can be checked by connecting to the tenant and looking in the deployed artifacts view for the keystore.
There is one keystore for everyone called system.jks, if you deploy a keystore you MUST make sure it has the
existing certificates in it preserved!
Here is the system.jks keystore file deployed on the tenant. To access the keystore file, click the download button on right to download the keystore to your machine. However you will be unable to edit without the correct tools.
There is a really good article on adding certificates to the key store on the command line here http://alvinalexander.com/java/java-using-keytool-import-certificate-keystore however I prefer to use the KeystoreExplorer tool to do this since it is much easier to do with a GUI.
The keystore explorer application can be obtained from http://keystore-explorer.sourceforge.net/downloads.php and has applications for Windows, OSX and Linux.
Special instructions for OSX users:
Using KeystoreExplorer required that the unlimited strength policy files be installed. On OSX is was not clear how to do this. The short answer is to update the package in /Library/Internet Plug-Ins/JavaAppletPlugin.plugin by opening the package and replacing the policy files in security folder of the package. This was documented in this StackOverflow thread – http://stackoverflow.com/questions/12245179/how-to-install-unlimited-strength-jce-for-jre-7-in-macosx
Once KeyStoreExplorer is installed and running you can proceed to add the certificates. If you downloaded the keystore file since there was already one on your tentant then open the keystore otherwise create a new keystore.
In this case I created a new keystore where I selected the first option “JCEKS”
However we now want to add the certificate chain for google to the keystore.
I covered importing certificates the traditional way in my how to guide on SCN. However there is an easier way to do this in KeyStore explorer.
In your web browser goto your gmail account and note the server name I have hilighted in the browser address bar. This is the address of the server that your browser is connecting to and this is also the server that will be supplying the SSL certificate.
Go back to KeyStore explorer and from the Examine menu, select the “Examine SSL” command.
This will prompt you for the site to examine.
Select each certificate in the certificate hierarchy in the top panel and click “Import” to add each certificate to the KeyStore.
You will be prompted each time to accept the certificate as trusted which you will and to provide an alias for the certificate.
When all three certificates have been imported, click “OK” and the list of certificates will be displayed
And the keystore is updated. Of course if you downloaded an existing KeyStore from your tenant you will have many more certificates in the keystore than just these 3 certificates.
Now open Eclipse with the HCI Tooling installed and connect to your HCI tenant. Switch to the “Integration Operations” perspective and double click on the tenant id node in the Node Explorer view.
Right click over the tenant node in the “Node Explorer” pane and choose “Deploy Artifacts”
This will display a list of artifacts allowing you to select the KeyStore artifact.
Click “Next” and select the location and file of the KeyStore you created earlier and enter the password associated with the keystore.
Click on the “Refresh” button, highlighted above to refresh the list of deployed artifacts and notice that the “system.jks” keystore file has now been updated.
Redeploy the iFlow and the iFlow will now succeed.