126
5.2.1 SSL Session Caching
An SSL session is different from an SSL connection. A session refers to the set of parameters and encryption keys created by performing a handshake, whereas a connection is an active
conversation that uses a session. In other words, the connection refers to the process of communication, and the session refers to the parameters by which that communication was set up.
Understanding this, we can delve into some of the OpenSSL routines that provide for SSL session caching.
Since the majority of the computational expense associated with an SSL server is in setting up connections with clients and not in maintaining them, session caching can be a lifesaver when it
comes to server load reduction. OpenSSL implements sessions as
SSL_SESSION
objects. While the majority of the work in implementing session caching falls on the server side, the client must
also keep its previous sessions in order for the efficiency benefit to be realized. From the servers perspective, once it has established a connection, it merely needs to label the
data and cache the session. This label, called the session ID context, is described in Section 5.2.1.2
. After establishing a session, the server assigns a timeout value to it, which is simply a time after
which the session will be discarded and another will need to be negotiated. The default behavior of a session caching server is to flush expired sessions automatically. From the client side, an
SSL_SESSION
object is received from the server. The client can then save this session and reuse it if it needs to make another connection. For instance, a web browser may need to make several
connections to display all of the information presented from an SSL-enabled web server. By keeping this session information around, the client connects quickly, and the load on the server is
reduced, since it need not negotiate a new session for each connection.
As weve said, the server determines the valid session ID context. When a client attempts to connect to a caching server, it has only one attempt at presenting the correct value. If incorrect, a
normal handshake occurs, and a new session is created. If the client saves this newly created session, it will then have the correct session ID context for future connections.
The details associated with sessions, such as enabling a client and server, dealing with timeouts, and flushing old sessions, are discussed in the following sections. In addition, we will also outline
a mechanism for server-side, on-disk storage of sessions.
5.2.1.1 Client-side SSL sessions
When a connection is established, the function
SSL_get_session
returns the
SSL_SESSION
object representing the parameters used on the SSL connection. This function returns
NULL
if there is no session established on the SSL connection; otherwise, it returns the object. Actually,
this function is called as either
SSL_get0_session
or
SSL_get1_session
. These two variants are used to ensure that the reference counting on the
SSL_SESSION
object is updated correctly. The former does not change the reference count, and the latter increments it. In general,
we want to use the latter function since
SSL_SESSION
objects can timeout asynchronously. If this occurs, our object disappears and we are holding an invalid reference to it. Using
SSL_get1_session
requires that we call
SSL_SESSION_free
on the object when were done using it, in order to prevent memory leaks.
After saving a reference to the
SSL_SESSION
object, we can close down the SSL connection and its underlying transport normally a socket. For most clients, there will not be a large number of
SSL sessions established at one time, so caching them in memory is adequate. If this isnt the case, we can always write the sessions out to disk using
PEM_write_bio_SSL_SESSION
or
PEM_write_SSL_SESSION
, and reread them later using
PEM_read_bio_SSL_SESSION
or
PEM_read_SSL_SESSION
. The syntax of these functions is the same as the functions used for reading and writing public-key objects. They are discussed in
Chapter 8 in
Section 8.6.2 .
127
To reuse a saved session, we need to call
SSL_set_session
before calling
SSL_connect
. The reference count of the
SSL_SESSION
object will be incremented automatically so we should follow the call with
SSL_SESSION_free
. After reusing a session, it is a good idea to call
SSL_get1_session
before disconnecting to replace the
SSL_SESSION
object that weve cached. The reason is that renegotiations may occur during the connection. Renegotiations cause
the creation of a new
SSL_SESSION
, so we should keep only the most recent renegotiation is discussed in more detail later.
Now that we understand the basics of enabling session caching, well take a brief look at incorporating it into a client application.
Example 5-13 shows pseudocode for our client-side
session caching. Now that weve established an implementation for a client, well elaborate upon some of the details of session caching as we explore the implementation necessary for server-side
caching.
Example 5-13. Pseudocode for client-side caching
ssl = SSL_newctx ... setup underlying communications layer for ssl ...
... connect to host:port ... if saved session for host:port in cache
SSL_set_sessionssl, saved session SSL_SESSION_freesaved session
SSL_connectssl call post_connection_checkssl, host and check return value
... normal application code here ... saved session = SSL_get1_sessionssl
if saved session = NULL enter saved session into cache under host:port
SSL_shutdownssl SSL_freessl
5.2.1.2 Server-side SSL sessions