Kenny Cason
Kenny Cason

Reputation: 557

SSLSocketFactory in Java, LDAP network connection

My question is similar to: SSLSocketFactory in java

I need to set a custom SSLSocketFactory...except I do NOT have an https connection (it's LDAPS), so can't use:

HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

...to set the SSLSocketFactory. I have an SSLContext object initialized but when I make the LDAP connection the default SSLContext is called automatically since my custom one is not set:

dirContext = new InitialDirContext(env); // <-- reverts to default ssl context

Is there a non-HTTPS equivalent method to line #3 below:

  1. SSLContext sc = SSLContext.getInstance("SSL");

  2. sc.init(myKeyManagerFactory.getKeyManagers(), myTrustManagerArray, new java.security.SecureRandom());

  3. HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

Upvotes: 1

Views: 3056

Answers (2)

laoseth
laoseth

Reputation: 81

Note, if the issue is just a hostname mismatch (which is super common in clustered Active Directory Environments), you can just set the system property com.sun.jndi.ldap.object.disableEndpointIdentification to true, so as a command line arg -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

Note this will only ignore a hostname mismatch on the certificate, you will still need to have a trust chain from ldap's cert to something in your truststore, but this seems to be the most common issue people have with SSL, LDAP and Active Directory, as the certificate's the domain generate for each domain controller don't include a subject alternate name for the domain itself, so if you follow the standard example of just pointing ldap to yourcomapanydomain.com, when it resolves to domaincontroller1.yourcompanydomain.com you get a failure. Note, if you are upgrading from an old java version, this behavior changed in https://www.oracle.com/java/technologies/javase/8u181-relnotes.html

Upvotes: 0

Eng.Fouad
Eng.Fouad

Reputation: 117569

Yes, there is.

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

UnsecuredSSLSocketFactory.java:

public class UnsecuredSSLSocketFactory extends SSLSocketFactory
{
    private SSLSocketFactory socketFactory;

    public UnsecuredSSLSocketFactory()
    {
        try
        {
            var sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{new X509TrustManager()
            {
                @Override
                public void checkClientTrusted(X509Certificate[] xcs, String string){}

                @Override
                public void checkServerTrusted(X509Certificate[] xcs, String string){}

                @Override
                public X509Certificate[] getAcceptedIssuers()
                {
                    return null;
                }
            }}, new SecureRandom());
            socketFactory = sslContext.getSocketFactory();
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("unused")
    public static SocketFactory getDefault()
    {
        return new UnsecuredSSLSocketFactory();
    }

    @Override
    public String[] getDefaultCipherSuites()
    {
        return socketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites()
    {
        return socketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException
    {
        return socketFactory.createSocket(socket, string, i, bln);
    }

    @Override
    public Socket createSocket(String string, int i) throws IOException
    {
        return socketFactory.createSocket(string, i);
    }

    @Override
    public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException
    {
        return socketFactory.createSocket(string, i, ia, i1);
    }

    @Override
    public Socket createSocket(InetAddress ia, int i) throws IOException
    {
        return socketFactory.createSocket(ia, i);
    }

    @Override
    public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException
    {
        return socketFactory.createSocket(ia, i, ia1, i1);
    }

    @Override
    public Socket createSocket() throws IOException
    {
        return socketFactory.createSocket();
    }
}

Upvotes: 2

Related Questions