There are several steps in the TLS negotiation process, which is also called the handshake.
The process varies somewhat based on the TLS version that is ultimately chosen. The basic components of a TLS 1.2 handshake are as follows:
- The client sends a client hello message, which tells the server the highest version of the TLS protocol that the client supports and what cipher suites it’s willing to use. It also includes a set of extensions with additional information, like the address the client is using to communicate with the server, which signature algorithms and elliptic curves the client supports, and whether it supports secure renegotiation.
- The server returns a server hello message, which tells the client which TLS protocol version it uses and the cipher suite that it has selected. The server can also provide its own extensions to the client.
- The server sends a certificate message, in which it provides its certificate chain to the client.
- The server can optionally send a server key exchange message with additional information that the client might need to help it securely derive the same symmetric encryption key that the server comes up with.
- The server can optionally send a certificate request message, asking the client to present its own certificate chain to the server.
- The server sends a server hello done message to tell the client that it has completed its hello sequence.
- The client can optionally send a certificate message to the server with its own
certificate chain. It should only do this if the server sent a certificate request.
Even if the client got such a request, it can decide not to send a certificate chain and in most cases, it won’t. It is up to the server to decide whether it will require a client certificate chain, or whether it is merely optional.
In LDAP, it’s very common for the server to ask the client to present a certificate, but to continue with TLS negotiation even if the client doesn’t present one. This makes it possible to support authentication methods like SASL EXTERNAL in which the client can use the certificate chain it presented during TLS negotiation as proof of its identity at the LDAP layer.
- The client derives a symmetric key to use for the remainder of the encrypted processing, and then sends a client key exchange message to the server that includes the information that the server needs to come up with the same key. This is done in such a way that only the client and the server know what that key is, even if someone else can observe all the communication that passes between the client and the server.
- If the client presented a certificate chain to the server, then it also sends a certificate verify message to prove that it has the private key for the certificate at the head of the chain.
- The client sends a change cipher spec message to the server, which tells the server that it is going to start encrypting everything else that it sends to the server with the symmetric key that they have agreed upon.
- The client sends a finished message to the server, indicating that it has completed its portion of the handshake.
- The server sends a change cipher spec message to the client, which tells the client that it is going to start encrypting everything else that it sends to the client with the agreed-upon symmetric key.
- The server sends a finished message to the client, indicating that it has completed its portion of the handshake.
TLS 1.3 uses a dramatically different handshake sequence that might only require a single round trip to exchange all the necessary information between the client and the server as opposed to the two round trips that TLS 1.2 uses. It does this by trying to guess the type of key agreement that the server wants to use and sending the necessary information to the server up front instead of waiting to hear from the server.
The elimination of an extra round of communication between the client and the server does mean that the server now finishes its portion of the negotiation before the client, whereas it was previously the other way around.
This means that the server has to assume that the client trusts its certificate chain, while it would have previously known that before completing negotiation. This can make certain types of troubleshooting a little more complicated, because the server can log a successful negotiation, only to later find (though a TLS alert) that the client rejected the certificate.