Question

I am trying to connect to an LDAP server with SSL enabled. I dont want to use authentication hence i have overridden SSLSocketFactory to allow every site. I am getting following error:

main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: **handshake_failure**
    javax.naming.CommunicationException: slc00ahj.us.oracle.com:3131 Root exception is javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

at com.sun.jndi.ldap.Connection.<init>(Connection.java:209)
at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:116)
at com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1582)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2678)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:296)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:82)
at SumanLdapTest1.main(SumanLdapTest1.java:37)

SSL log is :

 Allow unsafe renegotiation: false
    Allow legacy hello messages: true
    Is initial handshake: true
    Is secure renegotiation: false
    main, setSoTimeout(120) called
    %% No cached client session
    ClientHello, TLSv1 
    RandomCookie: GMT: 1357201614 bytes = { 70, 133, 164, 224, 89, 101, 204, 41, 107, 201, 176, 66, 93, 118, 139, 59, 50, 176, 84, 197, 238, 236, 187, 211, 158, 43, 159, 112 }
    Session ID: {}
    Cipher Suites: SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV
    Compression Methods: { 0 }
    ***
    **main, WRITE: TLSv1 Handshake, length = 75
    main, READ: TLSv1 Alert, length = 2
    main, RECV TLSv1 ALERT: fatal, handshake_failure
    main, called closeSocket()**




**My source code:**





    public class **SumanLdapTest1**{
        public static void main(String args[]){
       try{
                //System.setProperty("ldaps.protocols", "TLSv1");
                 System.out.println("here");
                 DirContext ctx = null;
            String host="slc00ahj.us.oracle.com"; 
            String port="3131";
            String userName="cn=orcladmin";
            String password="welcome1";
            Hashtable<String, String> env = new Hashtable<String, String>();
            env.put(Context.INITIAL_CONTEXT_FACTORY,
                            "com.sun.jndi.ldap.LdapCtxFactory");
            //env.put(Context.PROVIDER_URL, "ldap://" + host + ":"+ port+ "/");
            env.put(Context.SECURITY_PRINCIPAL, userName);
            env.put(Context.SECURITY_CREDENTIALS, password);
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put("com.sun.jndi.ldap.connect.timeout", "120");
            env.put(Context.PROVIDER_URL, "ldaps://" + host
                            + ":" + port);
            env.put(Context.SECURITY_PROTOCOL, "ssl");
            env.put("java.naming.ldap.factory.socket","**SumanSSLFactory**");
            ctx = new InitialDirContext(env);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    public class SumanSSLFactory extends SSLSocketFactory {
            private SSLSocketFactory factory = null;
        private Exception exception = null;

        public SumanSSLFactory() {
            System.out.println("LdapSSLFactory initialization started...");


            try {
                this.factory = **getSSLSocketFactory**();
            } catch (Exception ex) {
                            ex.printStackTrace();
                System.out.println("LDAPSSLFactory Initialization error");
                this.factory = null;
                this.exception = ex;
            }

            System.out.println("LdapSSLFactory Initialization completed.");
        }

        public SSLSocket createSocket() throws IOException {
            System.out.println("LdapSSLFactory.createSocket()");
            if (this.factory == null)
                throw new IOException();
            SSLSocket st=null;
            try{


                    (new Throwable()).printStackTrace();
                     st=(SSLSocket)this.factory.createSocket();
                    st.setEnabledProtocols( new String[] { "TLSv1", "SSLv3" } );  

                         }catch(Exception e){
                             e.printStackTrace();
                         }

            return st;
        }


        private SSLSocketFactory **getSSLSocketFactory**()
                        {
                SSLSocketFactory sslSocketFactory = null;
                System.out.println("Using Non Authenticated SSL Mechanism.");
                try {
                        TrustManager[] tmA = { new X509TrustManager() {
                                public X509Certificate[] getAcceptedIssuers() {
                                        X509Certificate[] issuers = new X509Certificate[0];
                                        return issuers;
                                    //return null;
                                }

                                public void checkClientTrusted(X509Certificate[] chain,
                                                String authType) throws CertificateException {
                                }

                                public void checkServerTrusted(X509Certificate[] chain,
                                                String authType) throws CertificateException {
                                }
                        } };

                        // get the SSLContext and factory
                        SSLContext ctx = SSLContext.getInstance("TLS");
                        ctx.init(null, tmA, null);
                        sslSocketFactory = ctx.getSocketFactory();
                   // System.setProperty("ldaps.protocols", "TLSv1");
                    System.out.println("SSOSocketUtil factory created sslSocketFactory"+sslSocketFactory);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    System.out.println("SSOSocketUtil factory exception");

                }

                return sslSocketFactory;
        }

    }

Any help on this will be appreciated    
Was it helpful?

Solution

I would test without using your code for starters. For example, try to test an SSL operation of some kind using one of the LDAP Utils binaries (e.g: ldapsearch, ldapwhoami, etc). Make sure SSL/TLS works that way.

If it doesn't work, check your local system LDAP settings, and ALSO verify the certificate being used by the server is not expired and not self-signed (allowing self-signed certs is allowed, but requires further configuration).

Additionally, make sure the server is listening on your special port (3131?) via LDAPS and not LDAP. If regular LDAP is used for the listener, then SSL is not supported, but TLS (StartTLS) IS supported. Do note that LDAP SSL is technically deprecated in favor of TLS. If you have the ability to use TLS instead of SSL, you should.

Lastly on the server-side, make sure the RootDSE shows the OID for TLS/SSL support (1.3.6.1.4.1.1466.20037). If you do not see this, then SSL/TLS is not supported by the server (this is true at least for OpenLDAP).

If the command-line binary test works, then I would have to assume its either the code itself OR the system LDAP settings on the HOST from which the code runs. Or both.

I'm not skilled (at all) with JAVA, but I looked through your code anyway and didn't see anything obviously wrong. If there is direct problem with the code itself, I'm the wrong person to ask =)

If you cannot fix your code, if possible, try altering your code to NOT use SSL/TLS. At least you could ascertain that the intended functionality of your code works, just not the secure transport. That at least narrows it down significantly. Of course, if there are security concerns for this type of test, you might have to make special arrangements (e.g: use stunnel, or run the script locally on the LDAP server, etc).

I hope this helps...

Max

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top