We tried to access a remote webservice from a partner and they updated their certificate a few days ago. This request fails with an very unhelpful error message in ColdFusion.
Symptom:
- ColdFusion CFHTTP is broken if you access a SSL site, but it worked in past.
- ColdFusion CFDUMP says Connection Failure with I/O Exception: peer not authenticated
- ColdFusion CFDUMP says I/O Exception: sun.security.validator.ValidatorException: PKIX path building failed: java.security.cert.CertPathBuilderException: Could not build a validated path.
Analysis:
Since intermediate certificates have been provided by the server it can only be the root level certificate. But there may exists other situations where the certificate chain my be incomplete and you get the same error. Verify this with SSLLabs or a certificate checker from a certificate authority very first. Be aware that they sometimes fail to show missing intermediate certificates.
Code for testing:
<cfhttp result = "test" url="https://www.example.com/" /> <cfdump var="#test#">
Let's start up ColdFusion with these debugging and see what happens. Add the java.args=-server -Djavax.net.debug=ssl,handshake,verbose
to C:\ColdFusion10\[cfusion]\bin\jvm.config and it may looks like:
java.args=-server -Djavax.net.debug=ssl,handshake,verbose -Xms256m -Xmx512m -XX:MaxPermSize=192m -XX:+UseParallelGC -Xbatch -Dcoldfusion.home={application.home} -Dcoldfusion.rootDir={application.home} -Dcoldfusion.libPath={application.home}/lib -Dorg.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER=true -Dcoldfusion.jsafe.defaultalgo=FIPS186Random -Dcoldfusion.classPath={application.home}/lib/updates,{application.home}/lib,{application.home}/lib/axis2,{application.home}/gateway/lib/,{application.home}/wwwroot/WEB-INF/cfform/jars,{application.home}/wwwroot/WEB-INF/flex/jars,{application.home}/lib/oosdk/lib,{application.home}/lib/oosdk/classes
Run the example test code once and than look into:
[coldfusion-out.log]
catalina-exec-1, SEND TLSv1 ALERT: fatal, description = certificate_unknown catalina-exec-1, WRITE: TLSv1 Alert, length = 2 catalina-exec-1, called closeSocket() catalina-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: java.security.cert.CertPathBuilderException: Could not build a validated path. catalina-exec-1, IOException in getSession(): javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: java.security.cert.CertPathBuilderException: Could not build a validated path.
The error message certificate_unknown
is the root cause. Scroll up a little bit and you will see what root CA the intermediate certificate requires. For us it was Issuer Name: CN=Go Daddy Root Certificate Authority - G2, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US. That one is not inside Java if you look into the keystore with:
keytool -list -keystore "C:\ColdFusion10\jre\lib\security\cacerts"
You can download the Root CA "gdroot-g2.crt" file from https://certs.godaddy.com/repository/ and rename the file to "gdroot-g2.pem". Install it by importing it with keytool (password is "changeit")
keytool -import -alias "godaddyrootcag2" -keystore "C:\ColdFusion10\jre\lib\security\cacerts" -file gdroot-g2.pem
Do not forget to restart ColdFusion. Convince the server owner to get a better certificate from Godaddy or any other certificate authority if the certificate root CA is missing in your Java. An update to latest Java sometimes also help, too. Typically these issues are caused by low budget / ultra cheap domain validated certificates. Importing intermediate certificates in case someone failed to install his certificate cannot suggested. You should expect that this is an insecure server if SSL basics are not completed. Importing intermediates may only a last resort solution if server owners do not understand that they are not capable to install a SSL certificate properly. If you need to stay with this workaround do not forget that you may need to import this again and again with every Java update as this may install everytime a new cacerts file. This suxxx a lot.
History:
- 07/11/2017: Let's Encrypt has added with Java 8.0.101 and later. Extended by some details and other examples.
- 15/01/2016: Go Daddy Root Certificate Authority - G2 is integrated in Java 8.0.65 and maybe earlier versions.
- 11/04/2014: Found Go Daddy Root Certificate Authority - G2 that is not integrated into Java 7.