227
from M2Crypto import SSL
The SSL module contains several classes that provide the most basic interface to the OpenSSL C library. Included among them are
Context
,
Connection
,
Session
,
SSLServer
,
ForkingSSLServer
, and
ThreadingSSLServer
. The first,
Context
, is a wrapper around the C interfaces
SSL_CTX
object. All of OpenSSLs connection-oriented services require a context on which to operate.
When a context is created, the version of the protocol that it will support must be supplied. You cannot change a contexts protocol once it has been created. The
Context
classs constructor takes an optional parameter that specifies the protocol to use. The protocol can be
sslv2
,
sslv3
,
tlsv1
, or
sslv23
. If you do not specify a protocol, the default is
sslv23
, which indicates that SSLv2, SSLv3, or TLSv1 should be negotiated during the initial handshake. As we mentioned in
Chapter 1 , you should avoid supporting v2 in your applications.
Once a context object has been created, it can be used to establish an SSL connection. The class contains many methods that allow you to set and query the various attributes a context may have
that are supported by OpenSSL itself. Operations include assigning a certificate and private key, loading CA certificates, and specifying criteria to determine whether a peers certificate is
acceptable or not.
The
Connection
class combines OpenSSL with sockets to provide an all-in-one object for establishing both client and server connections, as well as transferring data bi-directionally over
the connection. This class is little more than a convenience object, since it does all of the tedious work of setting up a socket and establishing an SSL connection for you. All that you need to do is
create a
Context
and set it up to meet your needs. For example, to establish a connection using TLSv1 for the protocol, your code might look a little something like this:
from M2Crypto import SSL ctx = SSL.Contexttlsv1
conn = SSL.Connectionctx conn.connect127.0.0.1, 443
The
Session
class is not one that you would typically create yourself. There are two ways to get a
Session
object. The first is from an existing
Connection
object by calling its
get_session
method. The second is by loading a saved session from a file via
SSL.load_session
. Once you have a
Session
object, you can dump it to a file using its
write_bio
method. The last three classes,
SSLServer
,
ForkingSSLServer
, and
ThreadingSSLServer
, are SSL versions of the Python
TCPServer
class found in the SocketServer module. They all work in the same manner, except the constructor for each class requires an additional argument that is a
Context
object. You are of course required to create the
Context
object and set it up to meet your needs.
9.2.2.2 M2Crypto.BIO
from M2Crypto import BIO
The BIO module provides interface classes to OpenSSLs BIO functions. The
BIO
class itself is an abstract class that provides the basic functionality of the other four classes that are built on top of
it:
MemoryBuffer
,
File
,
IOBuffer
, and
CipherStream
. The
BIO
class itself is not intended to be instantiated. If you do, itll be mostly useless, capable of doing little more than throwing
exceptions when you try to use it.
228
There isnt much to be said for these four classes that we didnt already cover in Chapter 4
. BIO is simply an IO abstraction, and these four classes provide four different types of IO. The
MemoryBuffer
class provides a wrapper around the OpenSSL
BIO_s_mem
type, which is an in- memory IO stream. The
File
class provides a wrapper around the OpenSSL
BIO_s_fp
type, which is a disk file. The
IOBuffer
class provides a wrapper around the OpenSSL
BIO_f_buffer
type, and it is typically used only internally by a
Connection
objects
makefile
method. It essentially provides a wrapper around any other type of BIO. Finally, the
CipherStream
class provides a wrapper around the OpenSSL
BIO_f_cipher
type, which is perhaps the most interesting of all four BIO wrappers that are supported by M2Crypto. It
wraps around any other type of BIO of your choosing, encrypting data as it is written, and decrypting data as it is read. Some additional setup work is required to use this class, but all that is
actually involved is setting the cipher to be used.
9.2.2.3 M2Crypto.EVP
from M2Crypto import EVP
The EVP module provides an interface to OpenSSLs EVP interface. Additionally, it provides an interface to OpenSSLs HMAC interface, which is not technically a part of the EVP interface. As
we discussed in Chapters 6, 7, and 8, EVP is a high-level interface to message digests, symmetric ciphers, and public key algorithms. It provides a mechanism for computing cryptographic hashes,
data encryption, and digital signatures.
The
MessageDigest
class provides the interface for computing cryptographic hashes. Its constructor requires an argument that is the string name of the algorithm to use. The available
algorithms and their string names are listed in Chapter 7
. Once a
MessageDigest
object is instantiated, its
update
method can be called as many times as necessary to supply it with the data to be hashed. A call to the
final
method computes the hash and returns it. Example 9-1
demonstrates.
Example 9-1. Computing the cryptographic hash of data
from M2Crypto import EVP def hashdata, alg = sha1:
md = EVP.MessageDigestalg md.updatedata
return md.final
The
HMAC
class provides one of two interfaces for the OpenSSL HMAC support. The constructor accepts two arguments, the second of which is optional. The first argument is the key to use, and
the second optional argument is the string name of the message digest algorithm to use. The available algorithms and their string names are listed in
Chapter 7 . If no message digest algorithm
is specified, SHA1 is used. Once an
HMAC
object is instantiated, its
update
method can be called as many times as necessary to supply it with the data to be MACd. A call to the
final
method computes the MAC and returns it. The
hmac
function provides the other interface and is simply a wrapper around the OpenSSL
hmac
function. It accepts three arguments, the third of which is optional. The first argument is the key to use, and the second is the data to be MACd. The third
and optional argument is the message digest algorithm to use. Again, SHA1 is the default if one is not specified. The return from the function is the computed HMAC.
The
Cipher
class provides the interface to data encryption using a symmetric cipher. The classs interface is the same as the
MessageDigest
and
HMAC
classes. Once a
Cipher
object is constructed, the
update
method is used to supply it with the data to be encrypted or decrypted,
229
and the
final
method completes the operation, returning the encrypted or decrypted data. The constructor requires four arguments, and accepts an additional four optional arguments.
class Cipher: def _ _init_ _self, alg, key, iv, op, key_as_bytes = 0,
d = md5, salt = , i = 1:
alg The symmetric cipher to use. It is specified using the string name of the desired cipher.
Chapter 6 lists the available ciphers and their string names.
key The key to use to encrypt or decrypt the data.
iv The initialization vector to use to encrypt or decrypt the data.
op An integer that specifies whether encryption or decryption of the data should be
performed. If
op
is specified as 1, encryption is performed. If it is specified as 0, decryption is performed.
key_as_bytes Specifies how to interpret the specified key. If it is specified as a nonzero value, the key is
interpreted as a password or passphrase. In this case, an initialization vector is computed, and the
iv
argument is filled with the initialization vector that was used. d
Specifies the message digest algorithm that will be used to compute the key if
key_as_bytes
is specified as nonzero. The default is to use MD5. salt
Specifies the salt that will be used to compute the key if
key_as_bytes
is specified as nonzero.
i Specifies the number of iterations that will be performed to obtain the final key. In other
words, it specifies the number of times the key data will be hashed. Example 9-2
illustrates symmetric ciphers.
Example 9-2. Encrypting and decrypting with a symmetric cipher
from M2Crypto import EVP def encryptpassword, data, alg:
cipher = EVP.Cipheralg, password, None, 1, 1, sha1
TE AM
FL Y
Team-Fly
®
230
cipher.updatedata return cipher.final
def decryptpassword, data, alg: cipher = EVP.Cipheralg, password, None, 0, 1, sha1
cipher.updatedata return cipher.final
password = any password will do plaintext = Hello, world
ciphertext = encryptpassword, plaintext, bf-cbc print Decrypted message text: s decryptpassword, ciphertext,
bf-cbc
The EVP module also provides a
PKey
class that is intended to be a wrapper around the OpenSSL EVP interface for digital signatures and data encryption; however, it is incomplete, providing only
limited support for creating digital signatures. No mechanism exists for verifying digital signatures or data encryption in this class. The digital signature support is also nonfunctional. The
class is essentially useless in its current form, and so we will not discuss it in any more depth here.
9.2.2.4 Miscellaneous crypto