Search code examples
sslldapssl-certificateldapconnectionunboundid-ldap-sdk

How to use UnboundID SDK to connect to an LDAP server with the SSL server certificate?


I have in my hand an SSL LDAP server certificate. I want to use it to connect to the LDAP server using UnboundID SDK.

I do not want to use com.unboundid.util.ssl.TrustAllTrustManager as was showed here: Using UnboundID SDK with an SSL certificate file to connect to LDAP server in Android app

The following TrustManagers not fit our product requirements:

com.unboundid.util.ssl.PromptTrustManager
com.unboundid.util.ssl.HostNameTrustManager
com.unboundid.util.ssl.ValidityDateTrustManager

I do not want any user interaction, and what I miss in the list above the TrustManager that validate the certificate issuers.

Also, I do not want to insert the LDAP server certificate in any keystore, so I can not use the following TrustManagers:

com.unboundid.util.ssl.WrapperKeyManager
com.unboundid.util.ssl.PKCS11KeyManager
com.unboundid.util.ssl.KeyStoreKeyManager

I want to do something like the code below:

CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(byteArrayInputStream);
SSLUtil sslUtil = new SSLUtil(new CertificateTrustManager(cert));
SSLSocketFactory socketFactory = sslUtil.createSSLSocketFactory();
LDAPConnection connection = new LDAPConnection(socketFactory,
     "server.example.com", 636);

Please note, that CertificateTrustManager does not exist in UnboundID SDK. How is possible to do it?


Solution

  • I found the solution using Using UnboundID SDK with an SSL certificate file to connect to LDAP server in Android app and How to import a .cer certificate into a java keystore? (answer of Patrick M).

    Now I can take a certificate from UI and connect to LDAP via SSL :)

    import com.unboundid.ldap.sdk.LDAPConnection;
    import com.unboundid.util.ssl.SSLUtil;
    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import java.io.ByteArrayInputStream;
    import java.security.KeyStore;
    import java.security.cert.Certificate;
    import java.security.cert.CertificateFactory;
    
    String base64EncodedCertificateString = "...";
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64EncodedCertificateString.getBytes());
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(null);
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    int i = 0;
    while (byteArrayInputStream.available() > 0) {
        Certificate cert = cf.generateCertificate(byteArrayInputStream);
        trustStore.setCertificateEntry("cert " + i++, cert);
    }
    
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
    tmf.init(trustStore);
    TrustManager[] trustManagers = tmf.getTrustManagers();
    SSLUtil sslUtil = new SSLUtil(trustManagers);
    SSLSocketFactory socketFactory = sslUtil.createSSLSocketFactory();
    LDAPConnection connection = new LDAPConnection(socketFactory);
    connection.connect("place.myserver.com", 636);