I wrote a java client to connect to Ldap over ssl. I imported CA certificates to my java key store and I am able to connect Ldap over ssl and pull information. The problem is it is not working always. Often it throws:CommunicationException:sun.security.validator.ValidatorException: PKIX path building failed. If I re run again (with out changing anything) it works.
This issue killing me for days, as a work around I am catching this exception and retrying. But I am looking for a permanent fix. Any help would be greatly appreciated.
Below is the code where I get the context:
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, securityPrincipal);
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_CREDENTIALS, securityCredential);
env.put("java.naming.provider.url", url);
return new InitialLdapContext(env, null);
Strack Trace:
javax.naming.CommunicationException: simple bind failed: adapps.nms.comm:636 [Root 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]
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:215)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2685)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:306)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:211)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at javax.naming.InitialContext.init(InitialContext.java:240)
at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:151)
at NMSLdapServiceDAOImpl.getLdapContext(NMSLdapServiceDAOImpl.java:149)
at NMSLdapServiceDAOImpl.getUserByNTID(NMSLdapServiceDAOImpl.java:97)
at NMSLdapServiceDAOImpl.main(NMSLdapServiceDAOImpl.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: 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
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1682)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:257)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:251)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1168)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:609)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:545)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:930)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1175)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:805)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:94)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at com.sun.jndi.ldap.Connection.run(Connection.java:820)
at java.lang.Thread.run(Thread.java:679)
Caused by: 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:1147)
... 12 more
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)
... 18 more
CommunicationException:sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.naming.CommunicationException: simple bind failed: adapps.nms.com:636 [Root 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]
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:215)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2685)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:306)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:211)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at javax.naming.InitialContext.init(InitialContext.java:240)
at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:151)
at NMSLdapServiceDAOImpl.getLdapContext(NMSLdapServiceDAOImpl.java:149)
at NMSLdapServiceDAOImpl.getUserByNTID(NMSLdapServiceDAOImpl.java:97)
at NMSLdapServiceDAOImpl.getUserByNTID(NMSLdapServiceDAOImpl.java:109)
at NMSLdapServiceDAOImpl.main(NMSLdapServiceDAOImpl.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: 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
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1682)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:257)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:251)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1168)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:609)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:545)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:930)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1175)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:657)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:108)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at com.sun.jndi.ldap.Connection.writeRequest(Connection.java:409)
at com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:352)
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:210)
... 19 more
Caused by: 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:1147)
... 31 more
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)
... 37 more
CommunicationException:sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.naming.CommunicationException: simple bind failed: adapps.nms.com:636 [Root 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]
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:215)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2685)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:306)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:211)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at javax.naming.InitialContext.init(InitialContext.java:240)
at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:151)
at NMSLdapServiceDAOImpl.getLdapContext(NMSLdapServiceDAOImpl.java:149)
at NMSLdapServiceDAOImpl.getUserByNTID(NMSLdapServiceDAOImpl.java:97)
at NMSLdapServiceDAOImpl.getUserByNTID(NMSLdapServiceDAOImpl.java:109)
at NMSLdapServiceDAOImpl.getUserByNTID(NMSLdapServiceDAOImpl.java:109)
at NMSLdapServiceDAOImpl.main(NMSLdapServiceDAOImpl.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: 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
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1682)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:257)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:251)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1168)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:609)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:545)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:930)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1175)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:657)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:108)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at com.sun.jndi.ldap.Connection.writeRequest(Connection.java:409)
at com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:352)
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:210)
... 20 more
Caused by: 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:1147)
... 32 more
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)
... 38 more
You should import certificate of the server:port to java JRE keystore for example for following server and port:
serverAddress: myserver.mydomain.com
serverPort: 443
keystore password is default: changeit
First of all, check $JAVA_HOME and java executable before continue, you should be sure about the choosing correct JAVA_HOME for importing , if you have different ones:
$ ~/bin$ echo $JAVA_HOME
/opt/jdk
$ ~/bin$ which java
/usr/bin/java
$ ~/bin$ ls -l /usr/bin/java
lrwxrwxrwx 1 root root 22 May 10 2014 /usr/bin/java -> /etc/alternatives/java
$ ~/bin$ ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 17 Jun 6 2014 /etc/alternatives/java -> /opt/jdk/bin/java
$ ~/bin$ java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
$ ~/bin$ `which java` -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
$ ~/bin$ $JAVA_HOME/bin/java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
Extracting certificate from the server:
$ openssl s_client -connect <serverAddress:serverPort> 2>&1 < "/" | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/myserver.crt
For this example <serverAddress:serverPort>
should be replaced with myserver.mydomain.com:443
The extracted file should be look like as follows:
$ cat /tmp/myserver.crt
-----BEGIN CERTIFICATE-----
blahblahblahaC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCd
ME22AKpyBPIRbTwTBedJz/KFtwCAxO2jXIcIob99LXv8W4KMOJgazn2UUBm/azZ1
z+9qhq3UeIy8Z58WK2N5l/SI7s3+bkii/dnpW3Akw8OyXABnN1EyfwnL607POqXm
blahblahblah
...Certificate Data is variable for each server address...
blahblahblah
blahblahblahT9p1jar2vxoHv3/dSwKoeLL8XpkmVx9oVUZ3XuICPvEmu8eBfOEm
ZXNlYXJjaC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCd4I7L
ME22AKpyBPIRbTwTBedJz/KFtwCAxO2jXIcIob99LXv8W4KMOJgazn2UUBm/azZ1
-----END CERTIFICATE-----
You need to import the extracted certificate into JRE keystore:
$ keytool -import -alias myserverCert -file /tmp/myserver.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
You can check that the certification existence in java JRE keystore or not after the import:
$ keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
Default password for java JRE keystore is
changeit
For applying the changes you need to restart the java JVM.
After finish you can remove the temporary file if you had created it in a non temporary place:
$ rm /tmp/myserver.crt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With