blob: 7c980090bebdc35d24a9b371012db342b1374ca8 [file] [log] [blame]
Title: 5.2 - StartTLS
NavPrev: 5.1-ldaps.html
NavPrevText: 5.1 - LDAPS
NavUp: 5-ldap-security.html
NavUpText: 5 - LDAP Security
NavNext: 5.3-sasl-bind.html
NavNextText: 5.3 - SASL Bind
Notice: Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
.
http://www.apache.org/licenses/LICENSE-2.0
.
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
# 5.2 - StartTLS
As we have seen in the previous chapter, **LDAPS** has some drawbacks. There is a better alternative for securing communications between the client and server -- **startTLS**.
The idea is to use an existing connection to send a message to the server and request it to be encrypted. We keep going with the current connection, on the same port, but the exchanged data will continue as encrypted.
The **startTLS** extended operation is used for this. It's a pure LDAP request that blocks other requests on the connection until it becomes secured. Of course, if some operations are pending, the operation will not be executed until the pending operations are completed.
## How to use it
It's quite simple. You just have to inform an opened connection to send the **startTLS** extended operation. It can be done at any time. Here is a quick example:
try ( LdapNetworkConnection connection =
new LdapNetworkConnection( Network.LOOPBACK_HOSTNAME, getLdapServer().getPort() ) )
{
connection.connect();
Entry admin = connection.lookup( "uid=admin,ou=system" );
// startTLS
connection.startTls();
...
As you can see, we'll used the _startTLS()_ method, and it occurred in the middle of an LDAP session. (There previously was data transmission with the server in clear text).
You can also send the _startTLS_ request prior to a bind, protecting the entire session:
try ( LdapNetworkConnection connection =
new LdapNetworkConnection( Network.LOOPBACK_HOSTNAME, getLdapServer().getPort() ) )
{
// startTLS
connection.startTls();
Entry admin = connection.lookup( "uid=admin,ou=system" );
...
That's about it...
## Advanced usage
We just saw basic usage of the **startTLS** extended operation. Keep in mind that behind the scene, a **TLS** session will be established, which requires some negotiation between the client and the server. It's not different from the establishement of an **LDAPS** connection, except that we're doing it on top of an existing **LDAP** connection. Still, the client and the server must exchange ciphers, certificates, and agree on which protocol version to use. You probably need more control.
The **startTLS()** method uses an **LdapConnectionConfig** instance for parameters in order to define things like -- **TrustManagers**, allowed ciphers, enabled protocol versions, **KeyManager** instances, etc. You simply need an **LdapConnectionConfig** instance, and load it with instructions. for example, if you want to use a specific **TrustManager** that doesn't verify the server's certificate:
LdapConnectionConfig tlsConfig = new LdapConnectionConfig();
tlsConfig.setLdapHost( Network.LOOPBACK_HOSTNAME );
tlsConfig.setLdapPort( getLdapServer().getPort() );
tlsConfig.setTrustManagers( new NoVerificationTrustManager() );
try ( LdapNetworkConnection connection =
new LdapNetworkConnection( tlsConfig ) )
{
// Connect
connection.connect();
// At this point, we are not oo a secured connection
connection.bind( "uid=admin,ou=system", "secret" );
// At this point, we are not oo a secured connection. Let's secure it
connection.startTls();
...
In this example, the **startTls** call uses the parameter that was loaded into the _tlsConfig_ instance.
## Here's what isn't supported
The [LDAP StartTLS RFC](https://tools.ietf.org/html/rfc2830) requires more than securing connections. Typically, it's possible to stop securing a connection, using a **Graceful Closure** operation. That feature isn't currently supported.