title: SSL Connection to LDAP via Java
body: <p>Update: I never got this working over SSL. I ended up implementing a VPN in order to get the security.</p>
  
  <p>I've been trubleshooting this problem for 2 days and cannot figure it out for the life of me. I've reviewed the following threads:</p>
  
  <p><a href="https://stackoverflow.com/questions/9619030/resolving-javax-net-ssl-sslhandshakeexception-sun-security-validator-validatore">Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?</a></p>
  
  <p><a href="https://stackoverflow.com/questions/14465089/ssl-connection-in-glassfish-3-1">https://stackoverflow.com/questions/14465089/ssl-connection-in-glassfish-3-1</a></p>
  
  <p>Among many others.</p>
  
  <p>UPDATE: Sorry, I didn't even post the error I'm getting. Here it is:</p>
  
  <pre><code>javax.naming.CommunicationException: simple bind failed: server.local:636 [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
  </code></pre>
  
  <p>I'm also using GlassFish server 3.1.2 and NetBeans 7.3 on Win7 pro.</p>
  
  <p>Here is the code that is causing the error:</p>
  
  <pre><code>Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  env.put(Context.PROVIDER_URL, "ldap://server.local:636/");
  
  // Specify SSL
  env.put(Context.SECURITY_PROTOCOL, "ssl");
  
  // Fill in secuirty/bind variables
  env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
  env.put(Context.SECURITY_PRINCIPAL, config.Config.getSECURITY_PRINCIPAL()); //returns user@domain.local
  env.put(Context.SECURITY_CREDENTIALS, config.Config.getSECURITY_CREDENTIALS()); //returns password
  
  // Create the initial context
  ctx =  new InitialDirContext(env); //defined above as InitialDirContext ctx = null;
  </code></pre>
  
  <p>I have used <code>ldp.exe</code> to confirm that SSL is configured properly on our AD server. Furthermore, I've tried the following:</p>
  
  <ol>
  <li>Importing the client certificate (and the CA root certificate from AD CS) as outlined <a href="https://stackoverflow.com/questions/6659360/how-to-solve-javax-net-ssl-sslhandshakeexception-error" title="here">here</a> </li>
  </ol>
  
  <p>a. I used the following commands:</p>
  
  <pre><code>C:\Program Files (x86)\Java\jdk1.7.0_25&gt;bin\keytool -import -file SBS2011.sage.local_sage-SBS2011-CA.crt -keystore .\jre\lib\security\cacerts -alias SBS2011
  Enter keystore password:
  Certificate already exists in keystore under alias &lt;mykey&gt;
  Do you still want to add it? [no]:  yes
  Certificate was added to keystore
  </code></pre>
  
  <p>C:\Program Files (x86)\Java\jdk1.7.0_25></p>
  
  <ol start="2">
  <li><p>Uninstalling Java and reinstalling, then repeating step 1. </p></li>
  <li><p>Adding the following lines of code: </p>
  
  <p><code>System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jdk1.7.0_25\\jre\\lib\\security\\cacerts");</code></p>
  
  <p><code>System.setProperty("javax.net.ssl.trustStorePassword", "changeit");</code></p></li>
  </ol>
  
  <p>Other notes: the code works fine using non-SSL connection but then I get LDAP error 53 when trying to update user's information. In the end if there is a solution that involves not using SSL, I don't mind.</p>