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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.