Search code examples
javasslldapjndi

Finding JNDI/LDAP Connection Security Protocol


I'm using java (8) to connect to an LDAP-Server to get some information. I'm doing this over SSL but I cannot figure out if my specified security protocol is actually being used....

Here is my code:

LdapContext ctx = null;
Hashtable<String, String> env = new Hashtable <String, String>();
try{
    env.clear();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.SECURITY_PRINCIPAL, "user");
    env.put(Context.SECURITY_CREDENTIALS, "password");
    env.put(Context.SECURITY_PROTOCOL, "ssl");
    env.put("com.sun.jndi.ldap.read.timeout", 5000);
    env.put("com.sun.jndi.ldap.connect.timeout", 5000);
    env.put(Context.PROVIDER_URL, "myurl");
    ctx = new InitialLdapContext(env, null);
} catch(NamingException nex) {
    // Errors get treated here
}
int debug_stop = 1;

Its all about Context.SECURITY_PROTOCOL in my case as the connection is successfully established. Here is some information about this paramerter: https://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-ldap-gl.html#protocol

I tried usind the following parameters (all within "" of course) :

  • ssl / SSL
  • starttls / STARTTLS
  • SSL/STARTTLS
  • TLSv1.1

but I see no change at all.

I tried debugging it in Netbeans and looking at the ctx-variable but there is so much to look at that I cannot find the right information I'm looking for.

The thing I look at is:

ctx

  • Inherited
    • defaultInitCtx
      • clnt
        • conn
          • sock
            • sess
              • protocolVersion
                • name

And this always says TLSv1 no matter what I enter in my code above.

1) Is this the protocol that the connection is using?

2) Am I looking at the wrong variable?

3) How can I determine which protocol my established connection is using?

Another thing I found was in

ctx

  • Inherited
    • defaultInitCtx
      • clnt
        • conn
          • sock
            • Inherited
              • self
                • sslContext
                  • Static
                    • defaultServerSSLParams
                      • protocols

Here I found a list that says:

  • SSLv2Hello
  • TLSv1
  • TLSv1.1
  • TLSv1.2

and so I tried using TLSv1.1 as a parameter above as well but without success...


Solution

  • According to your link (http://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-ldap-gl.html), the only value for java.naming.security.protocol is "ssl".

    With Context.SECURITY_PROTOCOL="ssl" :

    • it opens a secure SSL/TLS connexion if the serveur supports it
    • it fails with a javax.net.ssl.SSLHandshakeException otherwise

    With Context.SECURITY_PROTOCOL=any other word than "ssl", it opens a simple connection (with no SSL/TLS)

    So, with the standard factory (com.sun.jndi.ldap.LdapCtxFactory) and with "ssl" param, you use a SSL/TLS connexion or do nothing.

    You can see a lot of details of your connection with the parameter -Djava.net.debug=ssl and can see which version of TLS and cipher is used by your connection. (see http://www.herongyang.com/JDK/SSL-Socket-Communication-Debug-javax-net-debug.html)