title: Inmemory keystore using keystore api 'unable to find valid certification path to requested target'
body: <p>I am trying to create an inmemory keystore for a single ldap request. Ldap connections and certificates can change so I can't store them anywhere.</p>
  
  <p>Spring Ldap is not very frendly to multiple ldap connections</p>
  
  <pre class="lang-java prettyprint-override"><code>    public LdapContextSource buildLdapContext(final LdapConnection connection) {
          final LdapContextSource context = new LdapContextSource();
          context.setBase(connection.getBaseDN());
          context.setUrl(connection.getConnectionUrl());
          context.setPassword(connection.getAdminPassword());
          context.setUserDn(connection.getUserDN());
  
          if(connection.getProtocol() == LdapProtocol.LDAPS) {
              final DefaultTlsDirContextAuthenticationStrategy authenticationStrategy = new DefaultTlsDirContextAuthenticationStrategy();
              authenticationStrategy.setSslSocketFactory(ldapSslSocketFactoryBuilder.buildSslSocketFactory(connection));
              context.setAuthenticationStrategy(authenticationStrategy);
          }
  
          context.afterPropertiesSet();
          return context;
      }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>    public SSLSocketFactory buildSslSocketFactory(final LdapConnection connection) {
          try {
              final KeyStore store = buildKeyStore(connection);
              final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
              tmf.init(store);
  
              final SSLContext ctx = SSLContext.getInstance("SSL");
              ctx.init(null, tmf.getTrustManagers(), null);
              return ctx.getSocketFactory();
  
          } catch(Exception e) {
              throw new LdapException(e.getMessage(), e);
          }
      }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>    private KeyStore buildKeyStore(final LdapConnection ldapConnection) {
          try {
              // Load in-memory keystore
              final KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
              keystore.load(null);
  
              // Decode certificate
              byte[] decoded = Base64.decodeBase64(ldapConnection.getSslCertificate()
                              .replaceAll(X509Factory.BEGIN_CERT, "")
                              .replaceAll(X509Factory.END_CERT, "")
                              .trim().getBytes(StandardCharsets.UTF_8));
  
              // Load certificate
              CertificateFactory certificateFactory = CertificateFactory.getInstance("x.509");
              Certificate cert = certificateFactory.generateCertificate(new ByteArrayInputStream(decoded));
              keystore.setCertificateEntry(ldapConnection.getConnectionUrl(), cert);
  
              return keystore;
          } catch(Exception e) {
              log.error(e.getMessage(), e);
              throw new LdapException(e.getMessage(), e);
          }
      }
  </code></pre>
  
  <p>I would expect that stored public key is used to connect to ldap server but instead I get "unable to find valid certification path to requested target"</p>