HH V1:V2 L1:L2 dataTLS Handshakes:
- one byte which describes the message type
- three bytes for the message length (Big-Endian convention).
The successive handshake messages are then sent with records tagged with the "handshake" type (first byte of the header of each record has value 22).
Note the layers:
- the handshake messages
- complete with four-byte header
Furthermore, several handshake messages can be sent within the same record, and a given handshake message can be split over several records. From the point of view of the module which builds the handshake messages, the "records" are just a stream on which bytes can be sent; it is oblivious to the actual split of that stream into records.Cipher Suite "TLS_NULL_WITH_NULL_NULL (0x000) Encryption with no MAC and null compression. This means that the record they will first send will be sent as cleartext and unprotected.
The Full TLS Handshake looks like this:
Step One: ClientHello#First message of a handshake is a ClientHello. The message by which the client states its intention to do some SSL. Note that "client" is a symbolic role; it means "the party which speaks first". It so happens that in the HTTPS context, which is HTTP-within-SSL-within-TCP, all three layers have a notion of "client" and "server", and they all agree (the TCP client is also the SSL client and the HTTP client), but that's kind of a coincidence.
The ClientHello message contains:
- the maximum protocol version that the client wishes to support;
- the ClientHello.random (32 bytes, out of which 28 are suppose to be generated with a cryptographically strong number generator);
- the "session ID" (in case the client wants to resume a session in an abbreviated handshake, see below);
- the list of "Cipher Suites" that the client knows of, ordered by client preference;
- the list of compression algorithms that the client knows of, ordered by client preference;
- some optional extensions.
Step Two: ServerHello#The server responds to the ClientHello with a ServerHello which contains:
- the protocol version that the client and server will use;
- the ServerHello.random (32 bytes, with 28 random bytes);
- the session ID for this connection;
- the Cipher Suite that will be used; Note: The client and the server must support at least one common cipher suite, or else the handshake fails. The server generally chooses the strongest common cipher suite.
- the compression algorithm that will be used;
- optionally, some extensions.
Step Three ServerCertificate#The server sends a Certificate_list, which contains its Site Certificate. This message is almost always sent, except if the Cipher Suite mandates a handshake without a certificate.
If the server requires a digital certificate for client authentication, the server sends a digital certificate request message. In the "digital certificate request" message, the server sends a list of the types of digital certificates supported and the distinguished names of acceptable certificate authorities.
Step Four ServerKeyExchange#The server sends ServerKeyExchange message is sent after the server certificate message if it does not contain enough information for the client to exchange the Premaster Secret, or after the server hello if anonymous Key-Exchange is in use.
Step Five CertificateRequest#The server sends a message requesting that the client also identifies itself with a Certificate_list of its own. This message contains the list of names of Trust Anchors (aka Root Certificates) that the server will use to validate the client certificate.
Step Six ServerHelloDone#The server sends a marker message (of length zero) which says that the server is finished, and the client should now talk.
Step Seven Client Send Certificate#The Client sends the client Certificate is an OPTIONAL step only when server requested. (Mutual TLS)
Step Eight ClientKeyExchange#The ClientKeyExchange is sent by the Client immediately after the client certificate if it is sent, otherwise immediately after the server hello done message. It has two variants, one for when RSA key-exchange is used as the Key-Exchange algorithm, and one for when Diffie-Hellman key-exchange is used.
Step Nine CertificateVerify#The client sends a digital signature computed by the client over all previous handshake messages. This message is sent when the server requested a client certificate, and the client complied. This is how the client proves to the server that it really "owns" the public key which is encoded in the certificate it sent.
Step Ten Change_cipher_spec#Then the client sends a ChangeCipherSpec message, which is not a handshake message: it has its own record type, so it will be sent in a record of its own.
Its contents are purely symbolic (a single byte of value 1). This message marks the point at which the client switches to the newly negotiated cipher suite and keys. The subsequent records from the client will then be EncryptedTLS-Finished message is always sent immediately after a Change_cipher_spec message to verify that the key exchange and Certificate-based Authentication processes were successful. It is essential that a change cipher spec message be received between the other handshake messages and the TLS-Finished message.
The TLS-Finished message is the first protected with the just negotiated algorithms, keys, and secrets. Recipients of finished messages must verify that the contents are correct. Once a side has sent its Finished message and received and validated the Finished message from its peer, it may begin to send and receive application data over the connection.
The Finished message is a cryptographic checksum computed over all previous handshake messages (from both the client and server). Since it is emitted after the ChangeCipherSpec, it is also covered by the integrity check and the encryption. When the server receives that message and verifies its contents, it obtains a proof that it has indeed talked to the same client all along. This message protects the handshake from alterations (the attacker cannot modify the handshake messages and still get the Finished message right).
Step Eleven change_cipher_spec#The server finally responds with its own change_cipher_spec then Finished. At that point, the handshake is finished, and the client and server may exchange application_data (in encrypted records tagged as such).
To remember: the client suggests the Cipher Suite but the server chooses. The Cipher Suite decision is in the hands of the server. Courteous servers are supposed to follow the preferences of the client (if possible), but they can do otherwise and some actually do (e.g. as part of protection against BEAST).Certificate-based Authentication.
Handshake Again#Since a handshake is just some messages which are sent as records with the current encryption/compression conventions, nothing theoretically prevents a SSL-TLS client and server from doing a second handshake within an established session. And, indeed, it is supported and it happens in practice.
At any time, the client or the server can initiate a new handshake, the client just sends a ClientHello. Likewise the server can send a HelloRequest message. A typical situation is the following:
- An HTTPS server is configured to listen to SSL requests.
- A client connects and a handshake is performed.
- Once the handshake is done, the client sends its "applicative data", which consists of a HTTP request. At that point (and at that point only), the server learns the target path. Up to that point, the URL which the client wishes to reach was unknown to the server (the server might have been made aware of the target server name through a Server Name Indication SSL extension, but this does not include the path).
- Upon seeing the path, the server may learn that this is for a part of its data which is supposed to be accessed only by clients authenticated with certificates. But the server did not ask for a client certificate in the handshake (in particular because not-so-old Web browsers displayed freakish popups when asked for a certificate, in particular if they did not have one, so a server would refrain from asking a certificate if it did not have good reason to believe that the client has one and knows how to use it).
Therefore, the server triggers a new handshake, this time requesting a certificate.
There is an interesting weakness in the situation I just described; see RFC 5746 for a workaround. In a conceptual way, SSL-TLS transfers security characteristics only in the "forward" way. When doing a new handshake, whatever could be known about the client before the new handshake is still valid after (e.g. if the client had sent a good username+password within the tunnel) but not the other way round.
In the situation above, the first HTTP request which was received before the new handshake is not covered by the Certificate-based Authentication of the second handshake, and it would have been chosen by the attacker! Unfortunately, some Web servers just assumed that the client authentication from the second handshake extended to what was sent before that second handshake, and it allowed some nasty tricks from the attacker. RFC 5746 attempts at fixing that.
Watch Out#There are a few caveats about How SSL-TLS Works you should be aware of: SSL/TLS correctly, all an attacker can see on the cable is which IP and port you are connected to, roughly how much data you are sending, and what encryption and compression is used. He can also terminate the connection, but both sides will know that the connection has been interrupted by a third party.
In typical use, the attacker will also be able to figure out which host name you're connecting to (but not the rest of the URL): although HTTPS itself does not expose the host name, your browser will usually need to make a DNS request first to find out what IP address to send the request to.
Some more details#
Why can you trust Google.com by trusting GeoTrust?#A website wants to communicate with you securely. In order to prove its identity and make sure that it is not an attacker, you must have the server's public key. However, you can hardly store all keys from all websites on earth, the database would be huge and updates would have to run every hour!
The solution to this are Certificate Authorities, or CA for short. When you installed your operating system or browser, a list of trusted CAs probably came with it. This list can be modified at will; you can remove whom you don't trust, add others, or even make your own CA (though you will be the only one trusting this CA, so it's not much use for public website). In this CA list, the CA's public key is also stored.
When Google's server sends you its certificate, it also mentions it is signed by GeoTrust. If you trust GeoTrust, you can verify (using GeoTrust's public key) that GeoTrust really did sign the server's certificate. To sign a certificate yourself, you need the private key, which is only known to GeoTrust. This way an attacker cannot sign a certificate himself and incorrectly claim to be Google.com. When the certificate has been modified by even one bit, the sign will be incorrect and the client will reject it.
So if I know the public key, the server can prove its identity?#Yes. Typically, the public key encrypts and the private key decrypts. Encrypt a message with the server's public key, send it, and if the server can tell you what it originally said, it just proved that it got the private key without revealing the key.
This is why it is so important to be able to trust the public key: anyone can generate a private/public key pair, also an attacker. You don't want to end up using the public key of an attacker!
If one of the CAs that you trust is compromised, an attacker can use the stolen private key to sign a certificate for any website they like. When the attacker can send a forged certificate to your client, signed by himself with the private key from a CA that you trust, your client doesn't know that the public key is a forged one, signed with a stolen private key.
But a CA can make me trust any server they want! Yes, and that is where the trust comes in. You have to trust the CA not to make certificates as they please. When organisations like Microsoft, Apple and Mozilla trust a CA though, the CA must have audits; another organisation checks on them periodically to make sure everything is still running according to the rules.
Issuing a certificate is done if, and only if, the registrant can prove they own the domain that the certificate is issued for.
What is this MAC for Message Authentication Code?#Every message is signed with a so-called Message Authentication Code, or MAC for short. If we agree on a key and hashing Cipher, you can verify that my message comes from me, and I can verify that your message comes from you.
For example with the key "correct horse battery staple" and the message "example", I can compute the MAC "58393". When I send this message with the MAC to you (you already know the key), you can perform the same computation and match up the computed MAC with the MAC that I sent.
An attacker can modify the message, but does not know the key. He cannot compute the correct MAC, and you will know the message is not authentic.
By including a sequence number when computing the MAC, you can eliminate replay attacks. SSL does this.