Using TLS encryption with the TDI LDAP connector

Many TDI connectors have the ability to use SSL encryption on network connections, but this has been deprecated by the IETF standards for some years. The preferred security mechanism is TLS (Transport Layer Security) as defined in RFC2246, RFC4346 and RFC5246. Unfortunately, TDI 7.0 does not yet have a simple tick-box to support TLS in connectors so we need to add some code (not very much though).

Negotiating TLS

The whole point of using TLS rather than SSL is that TLS can be negotiated after the application protocol has started. Thus an LDAP server for example only needs to listen on one TCP port to handle both encrypted and unprotected sessions.

From a TDI point of view, this means that we can intervene in a connector hook to add TLS protection and the rest of the system does not need to know what we have done. Here is some code to start TLS:

var ctx;

try{
   ctx = thisConnector.connector.getLdapContext();
   tls = ctx.extendedOperation(new Packages.javax.naming.ldap.StartTlsRequest());

   task.logmsg("Negotiating TLS");
   tls.negotiate();
   task.logmsg("TLS OK");
} catch (E) {
   task.logmsg("TLS negotiation FAILED");
   task.logmsg(E);
   tls.close();
   tls=null;
   throw(E);
}

// Now it is safe to authenticate...

try {
   ctx.addToEnvironment(
      Packages.javax.naming.Context.SECURITY_PRINCIPAL,
      "uid=tdi,dc=example,dc=org");
   ctx.addToEnvironment(
      Packages.javax.naming.Context.SECURITY_CREDENTIALS,
      "myPassword");

   ctx.reconnect(null);
} catch (E) {
   task.logmsg("Bind failed after TLS negotiation");
   throw(E);
}

Note that the bind DN and password should not be specified in the connector configuration, as they will be sent before TLS is established.

It would seem reasonable to put this code in the After Initialise hook, but if the connector is in Iterator mode that does not work as the LDAP search is issued first! Thus in an LDAP iterator the code must go in the Before Selection hook.

Drop the code snippet into a suitable connector and try it. You are likely get a failure message even with a TLS-enabled LDAP server, as the cryptographic trust relationship must be set up before TLS negotiation will succeed.

Key and Certificate management

To set up the cryptographic trust relationship you need to import the CA certificate that signed the LDAP server's certificate. (If you are using a self-signed certificate then just import that, but such relationships are harder to manage in the long run).

TDI 7 comes with the IBM Key Manager that can be started by clicking the 'key manager' button at the top of the CE window. This will allow you to import standard PEM certificates into the JKS keystores that TDI uses.

The complication here is that TDI already uses SSL/TLS when talking to the runtime server, so you must preserve or replace the keys used for that purpose. By default, the same file is used as both keystore and truststore. It is /opt/IBM/TDI/V7.0/serverapi/testadmin.jks and the password for it is administrator Note also that the keys in the default version expire on 7th September 2010, so if your CE stops talking to the development server on that day you will know why!

I suggest copying the supplied file and editing your solution.properties file to point to your local copy. Look for these items:
javax.net.ssl.trustStore {protect}-javax.net.ssl.trustStorePassword
javax.net.ssl.keyStore {protect}-javax.net.ssl.keyStorePassword

Use the key manager to import your own CA certificate as a Signer Certificate. TDI should now be able to use TLS when making connections to any server whose certificate was signed by that CA.

A Simple CA

The IBM Key Manager will make self-signed certificates, but will not run a CA for you. Here is a quick way to build a certificate hierarchy using OpenSSL:

First make the Certificate Authority (only need to do this ONCE):

  openssl genrsa -aes128 -out ca.key 2048
  openssl req -new -x509 -days 8000 -key ca.key -out ca.cert

Fill in the fields as appropriate - not much is critical here Remember the passphrase for the CA key!

Useful info comes from these:

  openssl x509 -in ca.cert -noout -hash
  openssl x509 -in ca.cert -noout -text

Now make a key and certificate for servers accessed through localhost:

  openssl genrsa -out localhost.key 1024
  openssl req -new -key localhost.key -out localhost.csr

The critical thing here is that the CN field must be 'localhost'

Sign the certificate with your CA:

  openssl x509 -req -in localhost.csr -out localhost.cert -CA ca.cert -CAkey ca.key -CAcreateserial -days 7999

Check the certificate:

  openssl x509 -in localhost.cert -noout -text

Thanks

The TLS code snippet is based on a newsgroup posting by Ezra Epstein.

-- AndrewFindlay - 03 Jun 2010
Topic revision: r3 - 09 Sep 2011, AndrewFindlay - This page was cached on 04 Aug 2023 - 17:11.

This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TDI Users? Send feedback