Trying to use Java 7u25 to connect to an LDAPS server using TLSv1.2. Thus far, all connections are initiated using TLSv1. At this exact moment, I don't even care about authentication or running a search. I just want to finish the handshake at the right level.
I can bring in almost any additional libraries I might need, but I cannot move to a newer version of Java.
I've seen many questions out there about ensuring inbound connections work with TLSv1.2, and that's working fine. I've seen other questions about ensuring Java OUTBOUND connections use TLSv1.2, but they all seem to be related to the URL class.
edit 1 Djdk.tls.client.protocols=TLSv1.2 is not available to me in the version I have to use.
-Dhttps.protocols=TLSv1.2 is set
-Djavax.net.debug=ssl is set
-If I take the LDAPS Uri and use the URL class to connect, it does show a TLSv1.2 negotiation.
Partial Snippet
// set the LDAP connection properties
String dsLocation = httpRequest.getParameter("location");
String userId = httpRequest.getParameter("userId");
String pwd = httpRequest.getParameter("pwd");
String encrypted = httpRequest.getParameter("encrypted");
Properties LDAPOptions = new Properties();
LDAPOptions.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
LDAPOptions.put(Context.SECURITY_PROTOCOL, "ssl");
// check for anonymous binds
if (userId == null || userId.isEmpty()) {
LDAPOptions.put(Context.SECURITY_AUTHENTICATION, "none");
}
else {
LDAPOptions.put(Context.SECURITY_AUTHENTICATION, "simple");
LDAPOptions.put(Context.SECURITY_PRINCIPAL, userId);
LDAPOptions.put(Context.SECURITY_CREDENTIALS, pwd);
}
LDAPOptions.put(Context.PROVIDER_URL, dsLocation);
LdapContext ctx = null;
try {
// try to connect
ctx = new InitialLdapContext(LDAPOptions, null);
connected = true;
result = "success";
ctx.reconnect(null);
}
catch (AuthenticationException aex) {
result = "invalid credentials";
}
finally {
if (ctx != null) {
ctx.close();
}
}
SSL DEBUG OUT
<ignore a bunch of cipher suites>
[Oct 4, 2021 8:44:54 PM ]: Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
[Oct 4, 2021 8:44:54 PM ]: %% No cached client session
[Oct 4, 2021 8:44:54 PM ]: *** ClientHello, TLSv1
<redacted>
[Oct 4, 2021 8:44:54 PM ]: ajp-bio-8009-exec-2, WRITE: TLSv1 Handshake, length = 169
[Oct 4, 2021 8:44:54 PM ]: ajp-bio-8009-exec-2, READ: TLSv1 Handshake, length = 1970
According to https://www.baeldung.com/java-7-tls-v12 , you need Java 1.7.0_95 or later to use -Djdk.tls.client.protocols=TLSv1.2
There's also some info on how one should create a TLS1.2 socket. It's not what you'll do, but that's how it's done internally in com.sun.jndi.ldap.Connection.createSocket()
You'll see there, that you can provide a LdapCtx.SOCKET_FACTORY
with the full qualified name of a class implementing javax.net.SocketFactory
.
For SSL, maybe try sun.security.ssl.SSLSocketFactoryImpl
?
And if this is not enough, it's worth trying in DEBUG with some breakpoints in createSocket()
(I don't have Java 7 to make the test).