M2Crypto.SSL High-Level Classes

226 Although there are several solutions available for Python, M2Crypto is the most popular, the most complete, and not surprisingly, the most mature. It is written and maintained by Ng Pheng Siong ngpspost1.com and can be found on the Web at http:www.post1.comhomengpsm2 . It requires SWIG, which can be found on the Web at http:swig.sourceforge.net . At the time of writing, the latest version of M2Crypto is Version 0.06 and requires OpenSSL 0.9.6 or later and SWIG 1.3.6. Its been tested and known to work on Unix and Windows with Python Versions 1.5.2, 2.0, and 2.1. Although it is the most mature Python solution available, M2Crypto is barely a year old. Unfortunately, it is sorely lacking in documentation. Luckily, included in the distribution is a sizable collection of examples as well as a suite of unit test scripts that also serve as excellent examples of how to use the modules. M2Crypto contains not only a large set of low-level bindings to the OpenSSL C library functions, but a set of high-level classes that provide a far cleaner interface to SSL as well.

9.2.1 Low-Level Bindings

A significant number of the OpenSSL C library functions are directly bound. Many others are still available, although wrapped with a slightly different name, and their arguments may have changed slightly. These wrappers typically make the functions easier to use from Python and do a little extra work under the hood that may be necessary for everything to work properly for Python. You can make the low-level bindings to OpenSSL available in your program with t he following statement: from M2Crypto import m2 All of the low-level functions are named entirely in lowercase, and the OpenSSL C functions are normally named in a combination of uppercase and lowercase. For example, the OpenSSL C function named SSL_CTX_new would become m2.ssl_ctx_new in Python. We will not include a complete list of the low-level bindings in this chapter; however, the M2Crypto package contains one. We dont recommend that you use the low-level bindings in your own programs, at least not without also using the high-level classes. The primary reason for this is that many of the SSL subsystems require some additional setup calls from Python to make them work properly. For example, to use the BIO functionality, you need to call m2.bio_init , an internal M2Crypto function, properly. If youre using the high-level classes, such calls are made for you, and you can generally feel free to extend the classes if you need to.

9.2.2 High-Level Classes

M2Crypto contains a reasonably complete set of high-level classes that you can use in your programs. Use of the high-level classes is encouraged over the low-level bindings for a couple of reasons. The primary reason that we cited in the earlier section on the low-level interface is a good one. As M2Crypto evolves and matures, its possible that its internals will change, breaking your programs in the process. Another reason is because Python is primarily an object-oriented language, and the low-level interface is not object-oriented at all. A third reason is that OpenSSLs C library functions are often cumbersome to use. The high-level classes provide a much cleaner, easier-to-use interface to OpenSSLs functionality. There are several submodules, all of which can be imported from the M2Crypto module to access the various groupings of functions that all make up the OpenSSL C API. Several of them are still works in progress, but the most commonly used SSL functionality is available.

9.2.2.1 M2Crypto.SSL

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