0

I'm trying LDAPS authentication, but I'm ignoring the SSL certificate.

public class BlindSSLSocketFactoryTest extends SocketFactory {

    private static SocketFactory blindFactory = null;

    static {
        TrustManager[] blindTrustMan = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkClientTrusted(X509Certificate[] c, String a) {
            }

            public void checkServerTrusted(X509Certificate[] c, String a) {
            }
        }};

        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, blindTrustMan, new java.security.SecureRandom());
            blindFactory = sc.getSocketFactory();
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
    }

    public static SocketFactory getDefault() {
        return new BlindSSLSocketFactoryTest();
    }

    public Socket createSocket(String arg0, int arg1) throws IOException,
            UnknownHostException {
        return blindFactory.createSocket(arg0, arg1);
    }

    public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
        return blindFactory.createSocket(arg0, arg1);
    }

    public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
            throws IOException, UnknownHostException {
        return blindFactory.createSocket(arg0, arg1, arg2, arg3);
    }

    public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2,
            int arg3) throws IOException {
        return blindFactory.createSocket(arg0, arg1, arg2, arg3);
    }
}

Also

        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, LDAP_SERVER);

        env.put("java.naming.ldap.factory.socket", BlindSSLSocketFactoryTest.class.getName());

When running on the development PC, it works as expected: certificate ignored, and authentication successful.

When running on an ARM device with OpenJDK, instead I get

javax.naming.CommunicationException: simple bind failed: 10.1.10.201:636 [Root exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present]
        at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:219)
        at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2791)
        at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
        at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
        at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
        at javax.naming.InitialContext.init(InitialContext.java:244)
        at javax.naming.InitialContext.<init>(InitialContext.java:216)
        at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at LDAP1.main(LDAP1.java:59)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:931)
        at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
        at com.sun.jndi.ldap.Connection.run(Connection.java:877)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.cert.CertificateException: No subject alternative names present
        at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:145)
        at sun.security.util.HostnameChecker.match(HostnameChecker.java:94)
        at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:459)
        at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1026)
        at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:993)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
        ... 12 more

Why is that and how can I make the device behave like the pc?

Please refrain to comment "you should fix the certificate instead", thanks.

michelemarcon
  • 23,277
  • 17
  • 52
  • 68
  • Possible duplicate of [How to fix the "java.security.cert.CertificateException: No subject alternative names present" error?](https://stackoverflow.com/questions/19540289/how-to-fix-the-java-security-cert-certificateexception-no-subject-alternative) – Lino Mar 14 '19 at 13:28
  • 1
    I think that is a non-fitting duplicate as they already implemented everything that is suggested there. Could it be related to https://bugs.openjdk.java.net/browse/JDK-8139942? Suggesting that `getSocket()` is used over `getSocket(String, int)` which leads to your SSLSocketFactory not falling back on your `blindFactory`? – Ben Mar 14 '19 at 13:29
  • @Ben It doesn't work. However, that code makes the error I see on the ARM device to appear on the development pc – michelemarcon Mar 14 '19 at 14:55

1 Answers1

0

I needed to disable the endpoint identification

-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

michelemarcon
  • 23,277
  • 17
  • 52
  • 68