141
code fragment from Example 5-18 goes here. the new session is made
post_connection_checkssl, host; if everything is error-free, we have properly authenticated the
client
The code in Example 5-18
realizes the solution to the problem we laid out earlier for upgrading client authentication. By changing the session context ID to
admin_user
, we allow clients previously verified as admin users to resume connections, but no others. This is effective at
keeping resumed sessions from being mistaken as privileged sessions. In addition, we set the verify options for the SSL object explicitly, forcing the renegotiation to demand a client certificate
or fail. After renegotiation is complete, we call the post-connection check function. In some cases, we may want to tailor the post-connection function to meet application-specific needs.
5.2.3.2 Renegotiations in 0.9.7
Overall, renegotiation in Version 0.9.6 is inferior to the functions and simplicity that Version 0.9.7 promises. A new function has been added,
SSL_regenotiate_pending
. This function will return nonzero if a request is sent, but the handshake hasnt been finished. It will return zero once
the handshake is complete. Using this function, we can eliminate most of the ugliness associated with renegotiations in 0.9.6. Before looking at forced renegotiations, well briefly return to passive
renegotiations.
In most applications, renegotiations for changing the session key rather than upgrading client authentication are started by byte transfer thresholds. In other words, once our connection has
transferred a certain number of bytes, we will renegotiate. Because of this new function, we can simply call
SSL_renegotiate
when the byte limit is reached. Then we periodically check the value of
SSL_renegotiate_pending
to determine if the renegotiation completed. Doing this, we can programmatically fail if the handshake isnt completed in a certain amount of time after the
request. Furthermore, a new SSL option to aid us has been added in Version 0.9.7. By setting
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
with a call to
SSL_CTX_set_options
, we can automatically prevent clients from being able to resume sessions when we ask for renegotiations, regardless of the session ID context. When our goal is to
refresh session keys, this option is invaluable. Using these two new additions will also allow us to make a much cleaner forced renegotiation for
client authentication. We can call
SSL_renegotiate
to set the flag and make a single call to
SSL_do_handshake
to send the request out. Instead of setting internal state of the SSL object, we can now just call
SSL_do_handshake
until we either programmatically timeout or
SSL_renegotiate_pending
returns zero. If the latter condition is met, our renegotiation completed successfully. Ideally, we want to leave the session ID context changing and not set the
new SSL option when performing renegotiation for client authentication. This is better because it allows authenticated users to resume authenticated sessions rather than always perform the full
handshake.
5.2.3.3 Further notes
Weve limited our discussion of renegotiations to server-side implementation. In general, applications will be made this way since servers dictate session caching, and a server almost
always presents credentials. However, it is possible for a client to request or force renegotiation, though it is less common. Doing this is a logical extension of the methods used by a server. We
now have a better understanding of renegotiations, why they occur, and why theyre needed for certain operations. Forcing a renegotiation to force the client to provide a certificate to continue
the connection is also a popular paradigm for implementing SSL applications. As we discussed
142
early in this section, the alternatives to renegotiation for accomplishing this task are often too burdensome to be a general solution.
One major point thats been missing up to now is how to make an application react to renegotiation requests. The good news here is that its all handled by the OpenSSL library for us.
Recall the complications with IO. The reason we had to handle all the different varieties of retries is that a renegotiation request could be received at any time. When an SSL connection is requested
to renegotiate, the implementation automatically does so and completes the new handshake to generate a new session.
143
Chapter 6. Symmetric Cryptography
So far, weve discussed how to use the OpenSSL programmatic interface for securing arbitrary TCPIP connections using SSL. While SSL is a great general-purpose protocol, there are situations
in which it is not appropriate. For example, SSL cant be used to store encrypted data, such as on a disk or in a cookie, nor can it encrypt UDP traffic. In these cases, you should use the OpenSSL
API for symmetric cryptography.
As you have probably noticed, weve been careful to recommend using SSL instead of raw cryptographic primitives for securing your applications if at all appropriate. We do this because it
is incredibly easy to apply cryptographic primitives in a way that is insecure. Even professional cryptographic protocol designers have a hard time writing secure cryptographic protocols built
on these primitives, which is one reason peer-review is so important in the world of cryptography.
If youre planning to use this chapter to do real work, then we assume that you have some sort of need that SSL cannot fill, such as long-term data storage. We recognize that many people will
want to design their own network protocols despite our recommendations. If you are considering such an option, we strongly urge you to prefer well-respected protocols, and even pre-existing
implementations of those protocols, if possible. Nonetheless, this chapter is a reference for the basic API, and it is your responsibility to use that API in a secure manner.
6.1 Concepts in Symmetric Cryptography
Although we gave a brief overview of symmetric key cryptography in Chapter 1
, there are some additional things we should discuss as background material for the rest of this chapter. Certainly,
we dont wish to serve as a general-purpose textbook on cryptography. For such things, we recommend other books, such as Bruce Schneiers Applied Cryptography John Wiley Sons.
For that reason, well avoid any topic that a developer need not care about, such as the internal workings of ciphers. Anything related to the choices you need to make, however, is fair game.
6.1.1 Block Ciphers and Stream Ciphers
Only two types of symmetric ciphers exist that are well-respected and see any sort of widespread use: block ciphers and stream ciphers. Block ciphers are traditionally the most popular. They
operate by breaking up data into fixed-size blocks, and then encrypting each block individually, in which the encryption algorithm is a reversible function of the input. Leftover data is traditionally
padded so that the length of the plaintext is a multiple of the ciphers block size. Stream ciphers are essentially just cryptographic pseudorandom number generators. They use a starting seed as a
key to produce a stream of random bits known as the keystream. To encrypt data, one takes the plaintext and simply XORs it with the keystream. Stream ciphers dont need to be padded per se,
though they are usually padded to byte-boundaries, since implementations usually operate on a per-byte level instead of a per-bit level.
The best block ciphers are a far more conservative solution than stream ciphers because they are better studied. Yet stream ciphers tend to be far faster than block ciphers. For example, RC4,
currently the most popular stream cipher, runs about 4 times faster than Blowfish, which is among the fastest available block ciphers, and runs almost 15 times faster than 3DES, which is a very
conservative cipher choice. AES is faster than 3DES and has more security in terms of a longer key size, but it is still generally slower than even Blowfish.