As I do not have an account on https://bugs.openjdk.java.net, yes I have submitted a standard oracle java bug report, I thought it might be of interest to those on this mailing list to forward information on how some java ldap users since the JDK-806769 fix may encounter invalid ldaps hostname issues.
When an "ldaps" provider url is set in the environment and a custom SocketFactory, which sets the SSLSocket endpoint identification algorithm to "LDAPS", is set in the ldap environment hostname because of the way the fix for JDK-806769 was implemented some clients encounter a CertificateException. This occurs because the code inside the com.sun.jndi.ldap.Connection class createSocket method[0] "prefers" to invoke the socketFactory.createSocket() method instead of socketFactory.createSocket(String host, int port) when a connection timeout is set, which results in the host not being set in the created ssl socket instance. Steps to reproduce: 1. git clone https://bitbucket.org/atlassian/cwd-4444-java-bug-reproducer.git 2. build the code - `cd src/main/java && javac Broken.java Main.java Working.java` 3. run the Main class and provide an ldaps url - `java Main ldaps://example.java:10636` 4. Observe that when the "Broken" SocketFactory is in use a hostname verification error occurs. Workaround: Naturally, one can workaround the Connection class's "preference" for the no argument createSocket method by not having such a method in the SocketFactory set in the ldap environment. Untested potential patch: --- Connection.java.orig 2015-09-25 11:39:26.323117929 +1000 +++ Connection.java 2015-09-25 12:41:04.175068697 +1000 @@ -33,6 +33,7 @@ import java.io.InputStream; import java.net.Socket; import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; import javax.naming.CommunicationException; import javax.naming.ServiceUnavailableException; @@ -287,7 +288,40 @@ Method createSocket = null; - if (connectTimeout > 0) { + if (connectTimeout > 0 && socketFactoryClass instanceof SSLSocketFactory) { + + try { + Socket sock = null; + createSocket = socketFactoryClass.getMethod("createSocket", + new Class<?>[]{Socket.class, String.class, + int.class, boolean.class}); + Constructor<Socket> socketCons = + Socket.class.getConstructor(new Class<?>[]{}); + + Method connect = Socket.class.getMethod("connect", + new Class<?>[]{Class.forName("java.net.SocketAddress"), + int.class}); + Object endpoint = createInetSocketAddress(host, port); + + // unconnected underlying socket + sock = socketCons.newInstance(new Object[]{}); + + if (debug) { + System.err.println("Connection: creating socket with " + + "a timeout"); + } + // connect the underlying socket + connect.invoke(sock, new Object[]{ + endpoint, new Integer(connectTimeout)}); + // connect the ssl socket + socket = createSocket(sock, host, port, true); + + } catch (NoSuchMethodException e) { + // continue + } + } + + if (connectTimeout > 0 && socket == null) { try { createSocket = socketFactoryClass.getMethod("createSocket", [0] http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/7d1d5f4d019a/src/share/classes/com/sun/jndi/ldap/Connection.java#l272 -- David Black / Security Engineer.