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

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

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

The following TrustManager do not meet our product requirements:

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

I do not want any interaction with the user, and that I missed in the list above TrustManager, which checks the issuance of certificates.

In addition, I do not want to embed the LDAP server certificate in any keystore, so I cannot 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); 

Note that CertificateTrustManager does not exist in the UnboundID SDK. How can I do that?

+4
source share
3 answers

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

Now I can take the certificate from the user interface 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); 
+4
source

If there is a specific certificate or a set of certificates that you want to trust, you can simply create your own javax.net.ssl.X509TrustManager implementations that examine the presented certificate chain and determine if it represents one of the expected certificates, you can hard-code the information about these certificates in your code (or, even better, put it in the configuration file so that you can change it without changing any code) and do something like comparing certificate fingerprints to get with tvetstvuyuschuyu degree of confidence that this is actually a legitimate certificate.

If you do not know what the individual certificates will be, but you know that all of them have a common issuer, and you trust the issuer only to issue good certificates, then you can include the trust information for this issuer.

If you want to allow a number of unknown certificates, potentially from unreliable issuers (and you don’t know what these issuers may have beforehand), and you don’t want to ask the user to trust them (which you can cache, so you only need to once ask), then I'm not sure what you could do. If you cannot find a way to distinguish certificates from good servers from servers with bad servers, then your application will be at risk of either trusting bad certificates or not trusting good ones.

+3
source

Although this is not recommended for security reasons, it is sometimes useful, at least for testing situations, to use TrustAllTrustManager as follows:

 TrustAllTrustManager tm = new TrustAllTrustManager(); TrustManager[] trustManagers = new TrustManager[] {tm}; SSLUtil sslUtil = new SSLUtil(trustManagers); SSLSocketFactory socketFactory = sslUtil.createSSLSocketFactory(); LDAPConnection connection = new LDAPConnection(socketFactory); 

It is NOT intended for use in production environments!

-1
source

Source: https://habr.com/ru/post/1491448/


All Articles