The final product Step 3: SSL Options and Cipher Suites

122 A cipher suite is a set of algorithms that SSL uses to secure a connection. In order to make a suite, we need to provide algorithms for four functions: signingauthentication, key exchange, cryptographic hashing, and encryptingdecrypting. Keep in mind that some algorithms can serve multiple purposes. For example, RSA can be used for signing and for key exchange. OpenSSL implements a variety of algorithms and cipher suites when it comes to SSL connections. When designing secure applications, it is essential that algorithms having known security vulnerabilities not be allowed. The SSL_CTX_set_cipher_list function allows us to set the list of cipher suites that we authorize our SSL objects to use. The list of ciphers is specified by a specially formatted string. This string is a colon-delimited list of algorithms. Given the number of possible combinations, specifying all the acceptable ones explicitly would be quite cumbersome. OpenSSL allows for several keywords in the list, which are shortcuts for sets of ciphers. For instance, ALL is a shortcut for every available combination. Additionally, we can precede a keyword with the operator to remove all ciphers associated with the keyword from the list. Using this, we will create a string to define our custom cipher list. There are other operators such as + or -, but they are not essential for specifying a secure list. For applications that need a custom definition, the ciphers manpage is a good reference on string formation. SSL allows the use of anonymous ciphers. Anonymous ciphers allow the SSL connection to succeed without proper authentication of the peer by using the DH algorithm. In almost all circumstances, we want to block these ciphers; they are identified by the ADH keyword. In addition to suites that do not allow us to authenticate properly, we want to block low-security algorithms. The LOW keyword refers to ciphers that use a key of 64 bits or 56 bits without export crippling. Accordingly, the EXP keyword marks the ciphers that are export-crippled to 56 or 40 bits. Finally, we should block algorithms that have known weaknesses, e.g., MD5. We can also use the special keyword STRENGTH. Using this indicates that the list of cipher suites should be sorted by their strength their key size in order of highest to lowest. Employing this keyword causes our SSL connections to attempt to select the most secure suite possible, and if necessary, back off to the next most secure, and so on down the list. This keyword should be specified last on the list.

5.1.4.4 The final product

Using our knowledge of SSL options, ephemeral keying, and cipher suite selection, we will implement the last step necessary to make our examples fully SSL-enabled, secure applications. After looking at the code for the client and server, we will discuss some of the simplifications that our applications employ. Example 5-11 contains the code for client3.c, the final client application. Because the only changes were making are to the setup_client_ctx function, we truncated the example to only the contents of the source file up to and including that function. Example 5-11. client3.c 1 include common.h 2 3 define CIPHER_LIST ALL:ADH:LOW:EXP:MD5:STRENGTH 4 define CAFILE rootcert.pem 5 define CADIR NULL 6 define CERTFILE client.pem 7 SSL_CTX setup_client_ctxvoid 8 { 9 SSL_CTX ctx; 123 10 11 ctx = SSL_CTX_newSSLv23_method; 12 if SSL_CTX_load_verify_locationsctx, CAFILE, CADIR = 1 13 int_errorError loading CA file andor directory; 14 if SSL_CTX_set_default_verify_pathsctx = 1 15 int_errorError loading default CA file andor directory; 16 if SSL_CTX_use_certificate_chain_filectx, CERTFILE = 1 17 int_errorError loading certificate from file; 18 if SSL_CTX_use_PrivateKey_filectx, CERTFILE, SSL_FILETYPE_PEM = 1 19 int_errorError loading private key from file; 20 SSL_CTX_set_verifyctx, SSL_VERIFY_PEER, verify_callback; 21 SSL_CTX_set_verify_depthctx, 4; 22 SSL_CTX_set_optionsctx, SSL_OP_ALL|SSL_OP_NO_SSLv2; 23 if SSL_CTX_set_cipher_listctx, CIPHER_LIST = 1 24 int_errorError setting cipher list no valid ciphers; 25 return ctx; 26 } Line 3 contains a definition of the cipher list we discussed in the previous section. Translated to plain terms, the list is composed of all cipher suites in order of strength except those containing anonymous DH ciphers, low bit-size ciphers, export-crippled ciphers, or the MD5 hash algorithm. As discussed at the beginning of this step, we enable all bug workarounds and disable SSL Version 2 with the call on line 22. Finally, lines 23-24 actually load our cipher list into the SSL_CTX object. The server application appears in Example 5-12 . Weve made significantly more changes than in the client, but most of our changes are the addition of new functions that are used only by the SSL context setup function. Weve similarly truncated the source listing for the server example. Example 5-12. server3.c 1 include common.h 2 3 DH dh512 = NULL; 4 DH dh1024 = NULL; 5 6 void init_dhparamsvoid 7 { 8 BIO bio; 9 10 bio = BIO_new_filedh512.pem, r; 11 if bio 12 int_errorError opening file dh512.pem; 13 dh512 = PEM_read_bio_DHparamsbio, NULL, NULL, NULL; 14 if dh512 15 int_errorError reading DH parameters from dh512.pem; 16 BIO_freebio; 17 18 bio = BIO_new_filedh1024.pem, r; 19 if bio 20 int_errorError opening file dh1024.pem; 21 dh1024 = PEM_read_bio_DHparamsbio, NULL, NULL, NULL; 22 if dh1024 23 int_errorError reading DH parameters from dh1024.pem; 24 BIO_freebio; 25 } 26 27 DH tmp_dh_callbackSSL ssl, int is_export, int keylength 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