Beyond the example Step 3: SSL Options and Cipher Suites

124 28 { 29 DH ret; 30 31 if dh512 || dh1024 32 init_dhparams; 33 34 switch keylength 35 { 36 case 512: 37 ret = dh512; 38 break; 39 case 1024: 40 default: generating DH params is too costly to do on the fly 41 ret = dh1024; 42 break; 43 } 44 return ret; 45 } 46 47 define CIPHER_LIST ALL:ADH:LOW:EXP:MD5:STRENGTH 48 define CAFILE rootcert.pem 49 define CADIR NULL 50 define CERTFILE server.pem 51 SSL_CTX setup_server_ctxvoid 52 { 53 SSL_CTX ctx; 54 55 ctx = SSL_CTX_newSSLv23_method; 56 if SSL_CTX_load_verify_locationsctx, CAFILE, CADIR = 1 57 int_errorError loading CA file andor directory; 58 if SSL_CTX_set_default_verify_pathsctx = 1 59 int_errorError loading default CA file andor directory; 60 if SSL_CTX_use_certificate_chain_filectx, CERTFILE = 1 61 int_errorError loading certificate from file; 62 if SSL_CTX_use_PrivateKey_filectx, CERTFILE, SSL_FILETYPE_PEM = 1 63 int_errorError loading private key from file; 64 SSL_CTX_set_verifyctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 65 verify_callback; 66 SSL_CTX_set_verify_depthctx, 4; 67 SSL_CTX_set_optionsctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | 68 SSL_OP_SINGLE_DH_USE; 69 SSL_CTX_set_tmp_dh_callbackctx, tmp_dh_callback; 70 if SSL_CTX_set_cipher_listctx, CIPHER_LIST = 1 71 int_errorError setting cipher list no valid ciphers; 72 return ctx; 73 } The most obvious change to this file is the addition of the functions init_dhparams and tmp_dh_callback . The initializing function reads the DH parameters from the files dh512.pem and dh1024.pem and loads them into the global parameters. The callback function simply switches on the required key size and returns either a 512-bit DH parameter set or a 1,024-bit set. This function intentionally does not try to perform any on-the-fly generation of parameters because it is simply too computationally expensive to be worthwhile. The only other changes to the server not done to the client, aside from the call on line 60 to set the callback, is the inclusion of the SSL option SSL_OP_SINGLE_DH_USE . As discussed earlier, this causes the private part of the DH key exchange to be recomputed for each client connecting.

5.1.4.5 Beyond the example

125 For purposes of clarity in the example code, we have avoided several serious considerations for real applications. The most obvious is error handling. Our examples simply exit if errors of any kind occur. For most applications, extension of the example to more robustly handle errors is application-specific. While specific functions may return different error codes, OpenSSL functions and macros will generally return 1 on success; thus, implementing better error handling should be straightforward. In addition, the examples weve built do two-way authentication. When making a new client and server application, this should always be done. However, when making applications that are meant to connect with other SSL peers, such as a web server, we should take into account that the stringent security requirements of our example are not always desirable. For instance, to entirely remove client authentication from a server, we simply need to remove the calls that load the verify locations, the call to set the verify mode, and the call to the post-connection verification routine. This isnt the best approach, though. When making such compatibility-first applications, we need to try to incorporate as much security as possible. For instance, instead of removing all of the verification calls, we could still load the verification locations and request a peer certificate with the SSL option SSL_VERIFY_PEER . We can, however, omit the SSL_VERIFY_FAIL_IF_NO_PEER_CERT option and modify the post-connection verification so that if the client does present a certificate, we go on with high security. If the client does not present the server with a certificate, the condition and associated information can be logged so that we can keep track of unauthenticated connections. Another point we avoided was the password callback for the encrypted private key for the certificate. For most server applications, common practice is to leave the private key in a file that isnt encrypted so that the application can start up and stop without user input. This convention, born of simplicity of implementation, can easily be subverted. When doing something like this, it is essential that we make sure users on the machine do not have read permission on the private key file; ideally, the file will also be owned by the root or administrator user so that the likelihood of compromise is further reduced. For most client applications, tying the encryption passphrase to the user should not be a problem. DSA parameters can be converted to DH parameters. This method is often utilized since the computational power necessary to generate the DSA parameters is smaller. Often, parameters generated in this fashion are used for ephemeral DH parameters. Without having to get into the mathematics behind the algorithms, the SSL option SSL_OP_SINGLE_DH_USE should always be used in these cases. Without it, applications are susceptible to a subtle attack. A large flaw of our example programs is their handling of IO on SSL connections. The examples rely on blocking IO operations. For most real applications, this is unacceptable. In the following section, we broach the important topic of non-blocking IO on SSL connections. We have also neglected to consider renegotiations requesting that a handshake be performed during an already established connection on SSL connections and their impact on IO. While this should occur automatically when the peer requests it, the IO routines must be robust enough to handle its subtle impacts. In the next section, we begin by addressing server efficiency with respect to session caching and then move into a more in-depth look at IO paradigms.

5.2 Advanced Programming with SSL

OpenSSL provides many more routines than those weve discussed up to this point. In fact, most of the SSL_CTX routines have SSL counterparts that perform the same function except on an SSL object instead of the context that creates it. Aside from this small point, we will discuss techniques for caching SSL sessions, using renegotiations, and properly reading and writing on SSL connections—including during renegotiation.