91
} return prime;
}
4.6 Using Engines
OpenSSL has built-in support for cryptographic acceleration. Using the
ENGINE
object type, an application can get a reference to a changeable, underlying representation, most often a hardware
device. This support was built in the 0.9.6 versions of OpenSSL that included the name engine; it will be incorporated into the main branch of OpenSSL beginning with Version 0.9.7. While 0.9.7
will have a much more robust feature specification for the ENGINE package, 0.9.6-engine contains some simple functions to set up an
ENGINE
object. These functions do not appear to have changed at the time of writing. If they do, well update our web site with the relevant information.
The general idea is simple: we retrieve an object representing the type of hardware we wish to utilize, then we tell OpenSSL to use the device we chose.
Example 4-17 shows a small code
example of how we would perform this operation.
Example 4-17. Enabling use of a hardware engine
ENGINE e; if e = ENGINE_by_idcswift
fprintfstderr, Error finding specified ENGINE\n; else if ENGINE_set_defaulte, ENGINE_METHOD_ALL
fprintfstderr, Error using ENGINE\n; else
fprintfstderr, Engine successfully enabled\n;
The function call
ENGINE_by_id
will look up an implementation from the built-in methods available and return an
ENGINE
object. The single argument to this function should be the string identifier of the underlying implementation we wish to use.
Table 4-2 shows the available
methods for supported cryptographic hardware and software.
Table 4-2. Supported hardware and software engines ID string
Description
openssl The engine uses the normal built-in functions for cryptographic operations.
This is the default. openbsd_dev_crypto
On the OpenBSD operating system, this engine will use the kernel level cryptography built into the operating system.
cswift Used for CryptoSwift acceleration hardware.
chil Used for nCipher CHIL acceleration hardware.
atalla Used for Compaq Atalla acceleration hardware.
nuron Used for Nuron acceleration hardware.
ubsec Used for Broadcom uBSec acceleration hardware.
aep Used for Aep acceleration hardware.
sureware Used for SureWare acceleration hardware.
The
ENGINE
object that we receive from the lookup should be used in the call to
ENGINE_set_default
to allow cryptographic functions to utilize the capabilities of the specific
92
ENGINE
. The second parameter allows us to specify constraints on what we allow the engine to implement. For example, if we had an engine that implemented only RSA, making a call like the
one in Example 4-17
would allow RSA to be handled by the engine. On the other hand, if we called
ENGINE_set_default
with our RSA engine and
ENGINE_METHOD_DSA
, OpenSSL would not use the engine for any cryptographic calls, since this flag allows the engine to work
only on DSA functions. Table 4-3
provides a complete list of the restraints we can use. They can be combined with the logical OR operation.
Table 4-3. Flags for ENGINE_set_default Flag Description
ENGINE_METHOD_RSA Limit engine usage to only RSA operations.
ENGINE_METHOD_DSA Limit engine usage to only DSA operations.
ENGINE_METHOD_DH Limit engine usage to only DH operations.
ENGINE_METHOD_RAND Limit engine usage to only random number operation.
ENGINE_METHOD_CIPHERS Limit engine usage to only symmetric ciphers operations.
ENGINE_METHOD_DIGESTS Limit engine usage to only digest operations.
ENGINE_METHOD_ALL Allow OpenSSL to use any of the above implementations.
Aside from setting the default engine,
ENGINE
objects are typically used in several other places in OpenSSL Version 0.9.7. For instance, the function
EVP_EncryptInit
has been deprecated and replaced by
EVP_EncryptInit_ex
. This ex function takes one additional parameter: the
ENGINE
object. In general, these replacement functions can be passed a
NULL
argument for the
ENGINE
, which will cause OpenSSL to use the default engine. Recall that the default engine is changed when a call to
ENGINE_set_default
is made; if no such call is made, the built-in software implementation is used.
The purpose of these new ex functions is to allow a more fine-grained control over which underlying cryptographic device is used for each call. This is particularly useful for circumstances
in which we have multiple cryptographic accelerators, and we wish to utilize them differently depending on application code.
93
Chapter 5. SSLTLS Programming
The main feature of the OpenSSL library is its implementations of the Secure Sockets Layer SSL and Transport Layer Security TLS protocols. Originally developed by Netscape for secure web
transactions, the protocol has grown into a general solution for secure stream-based communications. Netscapes first public version of SSL is what we now call SSL Version 2. From
that point, security experts began working to improve upon some of the flaws in SSLv2, and that gave birth to SSL Version 3. Development of a standard for transport layer security based on SSL
was being done concurrently, which resulted in TLS Version 1. Because of the security flaws with SSLv2, modern applications should not support it. In this chapter, well discuss only programming
with the SSLv3 and TLSv1 protocols in OpenSSL. Unless otherwise noted, when we refer to SSL, we refer to both SSLv3 and TLSv1.
From a design perspective, we need to know more than just that we want to use SSL in our application. The correct implementation of an SSL-enabled program can be difficult due to
complexities in protocol setup, the large size of the API, and developer inexperience with the library. OpenSSLs SSL support was originally designed to mimic the Unix socket interface;
however, the likenesses quickly fade as we get into the subtleties of the API. In order to make the process of becoming acquainted with the massive library easier, we take a small example client
and server through a step-by-step process of making it SSL-enabled and secure. To aid understanding, we start with some simplifying assumptions that may not be practical for real-
world applications.
From that point, well bridge the gap to the more advanced OpenSSL features. The goal of this chapter is to compartmentalize the features of the library into smaller groups to establish a sense
of process. We hope that this process will serve as a template for developers when it comes to implementing SSL in their own applications. In adding SSL to an application, the applications
unique requirements must be considered, and the best decision must be made for both security and functionality.
5.1 Programming with SSL
OpenSSLs API for SSL is large and can be daunting to inexperienced programmers. Additionally, as discussed in
Chapter 1 , SSL can be ineffective at accomplishing its security goals if
implemented incorrectly. These factors compound to leave the developer with a difficult task. In hopes of disentangling the mystery of implementing secure programs, we attack the problem in
three steps. At each step, the developer must provide some application-specific knowledge to make sure SSL does its job. For example, the choices made by a developer of a highly compatible
web browser will be different from those made by a developer of a highly secure server application.
The steps below provide a template for developers to follow when implementing an SSL client or server. We will start with a small example and build upon it. This example will not be secure to
our satisfaction until all of the steps have been thought through. In each step, we will introduce a small dose of the API; after all the steps, the developer should be able to think through the design
of an SSL-enabled application much more clearly. Completing these steps is not the end of the road, however. In order to address the requirements of many applications, we need to go further
and look into the advanced features of the API.
5.1.1 The Applications to Secure