Hi,

connecting to a secure ldap server with a SNA certificate fails with
"javax.naming.CommunicationException: simple bind failed: ldap.foo.bar:636 [Root exception is javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching ldap.foo.bar found.]"

The certificate is valid and i've tested it on https on the same machine which works flawlessly. The problem does not effect the Oracle JDK/JRE, only OpenJDK. I've testen OpenJDK 1.8.0_181, 11.0.1, 11.0.2 and all are affected.


With best regards

Heiko Jakob


How to reproduce:
Have a valid certificate for a host named CN "realhost.foo.bar" with x509 SNA extension for DNS.1 "realhost.foo.bar" DNS.2 "ldap.foo.bar". Use the same certificate for https & ldap on the same host.

Examine the certificate to have CN="realhost.foo.bar" and x509 SNA extension for ldap.foo.bar
$ openssl x509 -in my.crt -text -noout | less
Certificate:

...

       Validity
            Not Before: Feb  8 11:28:53 2019 GMT
            Not After : Feb  7 11:28:53 2024 GMT
        Subject: C = DE, ST = BW, L = Stuttgart, O = foo.bar, OU = IT Department, CN = realhost.foo.bar
...
            X509v3 Subject Alternative Name:
                DNS:realhost.foo.bar, DNS:ldap.foo.bar


Run the following small test program to reproduce the problem.

package testSSL;

import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public final class TestSSL {

    public static void main(String[] args) {
        String url_l = "ldaps://ldap.foo.bar:636";
        String url_h = "https://ldap.foo.bar";;

        System.out.println("TestSSL");
        URL url;
        try {
            System.out.println("Test " + url_h);
            url = new URL(url_h);
            URLConnection conn = url.openConnection();
            conn.connect();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Failed " + url_h);
            System.exit(-1);
        }
        System.out.println("https:// OK");


        System.out.println("Test " + url_l);
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, url_l);
        env.put(Context.SECURITY_PROTOCOL, "ssl");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=foo,dc=bar");
        env.put(Context.SECURITY_CREDENTIALS, "mysecret");
        try {
            DirContext ctx = new InitialDirContext(env);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Failed " + url_l);
            System.exit(-1);
        }
        System.out.println("ldaps:// OK");
    }
}

Test it against various JDKs

$ (for j in $(find /opt/java/ -type f -name 'java' 2> /dev/null); do echo $j; $j -version; $j -classpath ./ testSSL.TestSSL; echo""; echo "##############################################";echo ""; sleep 30; done ) 2>&1 | tee -a testSSL.out

Reference output from oracle JDK

opt/java/jdk1.8.0_73/bin/java
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)
TestSSL
https://ldap.foo.bar
https:// OK
ldaps://ldap.foo.bar:636
ldaps:// OK

##############################################
....
##############################################

/opt/java/jdk-11.0.2/bin/java
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
TestSSL
https://ldap.foo.bar
https:// OK
ldaps://ldap.foo.bar:636
javax.naming.CommunicationException: simple bind failed: ldap.foo.bar:636 [Root exception is javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching ldap.foo.bar found.]         at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:219)
        at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2795)
        at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:320)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)         at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)         at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)         at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)         at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:730)         at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)         at java.naming/javax.naming.InitialContext.init(InitialContext.java:236)         at java.naming/javax.naming.InitialContext.<init>(InitialContext.java:208)         at java.naming/javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at testSSL.TestSSL.main(TestSSL.java:57)
Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching ldap.foo.bar found.         at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)         at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)         at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)         at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)         at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:642)         at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:461)         at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:361)         at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)         at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)         at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)         at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:178)         at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)         at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)         at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)         at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)         at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:716)         at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:970)         at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)         at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)         at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:398)         at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:371)         at java.naming/com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:359)         at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:214)
        ... 12 more


Reply via email to