1
votes

I have certificates stored in LDAP server, and we use this certificate to sign the request that will be sent to other system.

and I'm using java.security.cert.CertStore class to retrieve the certificate from LDAP,

however, when my LDAP server is down (for example I have issued a firewall block to ldap server from the server where my application runs) then "CertStore.getInstance("LDAP", ldapCertStoreParams);" doesn't timeout and hangs forever.

I have also used a Future task so that I can timeout the process of connecting in case if it’s taking too long. Even though the Future task times out but still the underlying thread that trying to connect the LDAP is not timing out and hangs indefinitely

After some research I found that there is JNDI property com.sun.jndi.ldap.read.timeout can be used for the LDAP operations, like by setting this in environment variable within JNDI context.

env.put("com.sun.jndi.ldap.read.timeout", "5000");

causes the LDAP service provider to abort the read attempt if the server does not respond with a reply within 5 seconds.

But, since I am using SUN's CertStore provider it doesn't have any facility to set the above property so that thread can timeout if the LDAP server is not responding within a specified time period. I am stuck on how to use this property with CertStore object.

Does anyone have any idea on how to timeout the CertStore.getInstance("LDAP", ldapCertStoreParams) method when the LDAP server is not accessiable?

OR is there any other LDAP provider api where the dead connections are handled properly that can be used to retrieve the certificates from LDAP.

Any help is much appreciated

Below is the code snippet for retrieving the certificates from LDAP.

   protected CertStore getLdapCertStore(final CertStoreParameters ldapCertStoreParams) throws InterruptedException, ExecutionException, TimeoutException {
    final Callable<CertStore> connectionTask = new Callable<CertStore>() {
        public CertStore call() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
            return CertStore.getInstance("LDAP", ldapCertStoreParams);
        }
    };

    final Future<CertStore> futureConnection = getCertStoreConnectionExecutor().submit(connectionTask);
    return futureConnection.get(connectionTimeoutInSeconds, TimeUnit.SECONDS);
}

private synchronized ExecutorService getCertStoreConnectionExecutor() {
    if (certStoreConnectionExecutor == null) {
        // We want one thread per connection-setting, as any connection attempt can hang indefinitely if the port is blocked (e.g.: by a firewall)
        // NOTE: Cancelling a Future task does NOT guarantee that the associated thread will be freed and returned to the pool, as threads are not forcefully stopped (only *requested* to stop)!
        certStoreConnectionExecutor = Executors.newFixedThreadPool(Math.max(1, getLdapHostAndPortList().size()));
    }
    return certStoreConnectionExecutor;
}
1
Setting a read timeout can't have any effect when you can't even create a connection. What you need is a connect timeout. NB connect doesn't block forever: only for a minute or so. - user207421
Yes good suggestion however, I can't see any methods or a way to set the JNDI property "com.sun.jndi.ldap.connect.timeout" when I'm using the CertStore class, as its Sun library which internally manages the connection to LDAP server and does not provide any method to set the JNDI properties. Any ideas? - Enthu Leo

1 Answers

0
votes

You can still set the LDAP jndi properties by creating a jndi.properties file, within it you can set the connect and read timeouts. I've still found issues with the LDAP cert store despite this, namely, the first read attempt and cert check will fail when it enters this state, and then the next check will succeed when it reconnects. Using jndi pooling doesn't help either. What's worse, if it gets into this state, the enginegetcrls method is synchronized, so anything else trying to read from the cert store will hang if there is a stale connection. I realize this is 6 years old, but this same issue has caused me a headache recently.