Certificate preparation Step 1: SSL Version Selection and Certificate Preparation

99 In general, an application will create just one SSL_CTX object for all of the connections it makes. From this SSL_CTX object, an SSL type object can be created with the SSL_new function. This function causes the newly created SSL object to inherit all of the parameters set forth in the context. Even though most of the settings are copied to the SSL object on invocation of SSL_new , the order in which calls are made to OpenSSL functions can cause unexpected behavior if were not careful. Applications should set up an SSL_CTX completely, with all connection invariant settings, before creating SSL objects from it. In other words, after calling SSL_new with a particular context object, no more calls operating on that SSL_CTX object should be made until all produced SSL objects are no longer in use. The reason is simple. Modifying a context can sometimes affect the SSL connections that have already been created i.e.., a function we examine later, SSL_CTX_set_default_passwd_cb , changes the callback in the context and in all connections that were already created from this context. To avoid any unpredictability, never modify the context after connection creation has begun. If there are any connection-specific parameters that we do need to set, most SSL_CTX functions have SSL counterparts that act on SSL -type objects.

5.1.2.2 Certificate preparation

The SSL protocol usually requires the server to present a certificate. The certificate contains credentials that the client may look at to determine if the server is authentic and can be trusted. As we know, a peer validates a certificate through verification of its chain of signers. Thus, to implement an SSL server correctly, we must provide certificate and chain information to the peer. The SSL protocol also allows the client to optionally present certificate information so that the server may authenticate it. There are, in fact, ways of using SSL to create anonymous connections in which neither the server nor client presents a certificate. These are done by using the Diffie-Hellman key-agreement protocol and setting the SSL cipher suite to include the anonymous DH algorithm. This is discussed further Section 5.1.4.3 below. In general, server applications should always provide certificates to peers, and clients can do so optionally. The purpose and the desired security of the application should dictate whether client certificates are used. For instance, a server may request a client certificate, and if our client does not have one to present, we may not be able to establish a secure connection. Thus, its a good idea to implement client certificates if it makes sense to do so. On the other hand, server certificates are usually required, and, unless our goal is to create a completely nonauthenticated connection, we should implement them. OpenSSL presents the client certificate to the server during handshakes, as long as we assign a certificate to the client and the server asks for it. This is actually a small violation of the TLS protocol. The protocol calls for the server to present a list of valid CAs, and the client should send a certificate only if it matches. In practice, this infraction of the standard should not affect anything, but the behavior may be fixed in future versions of OpenSSL. The SSL API has several ways to incorporate certificate information into an SSL_CTX object. The function to use is SSL_CTX_use_certificate_chain_file . It loads the chain of certificates from the filename specified by the second argument. The file should contain the TE AM FL Y Team-Fly ® 100 certificate chain in order, starting with the certificate for the application and ending with the root CA certificate. Each of these entries must be in PEM format. In addition to loading the certificate chain, the SSL_CTX object must have the applications private key. This key must correspond to the public key embedded within the certificate. The easiest way that we can supply this key to the context is through the SSL_CTX_use_PrivateKey_file function. The second argument specifies the filename, and the third specifies the type of encoding. The type is specified by using a defined name—either SSL_FILETYPE_PEM or SSL_FILETYPE_ASN1 . It bears mentioning that this private key must be kept secret for the application to remain secure. Therefore, using an encrypted PEM format for on-disk storage is recommended; using triple DES in CBC mode is a good choice. The SSL_CTX will fail to incorporate an encrypted private key correctly unless the correct passphrase is supplied. OpenSSL collects passphrases through a callback function. The default callback prompts the user on the terminal. For some applications, the default will not be acceptable. The function SSL_CTX_set_default_passwd_cb allows us to set the callback to something more appropriate for the application. The assigned function is invoked during the call to SSL_CTX_use_PrivateKey_file if the indicated file contains an encrypted key. Therefore, the callback should be set before making that call. In fact, the certificates in our chain could be encrypted even though there is nothing secret about them, and our callback function would be invoked to gather the passphrase. More accurately, we could state that the passphrase function is called any time a piece of encrypted information is loaded as a parameter to the SSL_CTX . The callback functions obligation is to copy the passphrase into the buffer that is supplied to it when it is called. The callback function is called with four arguments. int passwd_cbchar buf, int size, int flag, void userdata; buf The buffer that the passphrase should be copied into. The buffer must be NULL terminated. size The size of the buffer in bytes; includes space for the NULL terminating character. flag Passed as either zero or nonzero. When the flag is nonzero, this passphrase will be used to perform encryption; otherwise, it will be used to perform decryption. userdata Application-specific data; SSL_CTX_set_default_passwd_cb_userdata is used to set this data. Whatever data is set by the application is passed to the callback function untouched by OpenSSL. There are two approaches to implementing the passphrase callback. The first method is simply to have the callback prompt the user, copy the collected passphrase to the buffer, and return. This method is viable for applications that need to decrypt a key only once, commonly on application startup. The second way to implement the callback is for the application to prompt the user for a passphrase on startup and store the collected information in a buffer. The passphrase can be added to the SSL_CTX as user data via the function SSL_CTX_set_default_passwd_cb_userdata . With this method, the callback itself only 101 needs to copy the data from the fourth parameter to the first. This method is viable for applications that need to decrypt keys during normal operation in which constant user prompting is a nuisance. An unlimited number of PEM-encoded items can be stored in a file, but only one DER item may be stored in a file. Also, different types of PEM items may be stored within a single file. As a result, if the private key is kept in PEM encoding, it can be appended to the certificate chain file, and the same filename can be used for the calls to SSL_CTX_use_certificate_chain_file and SSL_CTX_use_PrivateKey_file . This trick is used in Example 5-5 . PEM and DER encodings are discussed in Chapter 8 . At this stage, we will limit our discussion to the process of providing certificate information to the peer, rather than discussing the processes of validation. The validation problem will be discussed in Step 2.

5.1.2.3 Our example extended