Personal tools
You are here: Home Linux Java Howto verify Java TLS (with Server Name Indication) and the error 'PKIX path building failed'

Howto verify Java TLS (with Server Name Indication) and the error 'PKIX path building failed'

— filed under:

When Java programs generate the error 'PKIX path building failed' it can be unclear whether this is due to:

  • CA certificate not being present (i.e. a broken chain of trust)
    • an updated/new CA
    • a self-signed certificate not being in the 'cacerts' keystore
    • the CA from a privately signed certificate not being in the 'cacerts' keystore

The Atlassian people have a SSLPoke utility class that is very useful for testing the Java stack. e.g. (output)

$ java -Djavax.net.debug=ssl SSLPoke teamcity.lucidsolutions.co.nz 443

Before testing/verifying the java stack use the openssl s_client command to verify the certificate being presented. e.g. [Note: the openssl used here supports TLS SNI and the '-servername' option]

$ openssl s_client -connect teamcity.lucidsolutions.co.nz:443 -servername teamcity.lucidsolutions.co.nz

Conclusions

  1. The StartCOM CA certificate in OpenJDK is no consistent with the one I have for class 1 server certificate and needs to be added to the 'cacerts' file.
  2. The OpenJDK trust manager accepts a valid certificate, even though the common name is not the same as that specified. This double brokenness gets over the TLS SNI issues.

JDK 6

The Sun JDK/JRE and OpenJDK do not support TLS Server Name Indication (SNI).

JDK 7

It appears that JDK/JRE 7 will support client TLS SNI. At the time of writing this feature has been added and beta versions are available.

The boolean property 'jsse.enableSNIExtension' controls whether TLS SNI extensions are supported in the client. The default is for this to be 'true' (enabled). The JSSE reference guide reads:

       
* jsse.enableSNIExtension system property. Server Name Indication (SNI) is a TLS extension, defined in RFC 4366. It enables TLS connections to virtual servers, in which multiple servers for different network names are hosted at a single underlying network address.

Some very old SSL/TLS vendors may not be able handle SSL/TLS extensions. In this case, set this property to false to disable the SNI extension.

The support seems to be added in this changeset. This bug reports it fixed in 'Java 7 b118'

Links

Appendices

SSLPoke Failure

$ java SSLPoke teamcity.lucidsolutions.co.nz 443
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
   unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:324)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:224)
        at sun.security.validator.Validator.validate(Validator.java:235)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:147)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:230)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:270)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1144)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:610)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:546)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:913)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1158)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:652)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:78)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:92)
        at SSLPoke.main(SSLPoke.java:31)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:197)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:319)
        ... 15 more

Add StartCOM StartSSL ca certificate

# wget http://www.startssl.com/certs/ca.crt
# keytool -importcert -alias startssl-manual -keystore /usr/lib/jvm/jre-openjdk/lib/security/cacerts -file ca.crt

Java version

$ java -version
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.8) (rhel-1.22.1.9.8.el5_6-x86_64)
OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)
Document Actions